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 am trying to get the following to work so that no matter what you type in the URL bar you always go to "https://www.". So far www. does not go to https://www. and https:// does not go to https://www.

Below is my code. What needs to be done?

server { 
        listen  80;
        server_name  example.com;
        rewrite ^(.*) https://www.example.com$1 permanent;
}

    server {
        listen       80;
        server_name  www.example.com;
        #rewrite ^(.*) https://www.example.com$1 permanent;
        root /home/knownsrv/public_html;

        listen       443 ssl;
        #server_name  example.com www.example.com;
        #root /home/knownsrv/public_html;
        ssl_certificate      /root/knownsrv.crt;
        ssl_certificate_key  /root/knownsrv.key;
        #ssl_client_certificate /root/chain.cer;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   /home/knownsrv/public_html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
location ~ \.php$ {
            root           /home/knownsrv/public_html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
}
}
share|improve this question

2 Answers 2

You are way overcomplicating this....

To redirect HTTP with or without www to HTTPS with www:

server {
        listen 80;
        server_name www.example.com example.com;
        return 301 https://www.example.com$request_uri;
}

That leaves only the situation of HTTPS without www, which can be addressed like so:

server {
    listen 443 ssl;
    server_name example.com;
    return 301 https://www.example.com$request_uri;
    ssl_certificate /root/knownsrv.crt;
    ssl_certificate_key /root/knownsrv.key;
}

Then just add your ssl vhost for www.example.com. Everything else (ie, missing www, and/or non-ssl) will be redirected to it. No need for if (which can seriously degrade nginx performance).

share|improve this answer
    
Note it can be simpler still there's no need for two server blocks listening on port 80 - just use one (and the server name isn't required either) i.e. server { listen 80; return 301 https://www.example.com$request_uri; } - done. –  AD7six Jan 31 at 19:08
    
True. I'm so used to having two separate ones (long story - basically redirecting first to https, and then handling missing www, because of HSTS..) –  Joe Sniderman Jan 31 at 19:10
1  
I know HSTS are ignored over HTTP. However, if I were to redirect http:// example.com to https:// www.example.com and then send the HSTS header - that header would ONLY cover with www.example.com and not example.com. (the reverse is less of an issue, because subdomains can be included in the HSTS.) Side note: I corrected my answer per your suggestion. Thanks! –  Joe Sniderman Jan 31 at 19:14
    
Use backticks for inline plain text in posts and comments =) in backticks: https://example.com. Interesting; so you do that to have a HSTS header on both domains. I don't think the extra hop is generally worth it but it's worth thinking about nonetheless. –  AD7six Jan 31 at 19:18
    
Typically yeah, I'll put an HSTS header on both domains. The extra hop makes sense if someone bookmarks http://example.com but I want to redirect to https://www.example.com Thanks for the heads up re the backticks! –  Joe Sniderman Jan 31 at 19:26

In the server block add:

if ($host !~* ^www\.) {
        rewrite ^(.*)$ https://www.website.com$1 permanent;
}

So your config should look something like:

server {
    listen  80;
    server_name website.com www.website.com;
    rewrite ^(.*) https://www.website.com$1 permanent;
}

server {
    listen 443 ssl;
    server_name website.com www.website.com;
    root /home/knownsrv/public_html;

    if ($host !~* ^www\.) {
        rewrite ^(.*)$ https://www.website.com$1 permanent;
    }

    ssl_certificate /root/knownsrv.crt;
    ssl_certificate_key /root/knownsrv.key;

    location / {
        root /home/knownsrv/public_html;
        index index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }

    location ~ \.php$ {
        root            /home/knownsrv/public_html;
        fastcgi_pass    127.0.0.1:9000;
        fastcgi_index   index.php;
        fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include         fastcgi_params;
    }
}
share|improve this answer
    
Can't seem to get the non ssl to redirect to SSL –  K Mack May 18 '13 at 4:37
    
I edited the config just to make it more clear. –  chr1x2 May 18 '13 at 6:06
    
I've just tried it and it hasn't made any difference –  jackweirdy May 24 '13 at 17:16

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.