4

Given I have 2 subdomains configured in the DNS (so pinging both reply for both with the IP address of my server) and for those subdomains I have 2 different TLS certificates.

I have configured nginx this way:

# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
  default $http_x_forwarded_proto;
  ''      $scheme;
}

# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
  default upgrade;
  ''      '';
}

gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

access_log /var/log/nginx.log;
error_log /var/log/nginx_errors.log;

# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;

server {
  listen 80 default_server;
  server_name _; # This is just an invalid value which will never trigger on a real hostname.
  return 503;
  server_tokens off; # Hide the nginx version
}


upstream sub1.domain.tld {
  server 172.17.0.27:5000;
}

server {
  server_name sub1.domain.tld;
  server_tokens off; # Hide the nginx version

  listen 443 ssl;
  ssl_certificate /etc/nginx/ssl/sub1.domain.tld.crt;
  ssl_certificate_key /etc/nginx/ssl/sub1.domain.tld.key;

  location / {
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/htpasswd/sub1.htpasswd;
    proxy_pass http://sub1.domain.tld;
  }
}

At this point, if I go to https://sub1.domain.tld all is working fine. Now if I try to access https://sub2.domain.tld which is not yet configured and so should not reply it accept the connection and show me an issue with the certificate as it doesn't match the server name, so it seems that with this configuration, Nginx send the certificate for all request to the 443 port.

How should I change my configuration so that accessing https://sub2.domain.tld fail (with a 503 error for example) until I configure it by adding a new server instruction ?

2 Answers 2

1

You can add another server block like this:

server {
    listen 443 ssl default_server;
    server_name _;

    ssl_certificate /etc/nginx/ssl/default.crt;
    ssl_certificate_key /etc/nginx/ssl/default.key;

    return 503;
}

For the default certificate, you can make a self-signed certificate. This will trigger an invalid certificate error on the client, like Steffen mentioned. If the user accepts the certificate, then he will receive the 503 statuscode.

4
  • Otherwise is there a way to redirect to the default server on port 80 so that there is no certificate and the user/application got immediately the 503 error ?
    – ZedTuX
    Dec 31, 2014 at 16:57
  • No. All SSL connections require certificates. If you don't have a valid certificate for the domain, users will get certificate error. Jan 1, 2015 at 2:22
  • So with this solution I can have a default page, like a landing page, where people can be redirected in case they try to access an URL which is not yet configured, am I right ?
    – ZedTuX
    Jan 1, 2015 at 9:15
  • Yes, you can add a root directive if you want, and then nginx will try to serve files from that directory for all non-existing domains. Jan 1, 2015 at 14:28
3

If you listen on TCP port 443 on a specific IP it will accept new TCP connections on this port even if you only have SSL configured for some of the domains resolving to this IP address. And once the TCP connection is established it will do the SSL handshake and pick the most suitable certificate, that is either the matching certificate if SNI is used (i.e. the client sends the expected hostname in the SSL handshake) or just another certificate if it cannot determine the requested hostname or if no certificate is configured for this name.

This means, that you either need to have certificates for all domains accessible on this IP address or accept, that access to domains without proper certificates will cause errors like invalid certificates. This is not specific to nginx but it is because SSL is a layer on top of TCP and information about the requested host are only transmitted within the established TCP connection.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .