Nginx: Redirect All HTTP and HTTPS non-WWW to HTTPS WWW

One common requirement for a web site, especially in the age of mandatory SSL, is to ensure that its address is a) consistent, and b) forwards to SSL. In other words, when a visitor types in http://www.mysite.com/, http://mysite.com/, OR https://mysite.com/, they should be sent to https://www.mysite.com/.

To do this, we’ll set up some Nginx server blocks in a config file located at /etc/nginx/sites-available/mysite.com (we’re on Ubuntu 16 here, we’re running a PHP web site using PHP7.0-FPM, and we’re assuming you’ve got your SSL key-certificate pair ready to go).

First, we set up our forwards for http://mysite.com/ and http://www.mysite.com/:

1
2
3
4
5
6
server {
        listen       80;
        listen       [::]:80;
        server_name  mysite.com www.mysite.com;
        return       301 https://www.mysite.com$request_uri;
}

Next, we configure https://mysite.com to forward to https://www.mysite.com/ (we need our SSL cert to be working for this):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
        listen       443 ssl http2;
        listen       [::]:443 ssl http2;
 
        server_name  geoffstratton.com;
 
        ssl_certificate /etc/path/to/my/certificate.pem;
        ssl_certificate_key /etc/path/to/my/privatekey.pem;
 
        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
 
        ssl_prefer_server_ciphers on;
        ssl_dhparam /etc/ssl/certs/dhparams.pem;
 
        return       301 https://www.mysite.com$request_uri;
}

Finally, we set up our non-forwarding server block:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
listen 443 ssl http2;
listen [::]:443 ssl http2;
 
server_name www.mysite.com;
 
error_log /var/log/nginx/mysite_error.log;
access_log /var/log/nginx/mysite_access.log;
 
ssl_certificate /etc/path/to/my/certificate.pem;
ssl_certificate_key /etc/path/to/my/privatekey.pem;
 
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
 
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparams.pem;
 
root /var/www/mysite.com;
 
# Add index.php to the list if you are using PHP
index index.php;
# index index.html index.htm index.nginx-debian.html;
 
location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        # try_files $uri $uri/ =404;
        try_files $uri @rewrite;
}
 
location @rewrite {
        rewrite ^ /index.php last;
}
 
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ .php$ {
        include snippets/fastcgi-php.conf;
#
#       # With php7.0-cgi alone:
#       fastcgi_pass 127.0.0.1:9000;
#       # With php7.0-fpm:
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
 
location ~*  .(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 7d;
}

Finally, remember to symlink your config file to /etc/nginx/sites-enabled/ (ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/mysite) and restart Nginx (systemctl restart nginx).

Loading

Leave a Reply

Your email address will not be published. Required fields are marked *