Reputation: 841
Nginx isn't working to redirect non-www to www if I'm on https
:
https://domain.com to https://www.domain.com
My curent setup in .conf
is:
server {
listen 80;
server_name www.domain.com domain.com;
return 301 https://www.domain.com$request_uri;
}
server {
listen 443;
server_name domain.com;
return 301 https://www.domain.com$request_uri;
}
server {
listen IP_ADDRESS:443 ssl;
server_name www.domain.com;
...
}
http://domain.com to https://www.domain.com and http://www.domain to https://www.domain.com works, but non-www to www on https isn't working.
If I added the IP_ADDRESS on the second server
block, I get an error in Chrome (SSL error) and both (www and non-www) stop working.
UPDATE:
Thanks to Steffen (below answer), I updated the self-signed certificate to be *.domain.com
and not domain.com
.
The .conf
file was updated under this format:
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
server {
listen 80;
server_name www.domain.com domain.com;
return 301 https://www.domain.com$request_uri;
}
server {
listen 443 ssl;
server_name domain.com;
return 301 https://www.domain.com$request_uri;
}
server {
listen 443 ssl;
server_name www.domain.com;
...
}
Upvotes: 3
Views: 7223
Reputation: 12671
I had similar kind of scenario and this is how I solved the redirection problem
https://example.com -----> https://www.example.com
server {
listen 443;
server_name example.com;
if ($host = example.com) {
rewrite ^(.*) https://www.example.com:443$request_uri? permanent;
}
}
Hope this helps!
Directive if has problems when used in location context, in some cases it doesn't do what you expect but something completely different instead. In some cases it even segfaults. It's generally a good idea to avoid it if possible. The only 100% safe things which may be done inside if in location context are: return ...; rewrite ... last;
Upvotes: 9
Reputation: 149
I have used rewrite on both server directive and it worked for me:
General Rewrite Directive non www to https wwww
server {
listen 80;
server_name example.com www.example.com;
return 301 https://www.$server_name$request_uri;}
SSL Rule directive for non www to https wwww
server {
listen 443 ssl;
server_name example.com;
return 301 https://www.$server_name$request_uri;}
Upvotes: 0
Reputation: 51
In 2nd server block (one starting with "listen 443;") you must add all SSL-related directives that are in the SSL server group (last group). This is my example.conf:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://www.$server_name$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
return 301 https://www.$server_name$request_uri;
# SSL
ssl on;
ssl_certificate /var/www/example.com/cert/bundle.cer;
ssl_certificate_key /var/www/example.com/cert/example.com.key;
# Enables all versions of TLS, but not SSLv2 or 3 which are weak and now deprecated.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Intermediate cypersuite as recommended by Mozilla
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;
# Add HSTS (HTTPStrictTransportSecurity)
add_header Strict-Transport-Security "max-age=31536000";
}
server {
listen 443 ssl;
server_name www.example.com;
root /var/www/example.com/public;
index index.html index.htm index.php;
client_max_body_size 32m;
access_log /var/www/example.com/access.log;
error_log /var/www/example.com/error.log;
# SSL
ssl on;
ssl_certificate /var/www/example.com/cert/bundle.cer;
ssl_certificate_key /var/www/example.com/cert/example.com.key;
# Enables all versions of TLS, but not SSLv2 or 3 which are weak and now deprecated.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Intermediate cypersuite as recommended by Mozilla
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;
# Add HSTS (HTTPStrictTransportSecurity)
add_header Strict-Transport-Security "max-age=31536000";
# Directives to send expires headers and turn off 404 error logging.
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
#expires max;
log_not_found off;
access_log off;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
## Disable viewing .htaccess & .htpassword
location ~ /\.ht {
deny all;
}
location ^~ /admin/ {
auth_basic "Restricted";
auth_basic_user_file /var/www/example.com/.htpasswd;
try_files $uri $uri/ /index.php$is_args$args;
location ~ \.php$ {
include /etc/nginx/php-inside.conf;
}
}
include /etc/nginx/php.conf;
}
Upvotes: 5
Reputation: 567
This is a more graceful solution that I use. Requires one server block for the actual website, and one server block for the redirect from non-www/non-https to https://www.*
.
server {
listen IP_ADDRESS:443 ssl;
server_name www.domain.com;
}
server {
listen IP_ADDRESS:80 ssl default_server;
listen IP_ADDRESS:443 ssl default_server;
return 301 https://www.domain.com$request_uri;
}
The default_server option is important, otherwise the first definition becomes the default which can work against your intentions of redirecting all requests other than www.domain.com
. By using default_server, your redirect server block acts as a catch-all.
In my opinion though, you should NOT be using "www". You should be redirecting from www to non-www. www is a legacy thing that isn't relevant these days. You're perpetuating this irrelevant legacy by redirecting from non-www to www.
Upvotes: 0
Reputation: 123250
This is probably because you don't have a certificate for domain.com, but only for www.domain.com or *.domain.com. See Nginx redirect http://www and naked http/https to https://www or https://serverfault.com/questions/579916/nginx-redirect-https-www-to-https-non-www-without-untrusted-connection-warn/579917#579917 for details.
Upvotes: 4