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

ADVERTISEMENTS



Update your virtual domain config file as follows for HTTP redirection

I want ALL cyberciti.biz to go to www.cyberciti.biz 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 cyberciti.biz) traffic to www (e.g. domain name www.cyberciti.biz) 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.

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

## redirect http://cyberciti.biz to http://www.cyberciti.biz/ server { listen 80 ; access_log off; error_log off; server_name cyberciti.biz; return 301 http://www.cyberciti.biz$request_uri; } ## Continue below for www.cyberciti.biz server { listen 80 ; access_log off; error_log off; server_name www.cyberciti.biz; ## rest of config below ## } ## redirect http://cyberciti.biz to http://www.cyberciti.biz/ server { listen 80; access_log off; error_log off; server_name cyberciti.biz; return 301 http://www.cyberciti.biz$request_uri; } ## Continue below for www.cyberciti.biz server { listen 80; access_log off; error_log off; server_name www.cyberciti.biz; ## 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/cyberciti.biz.conf

Update it as follows:

## redirect http://cyberciti.biz to https://cyberciti.biz ## server { listen 80 ; access_log off; error_log off; server_name cyberciti.biz; return 301 https://$server_name$request_uri; } ## redirect www.cyberciti.biz to https://www.cyberciti.biz/ server { listen 80 ; access_log off; error_log off; server_name www.cyberciti.biz; return 301 https://$server_name$request_uri; } ## redirect http://cyberciti.biz to https://cyberciti.biz ## server { listen 80; access_log off; error_log off; server_name cyberciti.biz; return 301 https://$server_name$request_uri; } ## redirect www.cyberciti.biz to https://www.cyberciti.biz/ server { listen 80; access_log off; error_log off; server_name www.cyberciti.biz; 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://cyberciti.biz/ to https://www.cyberciti.biz/ server { listen 443 ssl http2; access_log off; error_log off; server_name cyberciti.biz; return 301 https://www.cyberciti.biz$request_uri; } ## define our https://www.cyberciti.biz/ ## server { listen 443 ssl http2; access_log /var/log/nginx/www.cyberciti.biz_access.log; error_log /var/log/nginx/www.cyberciti.biz_error.log; ## server name and root server_name www.cyberciti.biz; root /home/lighttpd/cyberciti.biz/http; # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate ssl_certificate /etc/nginx/ssl/letsencrypt/cyberciti.biz/cyberciti.biz.crt; ssl_certificate_key /etc/nginx/ssl/letsencrypt/cyberciti.biz/cyberciti.biz.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/cyberciti.biz/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://cyberciti.biz/ to https://www.cyberciti.biz/ server { listen 443 ssl http2; access_log off; error_log off; server_name cyberciti.biz; return 301 https://www.cyberciti.biz$request_uri; } ## define our https://www.cyberciti.biz/ ## server { listen 443 ssl http2; access_log /var/log/nginx/www.cyberciti.biz_access.log; error_log /var/log/nginx/www.cyberciti.biz_error.log; ## server name and root server_name www.cyberciti.biz; root /home/lighttpd/cyberciti.biz/http; # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate ssl_certificate /etc/nginx/ssl/letsencrypt/cyberciti.biz/cyberciti.biz.crt; ssl_certificate_key /etc/nginx/ssl/letsencrypt/cyberciti.biz/cyberciti.biz.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/cyberciti.biz/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 cyberciti.biz

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

OR

$ curl -I https://cyberciti.biz

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://www.cyberciti.biz/ 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 cyberciti.biz

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://cyberciti.biz/ 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://www.cyberciti.biz/ 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

And there you have Nginx doinng a non-www to www redirection on Linux or Unix-like system.