2

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;
        }
}
}

2 Answers 2

1

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

6
  • 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, 2015 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..) Jan 31, 2015 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! Jan 31, 2015 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, 2015 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! Jan 31, 2015 at 19:26
-1

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;
    }
}
3
  • Can't seem to get the non ssl to redirect to SSL
    – K Mack
    May 18, 2013 at 4:37
  • I edited the config just to make it more clear.
    – chr1x2
    May 18, 2013 at 6:06
  • I've just tried it and it hasn't made any difference
    – jackweirdy
    May 24, 2013 at 17:16

You must log in to answer this question.

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