nginx conf regex for server_name for specific REST route - regex

Setting up nginx config for my EC2 server already having a Laravel project deployed. What I require is to allow another domain to access my server, but only a specific REST route. So something like -
www.otherdomain.com/users/{user_id}/features/{feature_id}
Where user_id and feature_id could have any value
I have tried a number of regular expressions given on web but I am missing something or maybe something is incorrect. Have always struggled with regex!
This is my current value for server name but it allows access to all routes.
server {
listen 80;
server_name www.otherdomain.com/users/[0-9a-z]+/features/[0-9]+/;
...
...
}

This RegExp matches the literal string up to users/ looks for any character(s) that isn't a slash, followed by /features/, followed by any character(s) that isn't a slash:
www.otherdomain.com\/users\/[^\\]+\/features\/[^\\]+

Related

Redirect old domain to new domain, including /en/

Little stuck but I'm trying to redirect an old domain name to a new domain, which is working to a point. However, we have a long list of URLs from our old website (using the old domain). Which have /en/ appended at the end.
So the issue is when I link olddomain.com/en/old-url to newdomain.com/new-url it throws a 404 as it's not picking up the '/en/'. I've compiled a long list of 301 redirects inside the Django admin, but they don't include the '/en/'. Which is where the issue is. Ideally, I want to add something to my nginx config that tells the domain to redirect even if the /en/ is included.
So Far I have something like this:
server {
listen 80;
server_name olddomain.co.uk www.olddomain.co.uk olddomain.co.uk/en/
return 301 https://www.newdomain.co.uk$request_uri;
}
server {
HTTPS
server_name olddomain.co.uk www.olddomain.co.uk olddomain.co.uk/en/;
#return 301 https://www.newdomain.co.uk$request_uri;
listen 443;
}
Thanks in advance.

Nginx $http_cookie if directive pattern matching

So on the Nginx documentation it is a bit unclear but it appears we can use Regex to match anything within the if statement
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#if
So i wanted to tweak this to make it so Nginx checks the value of any cookie.
But my following string what should be from my understanding * matching any cookie name and = matching any cookie contents.
if ($http_cookie ~* "*=*") {
return 444;
}
But i get the error "pcre_compile() failed: nothing to repeat in "" at "" in"
What i am trying to achieve is to Have nginx check the cookie like a WAF (web application firewall) to make sure it only contains A-Z uppercase a-z lowercase 0-9 + - _ . my PHP app is Joomla what does these checks too but be useful if i could perform these checks with Nginx too since it could deny the request faster.
EDIT to Show half solved issue / dilemma
set $block_cookie_exploits 0;
#If cookie name or contents does not contain the following
if ($http_cookie !~ "[a-zA-Z0-9\+\-\_]=[a-zA-Z0-9\+\-\_]") {
set $block_cookie_exploits 1;
}
#Block the client request
if ($block_cookie_exploits = 1) {
return 403;
}
New problem with above configuration is it will return 403 while no cookie is present. And if you put characters in the name or contents of the cookie like {} it does not return 403

(Nginx) Regex pattern to match everything but www

Basically, I'm trying to setup nginx with regex so that it:
Matches all subdomains for pyronexus.com & notoriouspyro.com but NOT www (www is redirected to pyronexus.com).
Gives me a variable I can use to determine what the subdomain and domain entered are (e.g. if someone enters space.pyronexus.com, I would like to have two variables $subdomain and $domain containing space and pyronexus).
So far, I have this: ~^(.*)\.(?:pyronexus|notoriouspyro)\.com$
But I just can't seem to figure out anything else! Any help would be greatly appreciated.
Edit: Perhaps it would help to show my nginx config file:
server {
server_name pyronexus.com notoriouspyro.com;
listen 127.0.0.1:80 default_server;
root /home/nginx/pyronexus.com/public;
index index.html index.php;
access_log /home/nginx/pyronexus.com/logs/access.log;
error_log /home/nginx/pyronexus.com/logs/error.log;
include php.conf;
}
server {
server_name ~^(www\.)?(.+)$;
listen 127.0.0.1:80;
return 301 $scheme://$2$request_uri;
}
The first part is the server which I need the regex for, the second part is to try and catch all domains landing on www and redirect them without www.
This is pretty easy, like #Melvyn said, you are over thinking this, you need a catch all server to handle all domains, then create a specific server for redirecting the www.
The best variable you want to know the host you are accessing is $http_host
server {
listen 80 default_server;
# here handle all subdomains, this will also match the non-www domains of
# the both domains
}
server {
listen 80;
server_name www.pyronexus.com;
return 301 http://pyronexus.com$request_uri;
}
server {
listen 80;
server_name www.notoriouspyro.com;
return 301 http://notoriouspyro.com$request_uri;
}
This pattern seems to do it:
^((?!www).+?)\.(?:pyronexus|notoriouspyro)\.com$
Courtesy of Regular expression to match a line that doesn't contain a word?
Tested here:
http://regex101.com/r/yK7oE2/1
In case you need the domain name, simply leave out the ?::
^((?!www).+?)\.(pyronexus|notoriouspyro)\.com$
Take a step back. The task is:
serve sites on pyronexus.com and notoriouspyro.com
redirect subdomains to their respective domains
redirect www subdomains to pyronexus.com
So instead of fiddling with an overly complex regular expression, make three server blocks. The second in the task list is the catch all.

nginx rewrite url only with certain subdomain

I am trying to make my nginx rewriting all the urls with certain subdomain (m.example.com) to add string: ?theme=XXX to the end of the file
In my nignx server configuration i have:
server{
server_name example.com m.example.com y.example.com
(...)
}
Now, I want to rewrite all http requests going ONLY through m.example.com to add to the end of the url ?theme=XXX
I have the following rewrite:
rewrite ^(.*)$ $1?theme=XXX? break;
but i don't know how to make rewriting only requests from m.example.com (not from all server names)

Redirecting a subdomain with a regular expression in nginx

The nginx documentation says that the server_name directive supports regular expressions. I've been banging my head against the wall trying to get even a trivial regex working.
I want http://subdomain.mydomain.com to redirect to http://mydomain.com/subdomain
Here is my code.
server {
server_name "~^subdomain\.mydomain\.com$";
rewrite ^ http://mydomain.com/subdomain;
}
Also, potentially noteworthy. Further down in the nginx config file there is a rule:
server {
server_name *.mydomain.com
...
}
What am I doing wrong?
UPDATE:
It has been suggested that I not use regex for this... to offer a little more clarity: the trivial regex was simply for purposes of troubleshooting. The real regex will look more like...
server {
server_name "~^.*(cvg|cincinnati)\.fakeairport(app)?\.(org|com)$";
rewrite ^ http://fakeairport.com/cincinnati;
}
server {
server_name "~^.*(lex|lexington)\.fakeairport(app)?\.(org|com)$";
rewrite ^ http://fakeairport.com/lexington;
}
So it would be preferable to use regex.
To answer an old question to help others
using nginx 1.1.19 you can do the following:
server {
server_name ~^(?<subdomain>\w+)\.domainA\.com$;
location / {
rewrite ^ https://$subdomain.domainB.com$request_uri permanent;
}
}
The subdomain before domainA.com is matched and stored in variable $subdomain which then can be used in the rewrite.
This rewrites url like xxx.domainA.com to xxx.domainB.com with only one server directive.
Gotta love regex with NGINX!
As I often work with multiple domain-names and I like to keep my configs as clean and rock solid as possible I almost always use regex with nginx.
In this case I've solved it with the following regex:
server {
listen 80;
server_name ~^((?<subdomain>.*)\.)(?<domain>[^.]+)\.(?<tld>[^.]+)$;
return 301 $scheme://${domain}.${tld};
}
What this does is the following: every subdomain.domain-name.tld that points to this server (ip address) is automatically redirected to domain-name.tld.
So for instance www.myexampledomain.com is redirected to myexampledomain.com.
To answer the question, what you could also do is the following:
server {
listen 80;
server_name ~^((?<subdomain>.*)\.)(?<domain>[^.]+)\.(?<tld>[^.]+)$;
return 301 $scheme://${domain}.${tld}/${subdomain};
}
Now mysubdomain.myexampledomain.com is converted into myexampledomain.com/mysubdomain.
Above regex is great as you can throw anything at it that you like and it will convert it for you.
If you read the server_name matching rules, you'll see that prefix and suffix server_names are checked before regex names, but after exact hostnames. Since *.mydomain.com matches, the regex isn't tested. The fact that it's listed earlier in the config makes no difference. Since you're just trying to match a single hostname with your regex, a simple:
server {
server_name subdomain.mydomain.com;
rewrite ^ http://mydomain.com/subdomain$request_uri?;
}
server {
server_name *.mydomain.com;
# stuff
}
will work for you.
I know everyone is saying if is evil in nginx config files, but sometimes you can't get around any other way.
server {
server_name .mydomain.com;
if ( $host ~ subdomain.mydomain.com ) {
rewrite ^(.*) http://mydomain.com/subdomain$1;
}
}
Just as a comment. If you want to redirect all subdomain levels to first subdomain level, util when you use a wildcard SSL certificate for example, you could use:
server {
listen 80;
server_name ~^(.*)\.(?<subdomain>\w+).mydomain\.com$;
return 301 https://$subdomain.mydomain.com$request_uri;
}
server {
listen 80;
server_name ~^(?<subdomain>\w+).mydomain\.com$;
return 301 https://$subdomain.mydomain.com$request_uri;
}
The first is for redirect an http multiple level subdomain to the first subdomain level in https. And the next is for redirect the first level subdomain in http to the same subdomain in https.