I'm setting up a server to host a website at 'https://domain.tld'. I need http and https schemes of 'www.domaintld.com', 'domaintld.com', and 'www.domain.tld' to all redirect to 'https://domain.tld'. I thought I had it all nice and happy, and with Chrome on Mac it's happy as a clam. Unfortunately, it doesn't seem to work in any other browsers. I've had a hard time finding the appropriate settings, and I'm new to Nginx.
Current config:
...
server {
listen 80;
listen 443 ssl;
server_name www.domaintld.com;
return 301 $scheme://domain.tld$request_uri;
}
server {
listen 80;
listen 443 ssl;
server_name domaintld.com;
return 301 $scheme://domain.tld$request_uri;
}
server {
listen 80;
listen 443 ssl;
server_name www.domain.tld;
return 301 $scheme://domain.tld$request_uri;
}
server {
# SSL configuration
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/ssl-domain.tld.conf;
include snippets/ssl-params.conf;
...
location ~ /.well-known {
allow all;
}
root /var/www/html;
server_name domain.tld;
location / {
# Redirect to index instead of 404
try_files $uri $uri/ /index.php$is_args$args;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$ {
include snippets/fastcgi-php.conf;
# With php7.0-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# With php7.0-fpm:
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
location ~ /\.ht {
deny all;
}
}
Related
I have a couple of server blocks that are not playing nice with each other and I want to serve the files from the .well-known/ folder but also redirect to https when they are not from the .well-known/ folder
How can I make one server block that redirects but also serve some files?
sites-enabled/block1
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html;
server_name _;
location ~ /.well-known {
allow all;
}
location / {
try_files $uri $uri/ =404;
}
}
sites-enabled/block2
server {
listen 80;
listen [::]:80;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com cdn.example.com subdomain.example.com;
return 301 https://$host$request_uri;
}
You could replace all three server blocks with this:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html;
location /.well-known {
}
location / {
return 301 https://$host$request_uri;
}
}
Using a default_server for port 80 will redirect all requests to the similarly named https server, unless the URI begins with /.well-known.
See this document for more.
I've looked on Stack Overflow and other sites but cannot seem to get this redirect working. Everything is working as expected, except:
The following work:
http://example.com -> https://example.com
http://www.example.com -> https://example.com
This does NOT redirect to the non-www (it keeps the www in place):
https://www.example.com -> https://example.com
Both the www and non-www https versions seem resolve as is. Any ideas?
Here is the current config:
# Redirect WWW to NON-WWW
server {
# Server host
server_name www.example.com;
# Server ports
listen 80;
listen 443;
listen [::]:80;
listen [::]:443;
# SSL
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Redirect
return 301 https://example.com$request_uri;
}
# Redirect HTTP to HTTPS
server {
# Server host
server_name example.com;
# Server port
listen 80;
listen [::]:80;
# Redirect
return 301 https://example.com$request_uri;
}
# Main Block
server {
# Server host
server_name example.com;
# Server port
listen 443 ssl;
listen [::]:443;
# SSL
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
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;
root /var/www/example.com;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /.well-known {
allow all;
}
}
My config:
server {
listen 80;
listen 443 spdy;
server_name subdomain.domain.com;
add_header Alternate-Protocol 443:npn-spdy/3.1;
include custom.d/ssl-redirect.conf;
ssl_certificate /etc/ssl/domain.com/domain_com-nginx.crt;
ssl_certificate_key /etc/ssl/domain.com/domain_com.key;
access_log /var/log/nginx/domain_com.access.log geo;
error_log /var/log/nginx/domain_com.error.log error;
set $fpm_pool domain.com;
root /home/domain.com/htdocs/domain_com/public;
index index.html index.php;
location / {
proxy_pass https://domain.com/mypath;
}
include custom.d/restrictions.conf;
include custom.d/fpmstatus.conf;
}
I have https://domain.com/mypath URL.
And I want watch this when a call subdomain.domain.com
And when I call subdomain.domain.com/sompage. In may be throw https://domain.com/mypath/sompage
You just need to add a return, the best would be a 301 status code here:
return 301 https://domain.com/mypath$request_uri;
It may look like this in your code:
server {
listen 80;
listen 443 spdy;
server_name subdomain.domain.com;
add_header Alternate-Protocol 443:npn-spdy/3.1;
include custom.d/ssl-redirect.conf;
ssl_certificate /etc/ssl/domain.com/domain_com-nginx.crt;
ssl_certificate_key /etc/ssl/domain.com/domain_com.key;
access_log /var/log/nginx/domain_com.access.log geo;
error_log /var/log/nginx/domain_com.error.log error;
set $fpm_pool domain.com;
root /home/domain.com/htdocs/domain_com/public;
index index.html index.php;
return 301 https://domain.com/mypath$request_uri;
include custom.d/restrictions.conf;
include custom.d/fpmstatus.conf;
}
I am trying to redirect all non http and www traffic for the server_name to https://example.com. I have the following issues:
Any requests for http://www.example.com don't get redirected;
Any requests for http : //example.com get error 400;
Any requests for https go into a 301 redirect loop.
I've tried multiple variations using separate server blocks and the closest I came was getting it all working except the redirect loop which plagues me no matter what I do. Would appreciate some advice and pointers here. Code is below:
server {
listen 443;
listen 80;
server_name www.example.com example.com;
root /home/example/public_html;
index index.html index.htm index.php;
#SSL Stuff here
if ($scheme = http) { return 301 https://example.com$request_uri; }
if ($server_name = www.example.com) { return 301 https://example.com$request_uri; }
include conf.d/wp/restrictions.conf;
include conf.d/wp/wordpress.conf;
}
EDIT
So I tried the below and it all works with no 301 loop apart from http : //www.example.com is allowed to pass with no redirect to SSL. I don't understand how that's possible as it should be caught by the port 80 rule no? Updated config below:
server {
listen 80;
server_name example.com;
server_name www.example.com;
return 301 https://$server_name$request_uri;
}
################# SECURE #################
server {
listen 443;
server_name example.com;
access_log /var/log/nginx/example-ssl.access.log;
error_log /var/log/nginx/example-ssl.error.log;
root /home/example/public_html;
index index.html index.htm index.php;
# SSL Stuff here
#include conf.d/wp/restrictions.conf;
#include conf.d/wp/wordpress.conf;
}
There are a few issues with your config.
I would replace $server_name for $host or hardcode the domain
you want, like "secondexample.com$request_uri"
You are missing the ssl tag in the server 443 line.
Config:
server {
listen 80;
server_name example.com;
server_name www.example.com;
return 301 https://$host$request_uri;
}
################# SECURE #################
server {
listen 443 ssl;
server_name example.com;
access_log /var/log/nginx/example-ssl.access.log;
error_log /var/log/nginx/example-ssl.error.log;
root /home/example/public_html;
index index.html index.htm index.php;
# SSL Stuff here
#include conf.d/wp/restrictions.conf;
#include conf.d/wp/wordpress.conf;
}
In nginx, we wish to redirect all requests sent to:
https://www.<domain>
http://www.<domain>
http://<domain>
To:
https://<domain>
ie SSL, without the www prefix, as a catch-all, without specifying each domain individually.
The config we have come up with nearly works:
server {
server_name "~^www\.(.*)$" ;
return 301 https://$1$request_uri ;
}
server {
listen 80 default;
client_max_body_size 10m;
client_body_buffer_size 128k;
return 301 https://$host$request_uri;
}
server {
listen 443;
ssl on;
..... etc ......
...but the first server block (the www catch) seems to be matching all requests, and not just the ones that are www.*
nginx manual: A redirect to a main site
server {
listen 80;
listen [::]:80;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 default_server ssl;
server_name www.example.com example.org;
ssl_certificate /path/to/my/cert;
ssl_certificate_key /path/to/my/key;
}
don't lose “everything else”:
server {
listen 80 default_server;
server_name _;
return 301 http://example.com$request_uri;
}
more efficient, by only running the rewrite on the http protocol it avoids having to check the $scheme variable on every request (IfIsEvil)
Maybe you can try use in one place 80/443:
server {
listen 80;
listen [::]:80;
listen 443 default ssl;
server_name www.example.com;
ssl_certificate /path/to/my/cert;
ssl_certificate_key /path/to/my/key;
if ($ssl_protocol = "") {
rewrite ^ https://$server_name$request_uri? permanent;
}
}