NGINX Redirect all paths to a specific path - redirect

I have a main domain (example.com) and multiple domains (example.net, example1.info, example2.info) pointing to one location in NGINX configuration like so:
server {
server_name example.com *.com *.net *.info;
root /home/example.com/public;
}
And I want to redirect a specific path /login to example.com/login, how do I accomplish it? If I do
server {
server_name example.com *.com *.net *.info;
root /home/example.com/public;
location = /login {
return 301 https://example.com/login;
}
this work for all domains, except example.com/login because it keeps redirecting to itself.
What is the correct way of creating a redirections from a specific path on all sites to my chosen path?

The simplest logic to redirect from one site to another is to isolate the target site with its own server block. Common configuration can be imported into both server blocks by using an include statement.
I would use a default server block rather than a long list of wild cards.
Something like this:
server {
listen 80 default_server;
listen 443 ssl default_server;
include /path/to/common/config;
location = /login {
return 301 https://example.com/login;
}
}
server {
listen 443 ssl;
server_name example.com;
include /path/to/common/config;
}
See this document for details.

Related

Nginx 301 Redirect http (naked and www) to https www, plus wildcard subdomain to https

I'm trying to set up an Nginx proxy server for a multi-tenant Saas with lots of custom domain names. What I want to do is create a server block that can handle the following requests, all as 301 permanent:
http://custom-domain.com to https://www.custom-domain.com (custom-domain.com could be any user-set domain name)
http://www.custom-domain.com to https://www.custom-domain.com (again, any domain name)
http://.saas-domain.com to https://.saas-domain.com (saas-domain,com is a single domain name for my service)
I am currently handling this with a few If statements, but it looks hacky and I am hoping for some help with a more efficient way:
server {
listen 80 default_server;
location / {
# if 'www' redirect to https
if ($host ~* ^(www)) {
return 301 https://$host$request_uri;
}
# if '*.saas-domain.com' redirect to https://*.saas-domain.com
if ($host ~* ^(.*)\.saas-domain\.com) {
return 301 https://$host$request_uri;
}
# if not 'www' redirect to https and add 'www'
if ($host !~* ^(www)) {
return 301 https://www.$host$1 permanent;
}
}
}
Is this the best way to handle all of my scenarios? I think the complication is the wildcard custom domains. I'm concerned with the If statement's overhead. TIA!
Nginx recommend not to use "If" statements unless you have no other way to solve your issue. I would suggest to add separate blocks for your domain names as this will give you more flexibility.
Try the following to see if it helps.
# Capture requests that already have www and redirect to https
server {
listen 80;
server_name www.*;
return 301 https://$server_name$request_uri;
}
# Captures the saas-domain.com requests and redirects them
server {
listen 80 ;
server_name *.saas-domain.com;
return 301 https://$server_name$request_uri;
}
# Default capture everything else and redirect to https://www.
server {
listen 80 default_server;
server_name _;
return 301 https://www.$host$request_uri;
}
Test this first before implementing it in production.
Nginx Server names
Nginx if is evil
Nginx variables

Nginx: Only use server block if location matches

I have a catch all server block like this:
server {
listen 80 default_server;
server_name _;
location /blog{
# pass request to ghost
}
location /{
# pass request to custom node app
}
}
It passes to the custom node app, which verifies the requested domain, protocol, and path, and issues a single 301 redirect if necessary; we do this to minimize 301 redirects, for SEO purposes.
I also need my ghost blog to only be served at https://www.exmaple.com/blog. I added the following block:
server {
listen 80;
server_name example.com;
location /blog {
return 301 https://www.example.com$request_uri;
}
}
so that requests to the naked domain would get redirected. But now requests to example.com return the default Nginx index.html page. How do I prevent that? I'd like to avoid using if.
You need to have a catch-all in the naked domain server block that routes to the node application
server {
listen 80;
server_name example.com;
location /blog {
return 301 https://www.example.com$request_uri;
}
location /{
# pass request to custom node app
}
}

How can I redirect non-www to www.domain.com and along with that also keep the m.domain.com / subdomain.domain.com same as it is in nginx?

I used this:
server {
server_name "~^(?!www.).*" ;
return 301 $scheme://www.$host$request_uri;
}
but this redirects everything. I need to write exceptions for subdomains along with this.
If the server block containing server_name "~^(?!www.).*" is matching m.domain.com, you obviously do not have another server block with a server_name m.domain.com.
Rather than use complex regular expressions to redirect website names to a default server block, you could use the default server block to perform the redirect instead.
For example:
server {
listen 80 default_server;
return 301 http://www.domain.com/$request_uri;
}
server {
listen 80;
server_name www.domain.com m.domain.com subdomain.domain.com;
...
}
See this document for more details.

Is it feasible to redirect all possible similar domain to one domain in Nginx

I have below configuration but it only redirects my specified urls to target.fi,I want to make it more general and for any possible domain that contain "target" it will be redirected to my domain.
server {
listen 80;
server_name abctarget.fi bctarget.fi targetbcd.fi bc.target.fi;
return 301 $scheme://target.fi;
}
How to make it like server_name *target*.fi;
server {
listen 80;
server_name ?;
return 301 $scheme://target.fi;
}
You could use a wildcard name. See this documentation.

Redirect nginx config server_name to custom 404 error page

I'm new to nginx configs and have spent a lot of time googling so far. I'm trying to create a very basic nginx config file to be used in a "redirect" server.
Users will be required to point naked domains (example.com) by A-record to my redirect server IP address, and the 'www' record by CNAME to another server.
The purpose of the redirect server is to then perform a 301 redirect any/wildcard naked domains back to to the 'www' version of the domain so it can be properly handled by my other server.
But I also want to catch any misconfigured 'www' domains that are pointing to my server IP by A-record, and simply direct them to a custom error page on the redirect server with further instructions on how to set up their account correctly for my service.
Here's what I have. It works, but since I am new to writing configs I was wondering if there is a better way to handle the redirect to the custom error page in the first server block. TIA!
#redirect to error page if begins with 'www.'
server {
listen 80;
server_name ~^www.; #only matches if starts with 'www.'. Is this good enough?
rewrite ^(.*)$ /404.html; #is this the correct way to direct to a custom error page?
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}
}
#no match, so redirect to www.example.com
server {
listen 80 default_server;
rewrite ^(.*)$ $scheme://www.$host$1 permanent;
}
Prefix/suffix server name matching is faster and easier than regexp.
Also, there is no reason to use rewrite. You want to return 404, so do it and nginx will do all the rest. BTW, with rewrite you will return 200 OK with content of /404.html instead of 404 Not Found.
So here it is:
server {
listen 80;
server_name www.*;
root /usr/share/nginx/html;
error_page 404 /404.html;
location / {
return 404;
}
location = /404.html {
internal;
}
}