Serve multiple HTTPS domains on one IP address
Configure SNI virtual hosts in Nginx or Apache, verify each hostname’s certificate, and handle unmatched names and clients without SNI.
Multiple HTTPS domains can share the same IP address and port. With Server Name Indication (SNI), the client supplies the requested hostname during TLS setup, allowing the server to choose a certificate before it receives the HTTP request.
Configure a virtual host and matching certificate for each name, or use a shared certificate whose SAN entries cover all the intended names. The lack of SNI does not automatically require separate IPs: a suitable shared certificate can cover several names, although the server must still handle the default TLS configuration correctly.
Configure Nginx
server {
listen 443 ssl;
server_name site-a.example;
ssl_certificate /etc/ssl/site-a-fullchain.pem;
ssl_certificate_key /etc/ssl/site-a.key;
root /var/www/site-a;
}
server {
listen 443 ssl;
server_name site-b.example;
ssl_certificate /etc/ssl/site-b-fullchain.pem;
ssl_certificate_key /etc/ssl/site-b.key;
root /var/www/site-b;
}
Replace the example hostnames and paths with real deployment values. Each certificate file starts with its leaf certificate, followed by required intermediates. Validate the Nginx configuration before reloading. See Nginx HTTPS configuration.
Configure Apache
With mod_ssl loaded and a global HTTPS listener already configured:
<VirtualHost *:443>
ServerName site-a.example
SSLEngine on
SSLCertificateFile /etc/ssl/site-a-fullchain.pem
SSLCertificateKeyFile /etc/ssl/site-a.key
DocumentRoot /var/www/site-a
</VirtualHost>
<VirtualHost *:443>
ServerName site-b.example
SSLEngine on
SSLCertificateFile /etc/ssl/site-b-fullchain.pem
SSLCertificateKeyFile /etc/ssl/site-b.key
DocumentRoot /var/www/site-b
</VirtualHost>
These are virtual-host fragments, not a complete installation. Apache's mod_ssl reference describes certificate loading and protocol-policy behavior.
Test each name against the shared IP
# Replace 192.0.2.10 with your server's address.
openssl s_client -connect 192.0.2.10:443 -servername site-a.example </dev/null \
| openssl x509 -noout -subject -ext subjectAltName
openssl s_client -connect 192.0.2.10:443 -servername site-b.example </dev/null \
| openssl x509 -noout -subject -ext subjectAltName
Inspect SAN coverage, not just the subject's common name. For actual validation:
openssl s_client -connect 192.0.2.10:443 -servername site-a.example \
-verify_hostname site-a.example -verify_return_error </dev/null
Repeat for the other hostname with the intended trust store. To test a no-SNI client explicitly, use -noservername; an OpenSSL client may otherwise infer SNI from a DNS name in -connect.
The default virtual host controls what happens when no matching name is selected. In Nginx, this is the configured default_server for the listener or, otherwise, the first server for that address/port.
Operate the domains independently
A wildcard such as *.example.com covers sibling subdomains, but not example.com itself or deeper names. A SAN certificate can cover unrelated domains. ACME clients such as Certbot and lego can automate issuance and renewal; verify deployment to each endpoint afterward.
Guance HTTP tests and SSL tests can check each hostname independently. Testing one IP or one name is insufficient when virtual hosts have different certificates and applications.
Common questions
Do old clients support this?
Modern browsers and TLS stacks support SNI. Legacy embedded systems and old client runtimes may not, so test any clients your service is required to support. Their actual configuration matters more than a broad OS-version assumption.
What should the default host do?
On Nginx versions supporting it, a dedicated default TLS server can use ssl_reject_handshake on; to reject unmatched handshakes. An HTTP 403 or Nginx 444 response happens after TLS and does not replace handshake rejection. Also handle unknown HTTP Host values deliberately.
Does SNI expose the hostname?
Traditional ClientHello SNI is visible on the network. ECH can protect the real name when supported and enabled. A VPN or proxy changes which parties observe the traffic; it does not guarantee that every hostname is hidden from every party.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan