nginx HTTPS WWW redirect to non-WWW
My SSL certificate is for mydomain.com, so i am trying to redirect all www.mydomain.com over to without www. Now, all these work:
http://www.mydomain.com
http://mydomain.com
https://mydomain.com
but https://www.mydomain.com is giving the "Site not safe" warning to the browser... I tried setting up a redirect like the below but please tell me where my script is buggy...
server {
listen 80;
server_name www.mydomain.com mydomain.com;
rewrite ^(.*) https://mydomain.com$1 permanent;
client_max_body_size 100M;
location / {
index index.htm index.html index.php;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME /var/www/mysite$fastcgi_script_name;
}
}
server {
listen 443;
ssl on;
ssl_certificate /usr/local/nginx/conf/public.crt;
ssl_certificate_key /usr/local/nginx/conf/server.key;
server_name www.mydomain.com;
rewrite ^(.*) https://mydomain.com$1 permanent;
}
server {
listen 443;
ssl on;
ssl_certificate /usr/local/nginx/conf/public.crt;
ssl_certificate_key /usr/local/nginx/conf/server.key;
client_max_body_size 100M;
server_name mydomain.com;
root /var/www/mysite;
index index.php;
location ~ \.php$ {
include fastcgi_params;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME /var/www/mysite$fastcgi_script_name;
}
}
Solution 1:
Your configuration script is not buggy.
With your current configuration (assuming that you have a standard single subject SSL Certificate installed), this is not an option.
The reason for this is the way https connections work:
When a client (the browser), issues a https request to the server (nginx), it initiates an SSL session by way of an SSL handshake. When, and only when, the handshake succeeds and the session is established, the browser sends the actual HTTP request containing the hostname. Since SSL/TLS is not only a way to provide encryption for data connections, but also a way for the server to authenticate itself to the client. As part of the authentication process, the browser validates the identity of the server. One of the validation checks is to match the certificate subject name with the hostname that the browser intends to request content from. If this validation fails, the browser issues a warning to the user.
Since the validation process fails, the server never receives the HTTP request for www.mydomain.com on the port 443 listener, and thus cannot send a redirect response to the client/browser.
To enable redirection from https://www.mydomain.com/ to https://mydomain.com, you have a few options, but it all comes down to this: you need a certificate with a subject for each hostname.
-
SAN Certificate
- Obtain a UC/SAN Certificate, and have www.mydomain.com added as a SAN (Subject Alternate Name)
- The subject(s) now match requests for both
mydomain.com
andwww.mydomain.com
-
Multiple IP addresses
- Obtain another IP address for your server.
- Obtain an SSL certificate with the subject name
www.mydomain.com
- Configure the
www.mydomain.com
httpsserver
to listen on the new IP address (still port 443) - Configure the
www.mydomain.com
httpsserver
to use the new certificate - Update the A record for www.mydomain.com to point at the new IP address in your public DNS zone
-
TLS SNI
- Like in the above example, obtain an SSL certificate with the subject name
www.mydomain.com
- Instead of using another IP address, take advantage the Server Name Indication TLS Extension.
- Like in the above example, obtain an SSL certificate with the subject name
Since SNI has limited browser support, I would avoid suggestion 3. Check out the nginx documentation on SNI if you like (bottom of the page)
UPDATE: Some Certificate Authorities offer single subject certificates with a free additional SAN for the www.
prefix.
Solution 2:
You cannot avoid the "site-not-safe" warnings if your domains don't match. Your certificate must be valid for every single domain you want to serve over HTTPS, including the redirect-only domains.
If your certificate is not valid for "www.example.com", being only valid for "example.com", then you cannot redirect from https://www.example.com/ to https://example.com/ without a security warning.