Documentation

SNI: Server Name Indication

TLS EXTENSION MULTIPLE HOSTS ESSENTIAL FOR HTTPS

Enables Multiple HTTPS Sites on One IP

SNI (Server Name Indication) is a TLS extension that allows a single server with one IP address to host multiple HTTPS websites with different SSL certificates. Without SNI, you'd need a separate IP address for every HTTPS website!

What is SNI?

TLS EXTENSION

Simple Definition: SNI (Server Name Indication) is a TLS extension that allows a client to specify which hostname it's trying to connect to at the start of the TLS handshake. This enables servers to present the correct SSL certificate for that specific domain.

The Problem SNI Solves:

Before SNI, HTTPS had a major limitation:

  • One IP = One Certificate - Each HTTPS site needed its own IP address
  • IPv4 exhaustion - Running out of IP addresses globally
  • Expensive hosting - Virtual hosting didn't work with HTTPS
  • Wasteful - Using entire IPs for simple websites

How SNI Fixed It:

  • Multiple sites per IP - Host dozens of HTTPS sites on one IP
  • Virtual hosting works - HTTPS now works like HTTP virtual hosts
  • Cost effective - Dramatically reduced hosting costs
  • IPv4 conservation - Solved the IP shortage problem for HTTPS

Real-World Analogy

Think of SNI like an apartment building address system:

Without SNI (Old Way):

  • Each apartment (website) needs its own building (IP address)
  • Wasteful and expensive
  • Can't fit many buildings in the neighborhood (IPv4 exhaustion)

With SNI (Modern Way):

  • One building (IP address) with many apartments (websites)
  • Mailman (server) checks apartment number (hostname) before delivering
  • Each apartment gets the right mail (correct SSL certificate)
  • Efficient use of space (IP addresses)

How SNI Works

HANDSHAKE PROCESS

TLS Handshake with SNI

Step 1: Client Initiates Connection

plaintext🌐 Browser → 🏦 Server (IP: 203.0.113.10)

TLS ClientHello:
  - TLS Version: 1.3
  - Cipher Suites: [TLS_AES_256_GCM_SHA384, ...]
  - SNI Extension: hostname = "bank.com"  ← THIS IS THE KEY!
  - Random bytes for key generation

The Critical SNI Field

The SNI extension in the ClientHello message tells the server which hostname the client wants to connect to. This happens BEFORE encryption, so the server knows which certificate to present.

Step 2: Server Selects Correct Certificate

plaintextServer (IP: 203.0.113.10) receives ClientHello

Checks SNI: hostname = "bank.com"

Server has multiple certificates:
  ├── bank.com → Certificate A ← SELECTED!
  ├── shop.com → Certificate B
  └── blog.com → Certificate C

Selects Certificate A for bank.com

Step 3: Server Responds with Correct Certificate

plaintext🏦 Server → 🌐 Browser

TLS ServerHello:
  - Selected Cipher Suite: TLS_AES_256_GCM_SHA384
  - Certificate: [Certificate for bank.com]
  - Server Key Exchange
  - Server Hello Done

Step 4: Client Validates Certificate

plaintext🌐 Browser validates certificate:
  ✅ Certificate is for "bank.com" (matches SNI)
  ✅ Certificate is signed by trusted CA
  ✅ Certificate is not expired
  ✅ Certificate has not been revoked

🔒 Connection proceeds with encryption

Without SNI (Old Behavior)

plaintextServer (IP: 203.0.113.10) receives ClientHello

❌ No SNI extension provided!

Server has multiple sites:
  ├── bank.com → Certificate A
  ├── shop.com → Certificate B
  └── blog.com → Certificate C

❓ Which certificate should server send?
   → Server sends DEFAULT certificate (maybe Certificate A)

Client wanted shop.com but got bank.com certificate!
❌ Certificate name mismatch error
❌ Connection fails or shows warning

Why This Was a Problem

Without SNI, the server couldn't know which hostname the client wanted BEFORE choosing a certificate. This meant:

  • Only the default certificate would work
  • All other sites on that IP would show certificate errors
  • The only solution was using separate IP addresses for each HTTPS site

Security Considerations

PRIVACY CONCERNS

SNI and Privacy

SNI Exposes Hostnames

Critical Privacy Issue: SNI sends the hostname in plaintext during the TLS handshake, meaning eavesdroppers can see which website you're connecting to, even though the actual traffic is encrypted.

What's Exposed:

plaintextAttacker observes TLS ClientHello:

❌ Visible in plaintext:
  - hostname: "secret-dating-site.com"  ← EXPOSED!
  - Client IP address
  - TLS version
  - Cipher suites

✅ Still encrypted:
  - Actual page URLs (like /profile/user123)
  - POST data and form submissions
  - Cookies and authentication tokens
  - Page content

Privacy Impact:

ISPs can see which domains you visit Government surveillance can monitor website access Corporate networks can track employee browsing Censorship - Countries can block specific domains No way to hide the initial domain in standard SNI

Encrypted SNI (ESNI / ECH)

SOLUTION

Encrypted Client Hello (ECH)

Encrypted Client Hello (ECH), formerly called ESNI, encrypts the SNI field to protect privacy. This is the modern solution to SNI privacy concerns.

How ECH Works:

plaintextOld SNI (Plaintext):
  SNI: "bank.com" ← VISIBLE TO EAVESDROPPERS

ECH (Encrypted):
  SNI: "[encrypted blob]" ← HIDDEN FROM EAVESDROPPERS

The SNI is encrypted using the server's public key,
which is published in DNS records.

ECH Status (2025):

  • Cloudflare - Supports ECH
  • Firefox - ECH enabled by default
  • Chrome - ECH support in development
  • Server support - Growing but not universal
  • Deployment - Requires DNS record setup
nginx# Nginx with ECH support (example)
ssl_ech on;
ssl_ech_keys /path/to/ech_keys;
apache# Apache with ECH (example)
SSLECHEnabled on
SSLECHKeyDir /path/to/ech/keys

SNI Configuration

SERVER SETUP

Web Server Configuration

nginx# Multiple HTTPS sites on one IP with SNI

# Site 1: bank.com
server {
    listen 443 ssl;
    server_name bank.com www.bank.com;

    ssl_certificate /etc/ssl/certs/bank.com.crt;
    ssl_certificate_key /etc/ssl/private/bank.com.key;

    # TLS configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    root /var/www/bank;
    index index.html;
}

# Site 2: shop.com (same IP address!)
server {
    listen 443 ssl;
    server_name shop.com www.shop.com;

    ssl_certificate /etc/ssl/certs/shop.com.crt;
    ssl_certificate_key /etc/ssl/private/shop.com.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    root /var/www/shop;
    index index.html;
}

# Site 3: blog.com (same IP address!)
server {
    listen 443 ssl;
    server_name blog.com www.blog.com;

    ssl_certificate /etc/ssl/certs/blog.com.crt;
    ssl_certificate_key /etc/ssl/private/blog.com.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    root /var/www/blog;
    index index.html;
}

How This Works

Nginx automatically uses SNI to determine which server block to use based on the hostname in the SNI extension. Each site gets its own SSL certificate, all served from the same IP address!

apache# Multiple HTTPS sites with SNI

# Site 1: bank.com
<VirtualHost *:443>
    ServerName bank.com
    ServerAlias www.bank.com

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/bank.com.crt
    SSLCertificateKeyFile /etc/ssl/private/bank.com.key
    SSLCertificateChainFile /etc/ssl/certs/intermediate.crt

    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite HIGH:!aNULL:!MD5

    DocumentRoot /var/www/bank
</VirtualHost>

# Site 2: shop.com (same IP!)
<VirtualHost *:443>
    ServerName shop.com
    ServerAlias www.shop.com

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/shop.com.crt
    SSLCertificateKeyFile /etc/ssl/private/shop.com.key
    SSLCertificateChainFile /etc/ssl/certs/intermediate.crt

    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite HIGH:!aNULL:!MD5

    DocumentRoot /var/www/shop
</VirtualHost>

# Site 3: blog.com (same IP!)
<VirtualHost *:443>
    ServerName blog.com
    ServerAlias www.blog.com

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/blog.com.crt
    SSLCertificateKeyFile /etc/ssl/private/blog.com.key
    SSLCertificateChainFile /etc/ssl/certs/intermediate.crt

    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite HIGH:!aNULL:!MD5

    DocumentRoot /var/www/blog
</VirtualHost>

Testing SNI

VERIFICATION

Testing SNI Support

Test SNI with OpenSSL:

bash# Test specific hostname with SNI
openssl s_client -connect example.com:443 -servername example.com

# Test different hostname on same IP
openssl s_client -connect 203.0.113.10:443 -servername bank.com

# Test without SNI (old behavior)
openssl s_client -connect example.com:443 -no_servername

Expected output with correct SNI:

plaintextCONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, ...
verify return:1
---
Certificate chain
 0 s:CN = example.com
   i:CN = DigiCert SHA2 Secure Server CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGYzCCBUugAwIBAgIQBk...
-----END CERTIFICATE-----
subject=CN = example.com  ← Matches requested hostname

Check SNI in Browser:

  1. Open Developer Tools (F12)
  2. Go to Security tab
  3. View Certificate
  4. Check Subject Alternative Names (SAN)

What to Look For

  • Certificate should match the domain you're visiting
  • SAN field should include the domain
  • No certificate warning or error
  • Green padlock in address bar

Common SNI Issues

TROUBLESHOOTING

Issue 1: Old Client Support

Legacy Clients Don't Support SNI

Problem: Clients older than 2010 don't support SNI, causing certificate errors.

Affected Clients:

  • Windows XP (Internet Explorer 6)
  • Android 2.x (default browser)
  • Java 6 and older
  • Python 2.x (without backports)
  • Old mobile phones

Solutions:

WORKAROUND 1 Use dedicated IP address for critical sites

WORKAROUND 2 Display browser upgrade message for old clients

WORKAROUND 3 Use wildcard certificates for subdomains

Issue 2: Certificate Mismatch

Wrong Certificate Served

Problem: Server serves wrong certificate when SNI isn't working correctly.

Causes:

  • Server not configured properly
  • Client not sending SNI
  • Default certificate configured incorrectly
  • Firewall/proxy stripping SNI

Debug Steps:

bash# Check which certificate is served
openssl s_client -connect domain.com:443 -servername domain.com | openssl x509 -noout -text

# Check server configuration
nginx -t  # Nginx
apachectl configtest  # Apache

# Verify DNS points to correct IP
dig domain.com +short

Issue 3: Wildcard vs Multiple Certificates

When to Use Wildcards

Wildcard certificates (*.example.com) can simplify SNI configuration for subdomains.

Comparison:

Approach Pros Cons
Wildcard Cert (*.example.com) One cert for all subdomains
Simpler management
Can't have different CAs per subdomain
All subdomains share same cert
Individual Certs (SNI) Different CAs possible
More granular control
More certificates to manage
More complex renewal

SNI Best Practices

RECOMMENDATIONS

Do's

Enable SNI on all modern web servers Test thoroughly with multiple browsers and clients Monitor certificate expiration for all hosted domains Use Let's Encrypt for free automated certificates Configure default certificate as fallback for non-SNI clients Implement ECH when available for privacy Document which domains are on shared IPs

Don'ts

Don't assume all clients support SNI (check analytics) Don't forget intermediate certificates in the chain Don't mix wildcard and specific certs carelessly Don't ignore certificate transparency logs Don't use self-signed certificates in production


SNI History and Adoption

EVOLUTION

Timeline:

  • 2003 - SNI standardized in RFC 3546 (TLS Extensions)
  • 2006 - Apache 2.2.12 adds SNI support
  • 2009 - Nginx 0.5.23+ supports SNI
  • 2010 - Windows Vista+ / IE 7+ support SNI
  • 2012 - SNI becomes widely adopted
  • 2018 - ESNI (Encrypted SNI) proposed
  • 2020 - ECH (Encrypted Client Hello) development
  • 2025 - SNI universal, ECH deployment growing

Adoption Rate (2025):

  • 99%+ of browsers support SNI
  • 95%+ of servers configured for SNI
  • <1% legacy clients without SNI
  • 20%+ servers with ECH support

Learn More

TLS/SSL Basics - Understanding the full TLS handshake Certificate Chain - How certificates are validated HSTS - Forcing HTTPS connections Certificate Revocation - CRL and OCSP


Protected by Layerd AI

Layerd AI Cloud WAF provides:

SNI Validation - Ensures correct certificates for requested hostnames Certificate Monitoring - Alerts before certificate expiration Multi-Domain Support - Automatic SNI handling for virtual hosts ECH Support - Privacy-preserving hostname encryption Legacy Client Detection - Identifies and handles non-SNI clients

Learn more about Layerd AI Protection →


Last updated: November 2025