Bird
Raised Fist0
Nginxdevops~5 mins

SNI for multiple SSL certificates in Nginx - Commands & Configuration

Choose your learning style10 modes available
Introduction
When you want to host multiple websites securely on the same server using HTTPS, you need a way to serve the right SSL certificate for each website. SNI (Server Name Indication) lets the server know which certificate to use based on the website name the visitor wants.
When you host two or more websites on the same server and want each to have its own HTTPS certificate.
When you want to save IP addresses by using one IP for multiple secure websites.
When you need to add a new secure website without buying a new server or IP address.
When you want visitors to see the correct security lock icon for each website.
When you want to avoid browser warnings about wrong certificates on your sites.
Config File - nginx.conf
nginx.conf
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;

    location / {
        root /var/www/example.com;
        index index.html;
    }
}

server {
    listen 443 ssl;
    server_name example.org;

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

    location / {
        root /var/www/example.org;
        index index.html;
    }
}

server {
    listen 80;
    server_name example.com example.org;
    return 301 https://$host$request_uri;
}

This configuration defines two separate server blocks for two websites: example.com and example.org.

Each server block listens on port 443 with SSL enabled and uses its own SSL certificate and key files.

The last server block listens on port 80 (HTTP) and redirects all requests to HTTPS for both domains.

This setup uses SNI to serve the correct SSL certificate based on the requested domain name.

Commands
Check the Nginx configuration for syntax errors before applying it.
Terminal
sudo nginx -t
Expected OutputExpected
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Reload Nginx to apply the new configuration without stopping the server.
Terminal
sudo systemctl reload nginx
Expected OutputExpected
No output (command runs silently)
Test that example.com serves the correct SSL certificate and website content.
Terminal
curl -v https://example.com
Expected OutputExpected
* Rebuilt URL to: https://example.com/ * Trying 127.0.0.1... * Connected to example.com (127.0.0.1) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use http/1.1 * Server certificate: * subject: CN=example.com * start date: Apr 1 00:00:00 2024 GMT * expire date: Apr 1 23:59:59 2025 GMT * subjectAltName: host "example.com" matched cert's "example.com" > GET / HTTP/1.1 > Host: example.com > User-Agent: curl/7.68.0 > Accept: */* <html>...</html>
Test that example.org serves its own SSL certificate and website content correctly.
Terminal
curl -v https://example.org
Expected OutputExpected
* Rebuilt URL to: https://example.org/ * Trying 127.0.0.1... * Connected to example.org (127.0.0.1) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use http/1.1 * Server certificate: * subject: CN=example.org * start date: Apr 1 00:00:00 2024 GMT * expire date: Apr 1 23:59:59 2025 GMT * subjectAltName: host "example.org" matched cert's "example.org" > GET / HTTP/1.1 > Host: example.org > User-Agent: curl/7.68.0 > Accept: */* <html>...</html>
Key Concept

If you remember nothing else from this pattern, remember: SNI lets one server use multiple SSL certificates by choosing the right one based on the website name requested.

Common Mistakes
Using the same SSL certificate for all domains without configuring separate server blocks.
Visitors to other domains will get certificate warnings because the certificate does not match the domain name.
Create separate server blocks with their own ssl_certificate and ssl_certificate_key for each domain.
Not reloading Nginx after changing the configuration.
Nginx keeps running the old configuration, so changes do not take effect.
Run 'sudo nginx -t' to check config, then 'sudo systemctl reload nginx' to apply changes.
Forgetting to redirect HTTP (port 80) traffic to HTTPS.
Users can access the site insecurely, which defeats the purpose of SSL certificates.
Add a server block listening on port 80 that redirects all requests to HTTPS.
Summary
Create separate server blocks in Nginx for each domain with its own SSL certificate.
Use 'nginx -t' to check configuration syntax before reloading Nginx.
Reload Nginx to apply changes and test each domain with curl to verify the correct certificate is served.

Practice

(1/5)
1. What is the main purpose of SNI (Server Name Indication) in nginx when using multiple SSL certificates?
easy
A. To allow multiple SSL certificates on a single IP address by selecting the correct certificate based on the requested domain name.
B. To enable HTTP/2 protocol support for faster website loading.
C. To redirect all HTTP traffic to HTTPS automatically.
D. To combine multiple SSL certificates into one file for easier management.

Solution

  1. Step 1: Understand what SNI does

    SNI allows the server to present different SSL certificates depending on the domain name requested by the client.
  2. Step 2: Relate SNI to nginx configuration

    In nginx, SNI lets you use multiple server blocks with different SSL certificates on the same IP and port.
  3. Final Answer:

    To allow multiple SSL certificates on a single IP address by selecting the correct certificate based on the requested domain name. -> Option A
  4. Quick Check:

    SNI = Multiple SSL certs on one IP [OK]
Hint: SNI matches domain to SSL cert on same IP [OK]
Common Mistakes:
  • Confusing SNI with HTTP/2 support
  • Thinking SNI merges certificates into one
  • Assuming SNI automatically redirects HTTP to HTTPS
2. Which of the following nginx server block snippets correctly enables SNI for two domains with separate SSL certificates?
easy
A. server { listen 80; server_name example.com example.org; ssl_certificate /etc/ssl/all.crt; ssl_certificate_key /etc/ssl/all.key; }
B. server { listen 443 ssl; server_name example.com; ssl_certificate /etc/ssl/example.com.crt; ssl_certificate_key /etc/ssl/example.com.key; } server { listen 443 ssl; server_name example.org; ssl_certificate /etc/ssl/example.org.crt; ssl_certificate_key /etc/ssl/example.org.key; }
C. server { listen 443; server_name example.com; ssl_certificate /etc/ssl/example.com.crt; ssl_certificate_key /etc/ssl/example.com.key; } server { listen 443; server_name example.org; ssl_certificate /etc/ssl/example.org.crt; ssl_certificate_key /etc/ssl/example.org.key; }
D. server { listen 443 ssl; server_name example.com example.org; ssl_certificate /etc/ssl/example.com.crt; ssl_certificate_key /etc/ssl/example.com.key; }

Solution

  1. Step 1: Check listen directive for SSL

    Each server block must listen on port 443 with ssl enabled to serve HTTPS.
  2. Step 2: Verify separate server blocks for each domain

    server { listen 443 ssl; server_name example.com; ssl_certificate /etc/ssl/example.com.crt; ssl_certificate_key /etc/ssl/example.com.key; } server { listen 443 ssl; server_name example.org; ssl_certificate /etc/ssl/example.org.crt; ssl_certificate_key /etc/ssl/example.org.key; } has two server blocks, each with its own server_name and SSL cert/key, which is correct for SNI.
  3. Final Answer:

    server { listen 443 ssl; server_name example.com; ssl_certificate /etc/ssl/example.com.crt; ssl_certificate_key /etc/ssl/example.com.key; } server { listen 443 ssl; server_name example.org; ssl_certificate /etc/ssl/example.org.crt; ssl_certificate_key /etc/ssl/example.org.key; } -> Option B
  4. Quick Check:

    Separate server blocks + listen 443 ssl = correct SNI setup [OK]
Hint: Use separate server blocks with listen 443 ssl for each domain [OK]
Common Mistakes:
  • Omitting 'ssl' in listen directive on port 443
  • Combining multiple domains in one server block with one cert
  • Using port 80 for SSL configuration
3. Given this nginx configuration snippet, what will happen when a client requests https://example.net?
server {
  listen 443 ssl;
  server_name example.com;
  ssl_certificate /etc/ssl/example.com.crt;
  ssl_certificate_key /etc/ssl/example.com.key;
}

server {
  listen 443 ssl;
  server_name example.org;
  ssl_certificate /etc/ssl/example.org.crt;
  ssl_certificate_key /etc/ssl/example.org.key;
}
medium
A. The client will receive the SSL certificate for example.com because example.net is not configured.
B. The client will receive the SSL certificate for example.org as a fallback.
C. The connection will fail because example.net is not configured with SSL.
D. The client will receive a certificate error but connect to example.com.

Solution

  1. Step 1: Identify configured server names

    Only example.com and example.org have server blocks with SSL certificates.
  2. Step 2: Understand nginx default server behavior

    If a requested domain is not matched, nginx serves the default SSL server block, which is usually the first one defined (example.com here).
  3. Final Answer:

    The client will receive the SSL certificate for example.com because example.net is not configured. -> Option A
  4. Quick Check:

    Unmatched domain gets first SSL cert [OK]
Hint: Unmatched domains get first server block cert [OK]
Common Mistakes:
  • Assuming nginx picks a fallback cert arbitrarily
  • Thinking connection fails without explicit config
  • Believing client gets a certificate error immediately
4. You configured two server blocks for SNI but clients always get the same SSL certificate regardless of domain. What is the most likely cause?
medium
A. The SSL certificate files are corrupted.
B. Both server blocks are missing the ssl parameter in the listen directive.
C. The server_name directives are identical in both server blocks.
D. The firewall is blocking port 443.

Solution

  1. Step 1: Check server_name directives

    If the server_name directives are identical in both blocks, nginx cannot distinguish between domains using SNI.
  2. Step 2: Understand effect on SNI

    SNI relies on unique server_name matches to select the correct server block and certificate. Identical names cause all requests to use the first block (default), resulting in the same certificate.
  3. Final Answer:

    The server_name directives are identical in both server blocks. -> Option C
  4. Quick Check:

    Identical server_name = always first cert [OK]
Hint: Unique server_name per block required for SNI [OK]
Common Mistakes:
  • Missing 'ssl' parameter in listen directive
  • The SSL certificate files are corrupted
  • The firewall is blocking port 443
5. You want to host three domains with different SSL certificates on one nginx server using SNI. Which configuration approach correctly ensures each domain uses its own certificate and nginx listens properly for HTTPS?
hard
A. Create three server blocks with listen 443; (without ssl), each with unique server_name and SSL certificates.
B. Use one server block with listen 443 ssl; and list all three domains in server_name, then specify one combined SSL certificate covering all domains.
C. Use one server block with listen 80; and redirect all traffic to HTTPS on port 443 with a single SSL certificate.
D. Create three separate server blocks, each with listen 443 ssl;, unique server_name, and corresponding ssl_certificate and ssl_certificate_key.

Solution

  1. Step 1: Understand SNI requires separate server blocks

    Each domain needs its own server block with listen 443 ssl; and its own SSL cert/key.
  2. Step 2: Verify correct listen and server_name usage

    Create three separate server blocks, each with listen 443 ssl;, unique server_name, and corresponding ssl_certificate and ssl_certificate_key. correctly uses three server blocks with SSL enabled on port 443 and unique domain names.
  3. Final Answer:

    Create three separate server blocks, each with listen 443 ssl, unique server_name, and corresponding SSL certificate and key. -> Option D
  4. Quick Check:

    Separate server blocks + listen 443 ssl + unique certs = correct SNI [OK]
Hint: One server block per domain with listen 443 ssl and cert [OK]
Common Mistakes:
  • Using one server block for multiple domains without SAN cert
  • Omitting 'ssl' in listen directive
  • Using port 80 for SSL traffic
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard