1

My nginx file doesn't file is failing and I'm not sure how. I have managed to redirect from http to https fine. But I can't get the www to redirect to non-www version. What am I doing wrong?

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

location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
    root /home/sammy/myproject;
}

location / {
    include proxy_params;
    proxy_pass http://unix:/home/sammy/myproject/myproject.sock;
}
# added for let's encrypt
location /.well-known/ {
   root /home/sammy/myproject;
   allow all;
}
}
server {
# SSL configuration

listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;

    location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
    root /home/myproject/myproject;
}

location / {
    include proxy_params;
    proxy_pass http://unix:/home/sammy/myproject/myproject.sock;
}
# added for let's encrypt
location /.well-known/ {
   root /home/sammy/myproject;
   allow all;
}
}

I tried this additional block:

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

This didn't seem to work though. I thought perhaps I should change this to listen on 443, but wasn't sure how that would affect the ssl server block and default_server directive?

  • You don't have any redirects from www to non-www. First you need to write one. – Michael Hampton Jan 16 '17 at 2:11
  • @MichaelHampton Oh! I think I see the problem. Taking the third block as my base. Do I need to replace return with example.com$request_uri; ? – Jonnny Jan 16 '17 at 2:14
  • @downvote - Please explain your reason for downvoting – Jonnny Jan 17 '17 at 12:58
5

The $server_name refers to the server name you have defined in the virtual host block. Therefore your additional block causes a redirect cycle redirecting back to itself.

You have to use a literal domain name there instead of a variable.

For SSL domain with www, you have to add listen 443 ssl; to the block and certificate values.

So, this should be your third block:

server {
    listen 80;
    listen 443 ssl;
    server_name www.example.com;
    return 301 https://example.com$request_uri;
    include snippets/ssl-example.com.conf;
    include snippets/ssl-params.conf;
    ...
}
  • Thank you, but I am still finding that the redirect doesn't occur. I tested and restarted nginx prior to testing also :-) – Jonnny Jan 16 '17 at 17:24
  • Please add the complete nginx configuration to your question. – Tero Kilkanen Jan 16 '17 at 19:03
  • I've updated to provide my full current nginx file. Currently set up to use Let's encrypt and redirect all requests to https. I took the third block out as it wasn't working with regards to redirecting from www to non-www :-) – Jonnny Jan 16 '17 at 19:07
  • Only odd thing in your configuration is the first server block where you have location directives. You don't need those, since you have the return there. That doesn't affect this issue though. What exactly happens when you load http://www.example.com or https://www.example.com? – Tero Kilkanen Jan 16 '17 at 20:04
  • It just loads the page as www.example.com with the privacy warning from Google. I actually tried in the first block running server_name www.example.com example.com and return 301 https://example.com$request_uri. But same result – Jonnny Jan 16 '17 at 20:06
0

Here's how I do the forwards from http to https. The key part are the three server blocks at the bottom.

server {
  server_name www.example.com;

  listen 443 ssl http2;

  ssl_certificate /var/lib/acme/certs/***CERT_DIRECTORY/fullchain;
  ssl_certificate_key /var/lib/acme/certs/***CERT_DIRECTORY/privkey;

  # Set up preferred protocols and ciphers. TLS1.2 is required for HTTP/2
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  # This is a cache for SSL connections
  ssl_session_cache shared:SSL:2m;
  ssl_session_timeout 60m;

  root     /var/www/***rootdir;

  # First line is a cached access log, second logs immediately
  access_log  /var/log/nginx/mrwild.access.log main buffer=32k flush=1m if=$log_ua;
  # access_log  /var/log/nginx/mrwild.access.log main;

  # Default location to serve
  location / {
    log_not_found off;

    # This is a static site, so set the cache control headers to allow caching
    # for a day  
    add_header Cache-Control "public";
    expires 1d;

    valid_referers none blocked server_names ~($host) ~(googleusercontent|google|bing|yahoo);
    if ($invalid_referer) {
      rewrite (.*) /stop-stealing-images.png redirect;
    }
  }
  # Let the hotlink detection image be hotlinked
  # *** Find yourself a suitable graphic
  location = /stop-stealing-images.png { 
    add_header Cache-Control "public"; expires 4h;
  }

  # Don't log robots errors but log access
  location = /robots.txt {
    allow all; log_not_found off; 
  }

  location ~ /favicon.ico {
    access_log off; log_not_found off;
  }

  # This is for issuing certificates
  location /.well-known/acme-challenge/ {
    root /var/www/acme-challenge/;
  }

}

# This server simply redirects the requested to the https version of the page
server {
  listen 80;
  server_name example.com;
  return 301 https://www.example.com$request_uri;
}

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

server {
  listen 443 ssl http2;
  server_name example.com;

  ssl_certificate /var/lib/acme/certs/***CERT_DIRECTORY/fullchain;
  ssl_certificate_key /var/lib/acme/certs/***CERT_DIRECTORY/privkey;

  # Set up preferred protocols and ciphers. TLS1.2 is required for HTTP/2
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  access_log  /var/log/nginx/mrwild.access.log main buffer=32k flush=1m if=$log_ua;

  return 301 https://www.example.com$request_uri;
}
  • Hi Tim, I try this but it doesn't redirect. It just stays as www.example.com but with the privacy warning. I have a A record for example.com and a CNAME record for www.example.com. If that makes any difference – Jonnny Jan 17 '17 at 12:58
  • This is stock standard configuration code, if it doesn't work the problem is elsewhere. Please edit your question to provide more information about how it doesn't work, the exact detail of the privacy warning, and if the site is in the internet you'd get more help if you shared the URL. The privacy warning suggests that your https certificate or general configuration isn't set up correctly. – Tim Jan 17 '17 at 17:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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