Serve HTTPS Only for One Vhost-Managed Domain in Nginx – How To

nginxssl

I have an ec2 instance running ubuntu and nginx 0.8.4, with vhosts serving several different domains using http but one using SSL/https.

Secure domain configuration:

server {
    listen 443 ssl;
    server_name "securedomain.tld";

    ssl_certificate     /etc/nginx/certs/securedomain.tld.crt;
    ssl_certificate_key /etc/nginx/certs/securedomain.tld.key;

    if ($host != $server_name) {
        return 444; # this won't work because HTTPS communication has 
                    # been already started, warning message is displayed
    }

    // ...
}

Unsecure domain configuration:

server {
    listen 80; 
    server_name "unsecuredomain.tld";

    // ...
}

Right now the domain served using https is catching up all the https trafic, for all managed domainsā€¦ that means that https://unsecuredomain.tld/ will display a warning and actually serve the contents from securedomain.tld šŸ™

Question is, is there a way to prevent nginx from serving all unsecure domains served using https? eg by specifying that you only want to accept https connections for a given requested hostā€¦

Hint: an ec2 instance cannot have more than one IP affected.

Best Answer

In short: nope. As far as nginx is concerned, you've told it that all connections to port 443 are SSL connections for that vhost, and it's just doing what you told it. By the time it can see the Host: header in the request, the SSL negotiation has been done (absent SNI, which is really only going to help if you've got certs for all your domains and are being hit by an SNI-aware browser).