How to redirect Nginx non-www to www domain over SSL

last updated in Categories , , ,

I am getting an error that reads, “Your connection is not secure” when trying to redirect https://theos.in/ to https://www.theos.in/ domain using HTTP 301. How do I redirect Nginx non-www to www domain over SSL?

First of all your need SSL certificate for both domains theos.in and www.theos.in. Another option is a SAN certificate or wildcard certificate that protect all first-level subdomains on an entire domain such as *.theos.in including www.theos.in, theos.in, forum.theos.in and more. This page show how one can redirect Nginx non-www to www domain over SSL using simple configuration options.

How to redirect Nginx non-www to www domain over SSL configuration

I am going to assume that you have either a wildcard certificate or two SSL certifcates for the domain named theos.in and www.theos.in.

Step 1 – Redirect https://theos.in to https://www.theos.in

Edit your nginx.conf or domain level conf file using a text editor such as vim command:
$ sudo vi /etc/nginx/sites-enabled/theos.in.conf
Append the following config:

 ### redirect HTTPS n
server {
    listen 443 ssl;
    server_name theos.in;
    ssl_certificate /etc/nginx/ssl/letsencrypt/non-www.theos.in/theos.in.cer;
    ssl_certificate_key /etc/nginx/ssl/letsencrypt/non-www.theos.in/theos.in.key;
    return 301 https://www.theos.in$request_uri;
}

Step 2 – Nginx configuration for https://www.theos.in

Here is my sample config:

server {
    access_log  /var/log/nginx/www.theos.in_access.log;
    error_log  /var/log/nginx/www.theos.in_error.log;
    listen 443 ssl http2;
    server_name www.theos.in;
    # adjust as per your needs #
    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate #
    ssl_certificate /etc/nginx/ssl/letsencrypt/www.theos.in/www.theos.in.cer;
    ssl_certificate_key /etc/nginx/ssl/letsencrypt/www.theos.in/www.theos.in.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_dhparam /etc/nginx/ssl/letsencrypt/theos.in/dhparams.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;
 
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Xss-Protection "1";
 
    # OCSP Stapling 
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;
    #resolver <IP DNS resolver>;
 
    ssl_buffer_size 8k;
    ## rest of your config below such as php-cgi, documentroot and more ##
}

Step 3 – Redirect all HTTP traffic to HTTPS

Of course all HTTP traffic must be sent to HTTPS server so that Strict-Transport-Security works correctly. Append following in your config file too:

# Redirect www.theos.in:80 to https://www.theos.in:443
server {
    listen      80;
    access_log  off;
    error_log   off;
    server_name www.theos.in;
    return         301 https://$server_name$request_uri;
}
# # Redirect http://theos.in:80 to https://theos.in:443
server {
    listen      80;
    access_log  off;
    error_log   off;
    server_name theos.in;
    return         301 https://$server_name$request_uri;
}

Make sure you reload or restart the nginx server:
$ sudo systemctl reload nginx
OR
$ sudo service nginx reload

How to test redirect non-www to www over SSL with Nginx serer and curl

The syntax is as follows for the curl command:
curl -IL https://theos.in/
curl -IL http://theos.in/

How to redirect Nginx non-www to www domain over SSL and test it with curl commad

See also

  1. Nginx Force (Redirect) WWW.Domain.COM To Domain.COM
  2. How To: Nginx Redirect All HTTP Request To HTTPS Rewrite 301 Rules

And there you have it. Nginx server is redirecting all non-www traffic to www over SSL. The config is also redirecting all HTTP traffic to HTTPS to avoid any other problems. Always use the curl command to check redirection status. You can use Firefox or Chrome web browser developer tools to examine, edit, and debug HTML/CSS/JS and view headers tools on the desktop.

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the latest tutorials on SysAdmin, Linux/Unix and open source topics via RSS/XML feed or weekly email newsletter.