Nginx rewrite: how to change URL from dynamic to static - nginx

I'm configuring nginx as reverse proxy.
I need to change (rewrite?) the URLs, example: when the request (to nginx Reverse Proxy) is "http://example.com/test/?username=test1;password=passwdtest1" it will must "modified" to the main server as "http://example.com/test/?username=production;password=passwdproduction1".
Consider that in the original request the fields "username=test1;password=passwdtest1" are not always the same (they changes), instead the "modified" to the main server are always the same.
Others example to be more clear:
"/test/?username=test1;password=passwdtest1" -> "/test/?username=production;password=passwdproduction1"
"/test/?username=test1876;password=somepasswd" -> "/test/?username=production;password=passwdproduction1"
"/test/?username=somevalues;password=somepasswdvalue" -> "/test/?username=production;password=passwdproduction1"
So, independently to what are the values of "?username=somevalues;password=somepasswdvalue" it should always become "?username=production;password=passwdproduction1".
Thanks for your help!

A little late on the answer but this should work for you:
location ~* /test/? {
if ($arg_username ~ "^$|\s+") { return 404; }
if ($arg_password ~ "^$|\s+") { return 404; }
rewrite ^ /test?username=production&password=passwdproduction1? permanent;
}
The code above checks if it is within the example.com/test path. If it is it will check if the user name or the password variable are present and not empty in the query string. In case if any isn't present or is empty it will return a 404 else it will redirect you to the preferred url.
By the way, instead of the semicolon in your example urls I would use an ampersand (&).

Related

Nginx location block with if but where is the else?

Need to redirect a url with variable to another domain name. The following code works when it matches but fails when it does not match.
For example it works when the request is https://old.example.com/test/place?id=2
Fails when the request is for https://old.example.com/test/place?id=1
Need https://old.example.com/test/place?id=1 to just pass through and only catch id=2.
What is missing in the configuration? What did I miss?
location = /test/place {
if ($request_uri ~ ^/test/place\?id=2) {
return 301 https://new.example.com/test/place?id=2;
}
}
Found the solution with the help from the nginx mailing list member, Patrick. Here is the link to the conversation.
The mailing list link to the solution
The final solution is as follows.
if ( $request_uri = "/test/place?id=2" ) {
rewrite ^ https://new.example.com${uri}?${args}? last;
}

How to debug and fix nginx wrong location redirection problem?

I have an Nginx config file list below. I want to send the request to different server base on Refer.
When I send a request with URL "doamin.com/capi/a/b" and refer "a.com/a/1/test", everything is good, server "be" will get "be/a/b" request.
But if I send a request with URL "doamin.com/capi/a/b" and refer "a.com/a/0/test", server "be_demo" will get "be_demo/" request, the path "a/b" is missing.
I've tried to add "/" at the end of "be_demo", it doesn't work.
map $http_referer $be_pool {
default be;
"~a\.com\/.*\/0\/.*" be_demo;
}
server {
...
location ~ ^/capi/(.*)$ {
proxy_pass http://$be_pool/$1;
}
}
Thanks.
The numeric capture $1 is set by the last regular expression to be evaluated. In the second case, the regular expression in the map statement is evaluated after the regular expression in the location statement.
The solution is to use a named capture instead.
For example:
map $http_referer $be_pool {
default be;
"~a\.com\/.*\/0\/.*" be_demo;
}
server {
...
location ~ ^/capi/(?<myuri>.*)$ {
proxy_pass http://$be_pool/$myuri;
}
}

Read query parameter from url to do a nginx redirect

I have two source URL format and want to redirect both url based on
color variant to the destination link with the parameter appended.
Scenario1: www.example.com/pages?abc=123&color=white which should redirect to www.example.com/variant1?abc=123&color=white
Scenario2: www.example.com/pages?abc=456&color=red which should redirect to www.example.com/variant2?abc=456&color=red
I have tried with below , it works for one but not for both as its specific. Not able find the solution for both cases, as else doesnt work
location = /pages {
if ($args ~* "&color=white”) {
rewrite ^.*$ /variant1 redirect;
} }
While it is possible to do this in Nginx, it'll defeat some of the advantages that Nginx provides. If you can, it's better to do it within your application code or Lua.
If you choose to go forward with if statements, you'll want to match against individual $arg_* variables rather than $args. In particular, you'll want to use $arg_color, which will contains the color querystring value.
location = /pages {
if ($arg_color = "white") { return 301 /variant1$is_args$args; }
if ($arg_color = "red") { return 301 /variant2$is_args$args; }
# If we get to this point, there was no match. You have to keep
# this very simple and can only use directives documented as being
# compatible with `if`, or you'll get all sorts of crazy bugs and
# crashes.
return 404.
}

Return with changing number in source url

When user visits:
/profile.php?mode=viewprofile&u=[NUMBER FROM 1 TO 4000]
I want nginx to return:
/memberlist.php?mode=viewprofile&u=[SAME NUMBER]
How can I do it? Thank you for help.
The problem is that you need to match /profile.php and mode=viewprofile which is not trivial nginx. There are a number of ways to achieve it.
You could replicate the location ~\.php$ block and add the conditional redirection there:
location = /profile.php {
if ($arg_mode = viewprofile) {
return 301 /memberlist.php?$args;
}
... # add location ~\.php$ stuff here
}
Alternatively, check the $request_uri (which contains the original URI including query string), early in the server block:
if ($request_uri ~ "^/profile\.php\?mode=viewprofile&") {
return 301 /memberlist.php?$args;
}
See this caution on the use of the if statement.

Rewrite Rule in Nginx to Block a Specific URL

I would like to block a specific URL from being access and return a 444 Error.
Example:
if ( $request_uri ~ https://subdomain.domain.com/abc/xyzdirector/login.do ) {
return 444;
}
Now this works fine, the issue is if I type the following URL in my browser and change ANY of the capitalization in the sub-directories, it does not work:
Example:
https://subdomain.domain.com/ABC/xyzdirector/login.d
https://subdomain.domain.com/abc/XYZdirector/login.d
https://subdomain.domain.com/abc/xyzdirecTOR/login.d
https://subdomain.domain.com/Abc/XyzDirector/login.d
When I do this, the url gets forwarded and servered.
How do I block this?
You want a case-insensitive regex location:
location ~* ^/abc/xyzdirector/login\.do$ {
return 444;
}
If you have any other regex locations in your config, make sure you put this one above any others that may match this url.

Resources