Nginx Redirect HTTP to HTTPS and WWW to Non-WWW - redirect

I'm having issues with this config:
#=========================#
# domain settings #
#=========================#
# Catch http://domain, and http://www.domain
server {
listen 80;
server_name www.domain domain;
# Redirect to https://domain
return 301 https://domain$request_uri;
}
# Catch https://www.domain
server {
listen 443;
server_name www.domain;
# Redirect to https://domain
return 301 https://domain$request_uri;
}
# Catch https://domain
server {
listen 443;
server_name domain;
root /usr/share/nginx/domain;
index index.html index.htm;
ssl on;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
location / {
try_files $uri $uri/ =404;
}
}
Something is wrong with the 3rd server directive. I get a SSL connection error. But when I comment our that section everything works fine. But I want www to redirect to non-www over https also
Can anyone spot the problem?

The Nginx configuration snippet below will enable you effectively redirect all http traffic to https while stripping any eventual www prefix.
As such, your site will strictly be available over https and without the www prefix.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name www.example.com example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
if ($host = www.example.com) {
return 301 https://example.com$request_uri;
}
server_name www.example.com example.com;
# SSL configuration
# Other configurations
}
With reference to if is evil, do note that it is safe to use the if directive as it is not used in a location context.

Adding the
ssl on;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
In the 3rd server directive fixed this issue.

Related

I am getting 404 while tying to reach my Rest-API with Nginx reverse_proxy

I have a Rest-API running on my cloud server 8084 port. When I try to access mysitename:8084/swagger-ui.html, I can see the Api Documentation page of Swagger. But when I try this as mysitename.com/api/swagger-ui.html, I get a 404 error.
I read a lot of similar questions about this problem on StackOverflow, I tried different solutions but I could not succeeded.
Here is my nginx config file
server {
listen 80;
listen [::]:80;
root /var/www/mysitename.com/html/;
index index.html index.htm index.nginx-debian.html;
server_name mysitename.com www.mysitename.com;
}
server {
listen 443;
server_name mysitename.com www.mysitename.com;
ssl_certificate /etc/letsencrypt/live/mysitename.com/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/mysitename.com/privkey.pem;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/petahr.access.log;
location / {
root /var/www/mysitename.com/html/;
index index.html index.htm index.nginx-debian.html;
}
}
server {
listen 443;
server_name mysitename.com www.mysitename.com;
ssl_certificate /etc/letsencrypt/live/mysitename.com/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/mysitename.com/privkey.pem;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
location /api/ {
proxy_set_header Host $host;
proxy_pass https://127.0.0.1:8084/;
proxy_read_timeout 90;
try_files $uri $uri/ =404;
}
}
EDIT
This is nginx -T output
/etc/nginx/sites-available$ sudo nginx -T
nginx: [warn] conflicting server name "mysitename.com" on 0.0.0.0:443, ignored
nginx: [warn] conflicting server name "www.mysitename.com" on 0.0.0.0:443, ignored
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
I'd appreciate it if you could help me.
The configuration check confirms Richard Smith's comment. Just a warning that there are two server blocks with the same listen and server_name.
1) Try to transfer your location /api/ {} right below your location / {} block of the 2nd server block.
2) Remove the whole 3rd server block
3) If you wish to redirect from http to https, add return 301 https://$host$request_uri; right at the end of your server block listening to port 80.
4) Run nginx -T again to check for errors.
5) Reload Nginx, if no errors were found.
Here's the suggested server block configuration file:
server {
listen 80;
listen [::]:80;
root /var/www/mysitename.com/html/;
index index.html index.htm index.nginx-debian.html;
server_name mysitename.com www.mysitename.com;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name mysitename.com www.mysitename.com;
ssl_certificate /etc/letsencrypt/live/mysitename.com/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/mysitename.com/privkey.pem;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/petahr.access.log;
location / {
root /var/www/mysitename.com/html/;
index index.html index.htm index.nginx-debian.html;
}
location /api/ {
proxy_set_header Host $host;
proxy_pass https://127.0.0.1:8084/;
proxy_read_timeout 90;
## try_files $uri $uri/ =404;
}
}
Hope that helps!

Configuring WWW prefix and HTTPS using Nginx

I want Nginx to redirect all connections to: https://domain.xyz (remove www prefix if needed and always force https), so that for example:
http://wwww.domain.xyz/param and domain.xyz/param should redirect me to https://domain.xyz. To do that i made the following config in default server:
server {
return 301 https://$host$request_uri;
listen 80 default_server;
listen [::]:80 default_server;
}
and "sub servers":
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name domain.xyz;
location / {
try_files $uri $uri/ =404;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/domain.xyz/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/domain.xyz/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
server_name subdomain.domain.xyz;
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/domain.xyz/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/domain.xyz/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
So i assumed the default server will do both for me (remove www prefix and force https), however when i try to open www.domain.xyz I'm getting this error in Chrome console:
Redirecting navigation www.domain.xyz -> domain.xyz because the server presented a certificate valid for domain.xyz but not for www.domain.xyz. To disable such redirects launch Chrome with the following flag: --disable-features=SSLCommonNameMismatchHandling
Except that everything works as expected. Also, as you can see i used letsencrypt to generate certs (for domain.xyz and subdomain.domain.xyz -- without wwww prefix (!) -- maybe that is the reason). So to sum it up:
Is my config correct for the things i want to achieve?
Should i be worried about that Chrome message?

Nginx redirrect http to https

I need to redirect all the http requests to https in nginx and also to use some self-generated SSL certificate (using opensssl), but something is wrong with my configuration:
server {
listen 80;
server_name x.x.x.x;
# 301 = permanent redirect, 302 = temporary redirect
#return 301 https://x.x.x.x;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name x.x.x.x;
root /usr/share/nginx/html;
index index.html index.htm;
ssl on;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
}

Nginx - redirect correctly from http:// to https:// without www

Following my configuration file:
server {
listen [::]:443 ipv6only=off ssl;
server_name www.example.com;
// ssl stuff
return 301 https://example.com$request_uri;
}
server {
listen [::]:80 ipv6only=off;
return 301 https://example.com$request_uri;
}
server {
listen [::]:443 ssl;
server_name example.com;
// php and ssl stuff
}
I don't understand why http://www.example.com redirects to https://www.example.com and then to https://example.com. How to redirect from http://www.example.com directly to https://example.com?
NGINX config for redirect from HTTP to HTTPS without WWW:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 default_server;
listen [::]:443 ssl http2 default_server;
server_name example.com www.example.com;
##here-ssl-settings##
return 301 https://example.com$request_uri;
}
With HSTS enabled, the first redirect is done directly by your browser without any network interaction.

Nginx www. to non-www. redirect not working

I followed the instructions at https://stackoverflow.com/a/11733363/2532070 to redirect www to non-www. I'm trying to redirect the following formats:
http://example.com
http://www.example.com
https://www.example.com
all to:
https://example.com
http://example.com is redirecting to https. However, the other two, with www., are not. Here is my nginx.conf:
upstream app_server {
server 127.0.0.1:9000 fail_timeout=0;
}
#
# Redirect all www to non-www
#
server {
server_name www.example.com;
ssl_certificate /src/bin/ssl/ssl-bundle.crt;
ssl_certificate_key /etc/ssl/private/STAR_example_com.key;
listen *:80;
listen *:443 ssl spdy;
listen [::]:80 ipv6only=on;
listen [::]:443 ssl spdy ipv6only=on;
return 301 https://example.com$request_uri;
}
#
# Redirect all non-encrypted to encrypted
#
server {
server_name example.com;
listen *:80;
listen [::]:80;
return 301 https://example.com$request_uri;
}
#
# There we go!
#
server {
server_name example.com;
ssl_certificate /src/bin/ssl/ssl-bundle.crt;
ssl_certificate_key /etc/ssl/private/STAR_example_com.key;
listen *:443 ssl spdy;
listen [::]:443 ssl spdy;
# rest goes here...
root /usr/share/nginx/html;
index base.html index.html index.htm;
client_max_body_size 4G;
keepalive_timeout 5;
# Your Django project's media files - amend as required
location /media {
alias /src/media;
expires 1y;
add_header Cache-Control "public";
}
# your Django project's static files - amend as required
location /static {
alias /src/static;
expires 1y;
add_header Cache-Control "public";
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
I'm not seeing anything in the nginx log file to indicate the error. Is there somewhere to look for the error when I try to access a www. version? Thanks!
You are most likely experiencing problems with browser caching. Try purging your cache, e.g. check the disable cache in Chrome dev tools network tab or in Firefox's dev tools settings. That should fix it.