NGINX rewrite rule to remove leading www for Vanity URL - nginx

I've searched everywhere and although there are 1000s of examples of how to strip a leading www from a URL using NGINX rewrite rules, I've yet to find an example of how to strip the leading 'www' from a vanity url.
For example, convert 'www.fred.mysite.com' to 'fred.mysite.com'
Can you share an example of how this should work in an nginx rewrite rule?

the easiest way to do it is with a 2nd serverblock as follows:
server {
listen [::]:80; listen 80;
server_name www.fred.mysite.com;
return 301 $scheme://fred.mysite.com$request_uri;
}
server {
listen [::]:80; listen 80;
server_name fred.mysite.com;
#your site setup goes here
}
though you probably want to use "server_name *.fred.mysite.com;" in the 1st serverblock just to catch every possible extra prefix including misspellings

Related

nginx Redirect specific subdomain and path

Our nginx config serves multiple sites with their own subdomains.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name ~^(?P<sub>.+)\.(example1|example2)\.com$;
root /var/www/instances/$sub;
...
}
I want to redirect one specific subdomain with its path to different sites, but I cannot figure out how to write the check. I need to check for the host part and then check for the path to decide where the redirect should land.
The map looks somehting like this:
Old URI
New URI
sub1.example1.com/wiki/0/$path
newSub1.example1.com/wiki/0/$path
sub1.example1.com/wiki/20/$path
newSub2.example1.com/wiki/0/$path
Where $path is simply the rest of the request URI
All other requests to sub1.example1.com should work as before.
The obvious solution is to split sub1.example1.com into a separate server block. As you will see from this document a server_name with an exact name always takes precedence over a server_name with a regular expression.
This means that there are two server blocks with near identical contents, but this can be mitigated by using the include directive.
Alternatively, you can test the value of $host$request_uri using a map directive. This is less efficient, as you will be testing the URL in every site.
For example:
map $host$request_uri $redirect {
default 0;
~*^sub1.example1.com/wiki/0/(?<path>.*)$ //newSub1.example1.com/wiki/0/$path;
~*^sub1.example1.com/wiki/20/(?<path>.*)$ //newSub2.example1.com/wiki/0/$path;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name ~^(?P<sub>.+)\.(example1|example2)\.com$;
root /var/www/instances/$sub;
if ($redirect) { return 301 $scheme:$redirect; }
...
}

Nginx - all domains redirect

I looked around to see NGINX configuration for ALL domains and sub-domain but I can only find configurations that are specified.
This is what I want to achieve
server {
listen 80;
server_name all;
return 301 https://www.test.com$request_uri;
}
but then I don't want www.test.com forwarded, only anything else that doesn't match it, even if it is like x.test.com it should be forward too
how I can do it?
You need to provide a separate server block for the domain you don't want to redirect. For example:
server {
listen 80;
server_name www.test.com;
# rest of configuration
}
server {
listen 80 default_server;
return 301 https://www.test.com$request_uri;
}
BTW, you are redirecting to https. Then you need to listen not only 80, but 443 as well. I hope you have it working and left out for the question's simplicity. Otherwise, the documentation is here.

Rewrite module NGINX

Hi how can I rewrite my URL into a certain format?
Example:
# I have this URL
http://www.mywebsite.com
I would like it to be written into something like this
https://www.mywebsite.com.truesite.com
So if my URL is something like this
http://www.mywebsite.com/newsite?test=message
# it will be rewritten into like this
https://www.mywebsite.com.truesite.com/newsite?test=message
I'm not really good when it comes to regex so I have no idea on how to accomplish this on NGINX
Since this is an HTTP to HTTPS passing, you need more than the rewrite module of Nginx.
server {
listen 80;
listen [::]:80;
server_name www.mywebsite.com;
return 301 https://www.mywebsite.com.truesite.com$request_uri;
}
You need to have another block on your https website which includes SSL.

nginx server_name regex

server_name in nginx does not match
I want to match with such FQDNs
I came up with
server_name "~^(www.)?ucwebapi-uccore(\d{0,3})-(\d{0,3})\.testme\.net";
To Match
ucwebapi.testme.net
ucwebapi-uccore.testme.net
ucwebapi-uccore1-0.testme.net
ucwebapi-uccore999-999.testme.net
Validated with https://regex101.com/r/tAwEp9/2
Tested with
server_name "~^(www.)?ucwebapi-uccore(\d{0,3})-(\d{0,3})\.testme\.net ucwebapi1.testme.net";
to see if ucwebapi1.testme.de server is reachable at all.
Is there any restriction im not aware of?
Thank you.
Try this:
server_name "~^(www.)?ucwebapi(-uccore)?(\d{1,3}-\d{1,3})?\.testme\.net";
It looks like there are some missing characters between your regex101 page and what ended up in your config.
I've also tuned it a bit so that it will NOT match:
ucwebapi-uccore999.testme.net
ucwebapi-uccore-.testme.net
ucwebapi-uccore-999.testme.net
I've never seen server_name configurations with double-quotes... but I'm not shure if that solves the problem.
Some example configurations here.
Edit: Do you have a default virtual server like this:
server {
listen 80;
server_name _;
return 404; # default
}
# now add your specific server
server {
listen 80;
server_name "~^(www.)?ucwebapi-uccore(\d{0,3})-(\d{0,3})\.testme\.net ucwebapi1.testme.net";
...
}
Specific configurations will only work if you have a default configured.
#abcdn: your absolutely right, i didn't know that!
Try:
server_name "~^(www.)?ucwebapi-uccore(\d{0,3})-(\d{0,3})\.testme\.net" ucwebapi1.testme.net;
Your server_name quotes encompassed the entire line. What is probably perceived as 2 separate entries, nginx interpolated as a single entry.

nginx server_name wildcard or catch-all

I have an instance of nginx running which serves several websites. The first is a status message on the server's IP address. The second is an admin console on admin.domain.com. These work great. Now I'd like all other domain requests to go to a single index.php - I have loads of domains and subdomains and it's impractical to list them all in an nginx config.
So far I've tried setting server_name to * but that failed as an invalid wildcard. *.* works until I add the other server blocks, then I guess it conflicts with them.
Is there a way to run a catch-all server block in nginx after other sites have been defined?
N.B. I'm not a spammer, these are genuine sites with useful content, they're just powered by the same CMS from a database!
Change listen option to this in your catch-all server block. (Add default_server) this will take all your non-defined connections (on the specified port).
listen 80 default_server;
if you want to push everything to index.php if the file or folder does not exist;
try_files $uri /$uri /index.php;
Per the docs, It can also be set explicitly which server should be default, with the **default_server** parameter in the listen directive
As a convention, the underscore is used as a server name for default servers.
From http://nginx.org/en/docs/http/server_names.html
In catch-all server examples the strange name “_” can be seen:
server {
listen 80 default_server;
server_name _;
return 444;
}
There is nothing special about this name, it is just one of a myriad of >invalid domain names which never intersect with any real name. Other >invalid names like “--” and “!##” may equally be used.
Note that server_name _; alone is not enough. The above example only works because of default_server in the listen directive.
This will work:
server_name ~^(.+)$
Now you can use mask:
server {
listen 80;
server_name *.example.org;
...
}
server {
listen 80;
server_name mail.*;
...
}
Look more here: http://nginx.org/en/docs/http/server_names.html
Only 1 server directive
From Nginx listen Docs
The default_server parameter, if present, will cause the server to
become the default server for the specified address:port pair. If none
of the directives have the default_server parameter then the first
server with the address:port pair will be the default server for this
pair.
If you only have 1 server directive, that will handle all request, you don't need to set anything.
Multiple server directive
If you want to match all request with specified server directive, just add default_server parameter to listen, Nginx will use this server directive as default.
server {
listen 80 default_server;
}
About server_name _;
From Nginx Docs
In catch-all server examples the strange name “_” can be seen:
server {
listen 80 default_server;
server_name _;
return 444;
}
There is nothing special about this name, it is just one of a myriad
of invalid domain names which never intersect with any real name.
Other invalid names like “--” and “!##” may equally be used.
It doesn't matter what server_name you set, it is just an invalid domain name.
For me somehow define default_server was not working. I solved it by
server_name ~^.*$
using regular expression of all.
If you also want to catch requests with empty Host header (which is allowed in HTTP/1.0) you can use both regex and empty server_name:
server {
listen 80;
server_name ~. "";
}
Try $http_host
server {
server_name $http_host;
}

Resources