Reputation: 2130
I'm setting up an Nginx server with an SSL.
The domain with the SSL is www.mydomain.example
I want to redirect all requests from:
http://mydomain.example
, http://www.mydomain.example
, & https://mydomain.example
to
https://www.mydomain.example
I have the following server blocks setup currently:
server{
listen 443 ssl;
root /www/mydomain.example/;
ssl_certificate /ssl/domain.crt;
ssl_certificate /ssl/domain.key;
.
.
.
}
server{
listen 80;
server_name mydomain.example;
return 301 https://www.mydomain.example$request_uri;
}
server{
listen 80;
server_name www.mydomain.example;
return 301 https://www.mydomain.example$request_uri;
}
server{
listen ssl 443;
server_name mydomain.example;
return 301 https://www.mydomain.example$request_uri;
}
This currently does not work, but I don't understand why not. I can get a combination of either HTTP -> HTTPS working or no-www to -> www working, but mixing them as above does not work.
Upvotes: 39
Views: 36118
Reputation: 4503
I couldn't figure out why HTTP http://example.com wouldn't redirect to HTTPS https://example.com. i had configured it the following way like others have and according to https://nginx.org/en/docs/http/configuring_https_servers.html, even after restarting the server with nginx -s reload && sudo systemctl restart nginx
/etc/nginx/sites-available/example.com
server {
listen 80;
server_name www.example.com example.com;
return 301 https://$server_name$request_uri;
}
server {
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 1m;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name www.example.com example.com;
root /var/www/build;
index index.html;
location / {
try_files $uri /index.html =404;
}
}
But even though i'm using the latest browsers, the redirection from HTTP to HTTPS only works with the latest in incognito window:
But not with the latest in incognito window even after clear cache and hard reload:
With Brave and Chrome it just loads the default HTTP page "Welcome to nginx!" from /var/www/html/ index.nginx-debian.html
Upvotes: 0
Reputation: 5370
I was trying to fix the problem by redirecting the request URI to HTTPS
if it was requested with the HTTP
scheme. But this solution does not work in some conditions.
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
When we type a domain name in the search bar of a browser, it makes a request with the HTTP
scheme by default. This behavior of the browser is not handled by nginx, but it can be done manually. We have to handle 497 status code by adding error_page 497 https://$server_name$request_uri;
.
error_page 497 https://$server_name$request_uri;
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
What does the 497 indicate, and when occur?
The 497 HTTP Request Sent to HTTPS Port is used when a client has made an HTTP request to a port that is listening for HTTPS requests specifically.
Upvotes: 0
Reputation: 5831
I am late, But you can do like this
server{
listen 443 ssl;
server_name www.mydomain.example;
root /www/mydomain.example/;
ssl on;
ssl_certificate /ssl/domain.crt;
ssl_certificate /ssl/domain.key;
.
.
.
}
server{
listen 80;
server_name www.mydomain.example mydomain.example;
return 301 https://$server_name$request_uri;
}
server{
listen 443;
server_name mydomain.example;
return 301 https://www.$server_name$request_uri;
}
Or you can replace return 301 https://www.$server_name$request_uri;
with rewrite ^ http://www.$server_name$request_uri? permanent;
, both will work.
You also need to set this in google webmaster for better SEO.
Upvotes: 13
Reputation: 2490
this works for me for HTTP to HTTPS redirection,
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name example.com;
#For HTTP to HTTPS:
proxy_set_header X-Forwarded-Proto $scheme;
if ( $http_x_forwarded_proto != 'https' )
{
return 301 https://$host$request_uri;
}
location / {
try_files $uri $uri/ /index.php;
add_header 'Access-Control-Allow-Origin' '*';
}
location ~ \.php$ {
include fastcgi.conf;
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Upvotes: 1
Reputation: 1315
Please add two given things on your file.
Code to paste on top:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
Code to paste on bottom:
server {
listen 443 ssl http2;
server_name www.example.com;
# . . . other code
return 301 https://example.com$request_uri;
}
Upvotes: 0
Reputation: 570
#If you like to redirect all "http" to "https" then add the following:
server {
listen 80;
server_name yourdomain.example;
server_name www.yourdomain.example;
if ($scheme = "http")
{
rewrite ^(.*)$ https://yourdomain.example$1 permanent;
}
}
Upvotes: 0
Reputation: 42789
The SSL redirect won't work if your SSL certificate doesn't support the non-www domain. The config is correct but can be reduced to just 1 redirect server
Also don't forget to reload Nginx sudo service nginx reload
server {
listen 80;
listen 443 ssl;
server_name example.com;
# add ssl settings
return 301 https://www.example.com$request_uri;
}
Upvotes: 18
Reputation: 1057
Use a rewrite to send all HTTP traffic to HTTPS:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
This configuration listens on port 80 as the default server for both IPv4 and IPv6 and for any hostname. The return statement returns a 301 permanent redirect to the HTTPS server at the same host and request URI.
Upvotes: 0