SNI lets a single IP address host multiple HTTPS websites, resolving the "one IP, one certificate" problem that used to plague virtual hosting.

Let’s watch SNI in action. Imagine you have two websites, example.com and anothersite.org, both hosted on the same server at 192.168.1.100.

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    # ... other configurations for example.com
}

server {
    listen 443 ssl;
    server_name anothersite.org;

    ssl_certificate /etc/nginx/ssl/anothersite.org.crt;
    ssl_certificate_key /etc/nginx/ssl/anothersite.org.key;

    # ... other configurations for anothersite.org
}

When a browser connects to https://example.com, it establishes a TCP connection to 192.168.1.100. Before the SSL/TLS handshake even begins, the browser sends a Client Hello message. This message includes a crucial piece of information: the hostname it’s trying to reach, example.com. This is the SNI extension.

Client Hello (contains SNI: example.com) -> Server

The web server, Nginx in this case, receives the Client Hello. It inspects the SNI extension to see which hostname the client requested. Based on the server_name directive matching example.com, Nginx then selects the appropriate SSL certificate (/etc/nginx/ssl/example.com.crt) and private key (/etc/nginx/ssl/example.com.key) for the subsequent TLS handshake. If the SNI extension were absent, Nginx wouldn’t know which certificate to present, and the connection would likely fail or default to a single, potentially incorrect, certificate.

This ability to dynamically select certificates based on the requested hostname is what enables "HTTPS virtual hosting." Without SNI, each HTTPS website would require its own dedicated IP address, a significant limitation given the scarcity of IPv4 addresses.

The problem SNI solves is elegant in its simplicity. Before SNI, the server had no way to know which domain the client was asking for during the SSL handshake. The handshake is designed to establish a secure channel before any HTTP traffic (which contains the hostname) is exchanged. So, if a server hosted siteA.com and siteB.com on the same IP, and both used HTTPS, the server would present its certificate for siteA.com to every client. If the client was trying to reach siteB.com, their browser would receive a certificate mismatch error because the certificate’s common name (or subject alternative names) wouldn’t match siteB.com.

The solution was to extend the TLS handshake protocol itself. The SNI extension was added to the Client Hello message. This extension carries the requested hostname. When the server receives the Client Hello with SNI, it can look up the correct certificate for that hostname and present it. The Server Hello message then proceeds with the handshake using the appropriate certificate.

The primary lever you control with SNI is the configuration of your web server. You map hostnames to specific SSL certificate and key files. This is typically done within server blocks in Nginx or VirtualHost directives in Apache. The key is ensuring that the server_name (Nginx) or ServerName (Apache) directives accurately reflect the hostnames for which you have certificates, and that those certificates are correctly referenced.

For example, in Nginx, you might have:

server {
    listen 443 ssl http2; # Added http2 for modern performance
    server_name www.mycoolapp.com mycoolapp.com; # Multiple hostnames can share a cert

    ssl_certificate /etc/letsencrypt/live/mycoolapp.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mycoolapp.com/privkey.pem;

    # ... rest of config for mycoolapp.com
}

Here, both www.mycoolapp.com and mycoolapp.com will use the same certificate and key.

Most modern clients (browsers, curl, etc.) support SNI. However, older clients, particularly very old versions of Internet Explorer on Windows XP, do not support SNI. If you need to support such legacy clients, you might have to assign them a dedicated IP address or use a wildcard certificate on a shared IP if all your sites can share a single certificate.

The SNI extension is a field within the TLS handshake’s Client Hello message, and its absence or misconfiguration directly leads to certificate errors.

The next concept to understand is how SNI interacts with HTTP/2, specifically regarding connection reuse and multiplexing.

Want structured learning?

Take the full Cryptography course →