5

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.

NiKo
  • 153
  • 1
  • 5

2 Answers2

4

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).

womble
  • 96,255
  • 29
  • 175
  • 230
  • In newer versions of Nginx, this limitation has been defeated -- albeit, i'm still trying to figure out how --- – rm-vanda Jun 18 '14 at 16:44
  • @rm-vanda: Can you provide a reference for that? I know that it's theoretically possible to sniff the request and decide heuristically whether it's a HTTP request or an SSL connection establishment packet, but I keep an eye on nginx development and I haven't seen mention of it being implemented. – womble Jun 21 '14 at 03:39
  • It says so under http://nginx.org/en/docs/http/configuring_https_servers.html - But perhaps I misunderstood. It is, at least currently possible to tell NGINX it can only serve 443 on certain IP's and not necessarily the whole server. – rm-vanda Jun 22 '14 at 21:09
  • 1
    @rm-vanda: If you're referring to the section, "A single HTTP/HTTPS server", that's describing something different to what is being asked for in this question. – womble Jun 25 '14 at 23:37
2

The SSL mismatch warning is unpreventable without a second IP address or some sort of proxy setup, as womble notes.

If you want to prevent unsecuredomain.tld content from being served over SSL, you should use something like the following in the securedomain.tld SSL vhost definition instead of what you have:

if ($host != $server_name) {
    rewrite ^(.*)$ http://unsecuredomain.tld permanent;
}

and just bounce them out, instead of throwing up a different HTTP error after they've already received the browser warning and chosen to continue.

cjc
  • 24,916
  • 3
  • 51
  • 70
  • 1
    It is actually possible to use multiple SSL certs on one ip if you use TLS/SNI (Server Name Extension). However, client side support is still a bit "iffy". – Niall Donegan Mar 07 '12 at 14:33
  • Yeah, it's one of those "better not to mention SNI" responses. Anyway, womble has already brought up that option. – cjc Mar 07 '12 at 14:41
  • 1
    As an update on the issue of client side support for SNI: with XP going out of support, the number of browsers with security support that *don't* support SNI is now essentially zero. So you may now go forth and SNI **all the things** (unless you want to pander to people who *like* to get pwned up eight ways whenever they browse the web). – womble Jun 25 '14 at 23:34