HTTPS and no www with Nginx
I have tried to find the most efficient way to redirect all trafic for a specific domain to its https counterpart, and also to redirect to the domain without the www
subdomain.
I'm using Nginx in production and after combining various different solutions I found, I settled on this simple configuration that I now use and that I think is quite straightforward and efficient. Thought I'd share, for what it's worth.
(In this example the backend is a PHP application located in /var/www/my-website/
and I'm using letsencrypt for the certificates)
# no SSL
# Redirect both urls to the http server block
server {
server_name my-website.fr www.my-website.fr;
return 301 https://my-website.fr$request_uri;
}
# The main block : SSL
server {
server_name my-website.fr www.my-website.fr;
# If it has a www, rewrite.
# The 'last' here is important
# because we are cautious with the 'if's
# nginx.com/resources/wiki/start/topics/depth/ifisevil
if ($host ~* ^www\.){
rewrite ^(.*)$ https://my-website.fr$1 last;
}
include ssl.conf;
ssl_certificate /etc/letsencrypt/live/my-website.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-website.fr/privkey.pem;
# Application-specific stuff, just for illustrating
index index.php;
root /var/www/my-website;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /index.php$is_args$args;
}
# Pass on to FPM
location ~ \.php$ {
include php-fpm.conf;
}
# Deny access to .ht* files
location ~ /\.ht {
deny all;
}
}
ssl.conf
is as follows (of course, you might need to create the /etc/ssl/certs/dhparam.pem
file beforehand, with sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
):
listen 443 ssl;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.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_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
And, for reference, php-fpm.conf
is available here