Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

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?

share|improve this question

1 Answer 1

up vote 6 down vote accepted

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.

share|improve this answer
    
Oh, I've missed includeSubdomains. –  Alexey Ten Aug 15 at 7:11
    
Oh, it's so simple. Thank you! –  rush Aug 15 at 7:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.