1

I'm trying to migrate a site from HTTP to HTTPS, however, my nginx (version: 1.10.3) config seems not to be working.

The following behavior is desired:

  • http://www.example.com/path/to/content should redirect to https://example.com/path/to/content
  • http://example.com/path/to/content should redirect to https://example.com/path/to/content
  • https://www.example.com/path/to/content should redirect to https://example.com/path/to/content

With my current config browsers wont connect to the site using HTTPS:

server {
    listen 80;
    listen [::]:80;

    server_name www.example.com example.com;

    # redirects both www and non-www to https
    rewrite ^(.*) https://www.example.com$1 permanent;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name example.com;

    # redirects non-www to www
    rewrite ^(.*) https://www.example.com$1 permanent;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    include snippets/ssl-example.com.conf;
    include snippets/ssl-params.conf;

    charset utf-8;

    # rest of my config
}
  • What do I have to change to achieve the above mentioned behavior?
  • Is it possible to accept (and later redirect) HTTP requests in a first step in order to keep the page "live" and let me test it?
  • My site has very good SEO rankings (indexed as "http://www.example.com"), so properly redirecting is a must.
gregory
  • 113
  • 1
  • 1
  • 5

2 Answers2

2

This configuration makes what you ask:

server {
    listen 80;
    listen [::]:80;

    server_name www.example.com example.com;

    # redirects both www and non-www to https
    return 301 https://example.com$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name www.example.com;

    include snippets/ssl-example.com.conf;
    include snippets/ssl-params.conf;

    # redirects www to non-www
    return 301 https://example.com$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name example.com;

    include snippets/ssl-example.com.conf;
    include snippets/ssl-params.conf;

    charset utf-8;

    # rest of my config
}

I changed rewrite to return, since that is a bit more efficient. With return one has to use $request_uri to get the request path and arguments into the redirect URL.

Then I changed the server_name example.com; with listen 443; block to serve the actual contents of the site, and server_name www.example.com; with listen 443; to make redirect.

Tero Kilkanen
  • 36,796
  • 3
  • 41
  • 63
  • Awesome, will try that! Could you explain the difference between the second and the fourth server block? Why is the fourth server block needed? The only difference I see is the `permanent` keyword. – gregory Mar 01 '17 at 10:55
  • That was a mistake from my part, I was partly copy-pasting your question to form my answer and mistakingly copy-pasted one part too much. I fixed the answer now. – Tero Kilkanen Mar 01 '17 at 11:23
  • Kiitos, Tero :) – gregory Mar 01 '17 at 12:44
  • Writing "listen 443 ssl http2" instead of just "listen 443" solved my problem. Thanks! – jobima Jan 31 '22 at 20:53
1

Please try by using below method and update rest ssl info:

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

And For ssl provide the ssl key path:

server {  
 listen   443 ssl;
 ssl on;  
 ssl_prefer_server_ciphers   on;  
 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;  
  ssl_certificate      /path of certificate;  
 ssl_certificate_key  /path of server.key;
}
anand
  • 199
  • 7
  • So, basically you're suggesting to replace `rewrite ^(.*) https://www.example.com$1 permanent;` with `return 301 https://www.example.com$request_uri;` in the first server block? All SSL related config is in `ssl-example.com.conf` and `ssl-params.conf` which are then included. – gregory Mar 01 '17 at 09:09
  • yes, where return 301 is redirecting http request into https.Also can use: return 301 https://$server_name$request_uri; – anand Mar 01 '17 at 09:16
  • `return 301 https://$server_name$request_uri` introduces one useless 301 redirect when you access `http://example.com`. First redirect will be to `https://example.com`, and then to `https://www.example.com`. You don't want that. – Tero Kilkanen Mar 01 '17 at 10:24