Nginx redirect for http and https - redirect

I am trying to force HTTPS for incoming connections while also redirecting all requests to a certain url.
Desired result:
http://example.com -> https://example.com/dir
https://example.com -> https://example.com/dir
Here is what I believe should work but is saying there are too many redirects.
server {
listen 80;
listen 443 ssl;
server_name example.com;
location / {
return 301 https://$server_name/dir$request_uri;
}
location /dir {
try_files $uri $uri/ /index.php?$args;
}
Any help is much appreciated!

Server that is listening to 443 port shouldn't redirect to itself (return 301 https://...)

Can you try this,
server {
listen 80;
listen 443;
server_name example.com;
location / {
return 301 https://example.com/dir$request_uri;
}
location /dir {
...
...
}
}
Basically the idea is to keep both listen directive in the same server block. The above code is just an excerpt and you need to fill in the missing pieces.You can refer the return directive section of this link for more detail
EDIT: Updated the code with location block.

Related

Combine redirect with serve files

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.

Nginx redirect formatting

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;
}
}

Nginx Redirect all to https and non www - redirect loop

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;
}

Redirect www and http requests to https://, catching all domains, in nginx

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;
}
}

How to redirect a specific path to the same path without www in nginx

I've encountered an issue during server configuration: I require a 301 redirect from http://www.example.com to http://example.com just for one specific url alias - like /partners.
the expected output- http:// www.example.com/partners/stuff -> http:// example.com/partners/stuff.
I've tried adding the following code to the vhosts already:
server {
server_name http://www.example.com/partners;
return 301 $scheme://example.com/partners;
}
but vhosts gives me an error telling me this code isn't valid.
What's the correct way of implementing such rewrite?
server_name is for domain only. I can suggest you 2 solutions.
Copy configs between servers. This is the best solution recommended by nginx's author.
server {
server_name example.com;
include example.com.conf;
}
server {
server_name www.example.com;
include example.com.conf;
location /partners/ {
return 301 $scheme://example.com$request_uri;
}
}
Or using if. Bad solution due performance
server {
server_name .example.com;
...
location /partners/ {
if ($host = "www.example.com") {
return 301 $scheme://example.com$request_uri;
}
}
}
http://wiki.nginx.org/IfIsEvil
http://wiki.nginx.org/Pitfalls#Server_Name