5

I have domain.com and sub.domain.com configuraed in nginx. domain.com has ssl certificate, while sub.domain.com has not. wherever I try to open http://sub.domain.com in any modern browser (firefox, chrome even in clean browser without plugins) it redirects me to https://sub.domain.com and gives me an error as my ssl certificate is only for domain.com.

However wget doesn't redirect me:

 $ wget -O /dev/null http://sub.domain.com         
--2014-08-15 09:49:00--  http://sub.domain.com/
Resolving sub.domain.com (sub.domain.com)... X.X.X.X
Connecting to sub.domain.com (sub.domain.com)|X.X.X.X|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: ‘/dev/null’
2014-08-15 09:49:00 (1.23 MB/s) - ‘/dev/null’ saved [15807]

Here is nginx configuration for domain.com

server {
       # Redirect all http to https
       listen         X.X.X.X:80;
       server_name    ^domain.com www.domain.com;
       rewrite        ^ https://www.domain.com$request_uri? permanent;
}

server {
        ## Redirect https no-www to www for domain.com only
        listen               X.X.X.X:443 ssl;

        # Note ssl-bundle should contain only domain.com & root certificate
        ssl_certificate      /home/domain/ssl/www_domain.com.bundle;
        ssl_certificate_key  /home/domain/ssl/domain.com.key;

        ### Need to change that to avoid SSL Beast
        ssl_protocols              SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers  on;
        ssl_ciphers                "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK";

        ### Need to add this to enable HTTP Strict-Transport-Security
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
        server_name          ^domain.com;
        rewrite              ^ https://www.domain.com$request_uri? permanent;
}


server {
       ### Main section
       listen X.X.X.X:443 ssl;
       server_name                www.domain.com;
       server_tokens              off;

       ssl_certificate      /home/domain/ssl/www_domain.com.bundle;
       ssl_certificate_key  /home/domain/ssl/domain.com.key;
       ### Need to change that to avoid SSL Beast
       ssl_protocols              SSLv3 TLSv1 TLSv1.1 TLSv1.2;
       ssl_prefer_server_ciphers  on;
       ssl_ciphers                "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK";

        ### OCSP will be enabled only after nginx v1.3.5, so let's wait until it becomes the stable version 
        ### ( 1.6 is already in testing )
        # enable ocsp stapling (mechanism by which a site can convey certificate revocation information to visitors in a privacy-preserving, scalable manner)
        # http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/
        #resolver 8.8.8.8;
        #ssl_stapling on;
        #ssl_trusted_certificate /home/domain/certs/ssl-bundle.crt;

        ### Need to add this to enable HTTP Strict-Transport-Security
        ###
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
        add_header X-Frame-Options SAMEORIGIN;

        root /home/domain/www/domain.com;
        index index.php index.html index.htm;


        location /promo/ {
            proxy_set_header   Host             $host;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_pass         http://127.0.0.1:10001;
            proxy_redirect     off;
    }

    location ^~ /s/promo/static/ {
            disable_symlinks off;
            expires 1y;
            root /home/domain/www/promo-static ;
            log_not_found off;
    }


    location / {
          <.various rules.>
    }
}

And here is configuration for sub.domain.com:

server {
        listen X.X.X.X:80;
        server_name sub.domain.com ;

        # Serve media and static with nginx
        location ^~ /media/ {
                root /home/domain/www/sub_domain_com/project/;
                access_log off;
        }

        location ^~ /static/ {
                root /home/domain/www/sub_domain_com/project/;
                access_log off;
        }

        # Proxy redirect to django
        location / {
                proxy_read_timeout 1200;
                proxy_set_header   Host             $host;
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
                proxy_set_header   X-Real-IP        $remote_addr;
                proxy_pass         http://127.0.0.1:10001;
                proxy_redirect     off;
        }
}

I'm out of ideas how to stop http to https redirection for sub.domain.com.

One more strange thing: if I completely remove section for redirect http domain.com to https domain.com wget will return HTTP request sent, awaiting response... No data received. on http://domain.com but firefox and chrome will keep open https version when I type http://domain.com! what is wrong with these browsers and how do I need to configure nginx to stop such behaviour?

1 Answer 1

12

That's what HSTS is supposed to do. Once a browser has visited the https version of a site and received the HSTS header back, it will always request the https version until the expiry date, which in your case is one year.

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

And because you have includeSubDomains, subdomains are included.

To switch HSTS off, change the max-age to 1, request the https version again to cache the new header, wait 1 second then try the http version.

Or you could just remove includeSubDomains and then request the https version again to cache the header.

3
  • Oh, I've missed includeSubdomains.
    – Alexey Ten
    Aug 15, 2014 at 7:11
  • In my experience: "request the https version again to cache the new header" = CTRL+F5 the site. Deleting Firefox's cache somehow did not work.
    – benjaoming
    Feb 29, 2016 at 14:06
  • 1
    max-age=0 would also make sense here. "A max-age value of zero (i.e., "max-age=0") signals the UA to cease regarding the host as a Known HSTS Host" tools.ietf.org/html/rfc6797#page-16
    – fuglede
    Aug 11, 2016 at 20:26

You must log in to answer this question.

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