Blog

03/06/2019

How to redirect non-www to www HTTP / TLS /SSL traffic on Nginx



I want ALL sxi.io to go to sxi.io for SEO and other reasons. I want ALL HTTP traffic to go to HTTPS. How do I redirect all HTTP/HTTPS non-www (e.g. domain name sxi.io) traffic to www (e.g. domain name sxi.io) when using Nginx web server?

It is suggested that you do the redirection with the HTTP response status code 301 Moved Permanently. It is used for persistent URL redirection, meaning current links using the URL that the response is received for should be refreshed by both search engines and manually made bookmarks.

This tutorial shows you how to redirect a non-www URL to a www with Nginx web-server running in Linux or Unix-like system.

Update your virtual domain config file as follows for HTTP redirection

You need to define two virtual hosts as follows in your config file:

## redirect http://sxi.io to http://sxi.io/
server {
    listen       80;
    access_log  off;
    error_log   off;
    server_name  sxi.io;
    return       301 http://sxi.io$request_uri;
}
## Continue below for sxi.io
server {
    listen       80;
    access_log  off;
    error_log   off;
    server_name  sxi.io;
    ## rest of config below ##
}

## redirect http://sxi.io to http://sxi.io/ server { listen 80; access_log off; error_log off; server_name sxi.io; return 301 http://sxi.io$request_uri; } ## Continue below for sxi.io server { listen 80; access_log off; error_log off; server_name sxi.io; ## rest of config below ## }

Keep in mind if you are using ‘HTTP Strict Transport Security‘, you need to redirect ALL http traffic to HTTPS/TLS domain. So edit the nginx.conf or one of virtual hosting file stored in /etc/nginx/sites-enabled/ for your domain:
$ sudo vi /etc/nginx/sites-enabled/sxi.io.conf
Update it as follows:

## redirect http://sxi.io to https://sxi.io ##
server {
    listen      80;
    access_log  off;
    error_log   off;
    server_name sxi.io;
    return      301 https://$server_name$request_uri;
}
## redirect sxi.io to https://sxi.io/
server {
    listen      80;
    access_log  off;
    error_log   off;
    server_name sxi.io;
    return      301 https://$server_name$request_uri;
}

## redirect http://sxi.io to https://sxi.io ## server { listen 80; access_log off; error_log off; server_name sxi.io; return 301 https://$server_name$request_uri; } ## redirect sxi.io to https://sxi.io/ server { listen 80; access_log off; error_log off; server_name sxi.io; return 301 https://$server_name$request_uri; }

Save and close the file. You must reload the nginx server after testing for syntax errors using the -t option:
$ sudo nginx -t && systemctl reload nginx
OR
$ sudo nginx -t && service nginx reload

See how to configure Nginx with a free Let’s Encrypt SSL/TLS certificate

Update your virtual domain config file as follows for HTTPS/TLS redirection

Again edit your nginx.conf or one of virtual hosting file stored in /etc/nginx/sites-enabled/ for your domain as follows using the vi command/vim command:

## redirect all https://sxi.io/ to https://sxi.io/
server {
        listen 443 ssl http2;
        access_log  off;
        error_log   off;
        server_name sxi.io;
        return 301 https://sxi.io$request_uri;
}
## define our https://sxi.io/ ##
server {
    listen 443 ssl http2;
    access_log  /var/log/nginx/sxi.io_access.log;
    error_log  /var/log/nginx/sxi.io_error.log;
    ## server name and root
    server_name  sxi.io;
    root        /home/lighttpd/sxi.io/http;
 
    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /etc/nginx/ssl/letsencrypt/sxi.io/sxi.io.crt;
    ssl_certificate_key /etc/nginx/ssl/letsencrypt/sxi.io/sxi.io.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /etc/nginx/ssl/letsencrypt/sxi.io/dhparams.pem;
 
    # intermediate configuration. tweak to your needs.
    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;
 
  # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security "max-age=15768000" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Xss-Protection "1";
    add_header X-Whome "l-cbz02";
    # OCSP Stapling 
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8;
    ## Improves TTFB by using a smaller SSL buffer than the nginx default
    ssl_buffer_size 8k;
 
    # Directives to send expires headers and turn off 404 error logging.
    location ~* ^.+.(css|js|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
          access_log off; log_not_found off; expires max;
    }
 
    # Pass all .php files onto a php-fpm/php-fcgi server.
     index index.php;
     location ~ [^/].php(/|$) {
     fastcgi_split_path_info ^(.+?.php)(/.*)$;
            if (!-f $document_root$fastcgi_script_name) {
                     return 404;
     }
 
    # This is a robust solution for path info security issue and works with "cgi.fix_pathinfo = 1" in /etc/php.ini (default)
    include /etc/nginx/fastcgi_params;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass php;
 }
}

## redirect all https://sxi.io/ to https://sxi.io/ server { listen 443 ssl http2; access_log off; error_log off; server_name sxi.io; return 301 https://sxi.io$request_uri; } ## define our https://sxi.io/ ## server { listen 443 ssl http2; access_log /var/log/nginx/sxi.io_access.log; error_log /var/log/nginx/sxi.io_error.log; ## server name and root server_name sxi.io; root /home/lighttpd/sxi.io/http; # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate ssl_certificate /etc/nginx/ssl/letsencrypt/sxi.io/sxi.io.crt; ssl_certificate_key /etc/nginx/ssl/letsencrypt/sxi.io/sxi.io.key; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits ssl_dhparam /etc/nginx/ssl/letsencrypt/sxi.io/dhparams.pem; # intermediate configuration. tweak to your needs. 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; # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) add_header Strict-Transport-Security "max-age=15768000" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Xss-Protection "1"; add_header X-Whome "l-cbz02"; # OCSP Stapling # fetch OCSP records from URL in ssl_certificate and cache them ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8; ## Improves TTFB by using a smaller SSL buffer than the nginx default ssl_buffer_size 8k; # Directives to send expires headers and turn off 404 error logging. location ~* ^.+.(css|js|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { access_log off; log_not_found off; expires max; } # Pass all .php files onto a php-fpm/php-fcgi server. index index.php; location ~ [^/].php(/|$) { fastcgi_split_path_info ^(.+?.php)(/.*)$; if (!-f $document_root$fastcgi_script_name) { return 404; } # This is a robust solution for path info security issue and works with "cgi.fix_pathinfo = 1" in /etc/php.ini (default) include /etc/nginx/fastcgi_params; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass php; } }

Save and close the file. Again, you need to reload the nginx server after testing for syntax errors using the -t option:
$ sudo nginx -t && service nginx reload

Test it

Use the curl command as follows:
$ curl -I sxi.io

HTTP/1.1 301 Moved Permanently
Date: Sat, 17 Jun 2017 18:02:16 GMT
Content-Type: text/html
Connection: keep-alive
Location: https://sxi.io/
X-Whome: l-cbz01
X-Content-Type-Options: nosniff
Server: cloudflare-nginx
CF-RAY: 3707eb3d507d2ee1-DEL

OR
$ curl -I https://sxi.io
Sample outputs:

HTTP/1.1 301 Moved Permanently
Date: Sat, 17 Jun 2017 18:03:10 GMT
Content-Type: text/html
Connection: keep-alive
Location: https://sxi.io/
X-Whome: l-cbz02
Strict-Transport-Security: max-age=15552000
X-Content-Type-Options: nosniff
Server: cloudflare-nginx
CF-RAY: 3707ec8e7c612f23-DEL

See how redirection works:
$ curl -ILa sxi.io
Sample outputs:

HTTP/1.1 301 Moved Permanently
Date: Sat, 17 Jun 2017 18:04:20 GMT
Content-Type: text/html
Connection: keep-alive
Location: https://sxi.io/
X-Whome: l-cbz01
X-Content-Type-Options: nosniff


HTTP/1.1 301 Moved Permanently
Date: Sat, 17 Jun 2017 18:04:21 GMT
Content-Type: text/html
Connection: keep-alive
Location: https://sxi.io/
X-Whome: l-cbz02
Strict-Transport-Security: max-age=15552000
X-Content-Type-Options: nosniff


HTTP/1.1 200 OK
Date: Sat, 17 Jun 2017 18:04:21 GMT
Content-Type: text/html;charset=utf-8
Connection: keep-alive
Vary: Accept-Encoding
Cache-Control: public, max-age=1800
Expires: Sat, 17 Jun 2017 18:34:21 GMT
Last-Modified: Sat, 03 Jun 2017 08:24:57 GMT
Strict-Transport-Security: max-age=15552000
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1
X-Whome: l-cbz02
CF-Cache-Status: HIT

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 Nginx doinng a non-www to www redirection on Linux or Unix-like system.

(adsbygoogle = window.adsbygoogle || []).push({});

Posted by: SXI ADMIN

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.

14/08/2019

How to KVM, QEMU start or stop virtual machine from command line (CLI)

KVM or Kernel Based Virtual Machine is a popular virtualization technology. It allows you to run virtual guest machines over a host machine. To start...
14/08/2019

How to Docker backup Saving and restoring your volumes

Running a Docker volume backup First, we spin up a temporary container, and we mount the backup folder and the target Docker volume to this container....
12/08/2019

How to Start and Enable Firewalld on CentOS 7

In this article, we discuss how to start and enable firewalld. It is highly recommended that you have a firewall protecting your server.Pre-Flight CheckThese...