root context with preference over a regular expression - nginx

I have read the documentation and seems it is the same as explained here enter link description here, but during my tests the root context is having precedence over the regular expression one.
Does anyone know the reason?
See my nginx.conf file and a test curl I did to validate the configuration:
http {
server {
listen 80;
root /usr/share/nginx/html;
include /etc/nginx/mime.types;
location ~ /ui(/.*) {
try_files $1 $1/ #htmlext;
}
location #htmlext {
rewrite ^/ui(/\w*)(/.*)*$ $1.html last;
}
location / {
return 301 /ui$request_uri;
}
}
}
/ # curl -v http://localhost/ui/message?msg=error.forbidden
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /ui/message?msg=error.forbidden HTTP/1.1
> Host: localhost
> User-Agent: curl/7.67.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.19.0
< Date: Thu, 09 Jul 2020 22:34:49 GMT
< Content-Type: text/html
< Content-Length: 169
< Location: http://localhost/ui/ui/message?msg=error.forbidden
< Connection: keep-alive
<
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.19.0</center>
</body>
</html>
* Connection #0 to host localhost left intact
As you can see in the curl it is redirecting my /ui/message page instead of rendering it. If I remove the location / from the configuration it seems working, if I remove the #htmlext location and add that logic in the location ~ /ui(/.*) it seems working too. Then I think the reason of my error is the #htmlext redirect.
Does anyone know why?
Thanks

Related

nginx reverse-proxy rewriting custom header (NOT URL)

I am trying to rewrite custom header information like "Author" (not part of the URL) using nginx reverse proxy.
The header information "Author:" should be rewritten from "test123" to e.g. "BASIC"
command:
admin1#nginx1:~$ curl -x 192.168.175.134:80 http://home1.MyWeb.eu:8081/home1/index.html?t=1 -H "Author: test123" -vk
TCPdump on apache:
--
GET /home1/index.html?t=1 HTTP/1.0
Host: home1.MyWeb.eu
Connection: close
User-Agent: curl/7.58.0
Accept: */*
Proxy-Connection: Keep-Alive
Author: test123
wanted result:
--
GET /home1/index.html?t=1 HTTP/1.0
Host: home1.MyWeb.eu
Connection: close
User-Agent: curl/7.58.0
Accept: */*
Proxy-Connection: Keep-Alive
Author: BASIC
You can use the proxy_set_header in your configuration. I.e.:
proxy_set_header Author "BASIC";
I made with setting variables. A little ugly but seems to work.
location / {
<...>
set $rewritten_header $http_myheader;
if ($http_myheader = "something") {
set $rewritten_header somethingelse;
}
proxy_set_header Myheader $rewritten_header;
}
The above will rewrite your header only if the condition match. Otherwise keep original value.
I think more elegant to use map in case you have a large mapping.
Hi I have solved the issue like this:
curl -x localhost:80 https://www.dummy.com -H "Authorization: test12" -vk
NGINX configuration:
server {
listen 127.0.0.2:443 ssl;
# the included file below contains ssl certificates
include snippets/www.dummy.com.conf;
root /var/www/html;
set $MyAuthorization 'Basic bGaa9zX25ljYhhWxlcl9=';
location / {
proxy_pass https://www;
proxy_set_header Host www.dummy.com;
proxy_set_header Authorization $MyAuthorization;
}
}

Change the Server Signature in NginX

I wan to Hide the Server Signature in HTTP 400 Error HTML Error page footer in Nginx. After implementing Headers-more Module. The Server Signature is changed when an HTTP Package is requested:
>> curl -I localhost
Output
HTTP/1.1 301 Moved Permanently
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://www.abshnb.com/
Server: Abshnb
But the HTTP 400 Error HTML Page is still returning the error page with "nginx" footer.
Here is a dead simple example of error_page directive where error response is generated by nginx itself:
server {
listen 8888;
server_tokens off;
...
error_page 400 502 #error;
location #error {
default_type text/html;
return 200 '<center><h1>$status</h1></center>';
}
location = /error400 {
return 400;
}
location = /error502 {
return 502;
}
Custom error handler:
$ http :8888/error400
HTTP/1.1 400 Bad Request
Connection: close
Content-Length: 29
Content-Type: text/html
Date: Sat, 08 Feb 2020 11:43:05 GMT
Server: nginx
<center><h1>400</h1></center>
Default error handler:
$ http :8888/nonexistent
HTTP/1.1 404 Not Found
Connection: keep-alive
Content-Length: 162
Content-Type: text/html
Date: Sat, 08 Feb 2020 11:47:19 GMT
Server: nginx
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

Nginx "auth_request" like option for rate limiting

In Nginx I want to send a pre-request to another endpoint which checks for rate limiting violations. Basically exactly what auth_request does, but where auth_request only accepts authentication status codes (200, 401, 403), I want it to only allow rate limiting codes (200 or 429).
Is there a more general version of auth_request which could be used for this?
For now we're using auth_request, but the downside is it turns 429 status codes into 500s.
Thanks!
Below config works for me and returns a 429 instead of 500
events {
worker_connections 1024;
}
http {
server {
listen 80;
location /api {
auth_request /rate_limit;
error_page 500 = #rate_limit_error;
echo "You were allowed to access the API";
}
location #rate_limit_error {
return 429 "Limit has been exceeded\n";
}
location = /rate_limit {
internal;
return 400 "Access is not allowed";
}
}
}
The test shows the correct response
$ curl -v localhost/api?count=2
* Trying ::1...
* Connected to localhost (::1) port 80 (#0)
> GET /api?count=2 HTTP/1.1
> Host: localhost
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 429
< Server: openresty/1.11.2.2
< Date: Sat, 30 Sep 2017 18:50:56 GMT
< Content-Type: text/plain
< Content-Length: 24
< Connection: close
<
Limit has been exceeded
* Closing connection 0
If you don't want to return a message or something else. You can also use error_page 500 = 429;

How to write nginx rewrite rule for replacing query param in query string

folks!
We have following http request:
http://185.xxx.x.xx/auth/realms/master-realm/protocol/openid-connect/auth?response_type=code&client_id=regportal&redirect_uri=http%3A%2F%2Fsome.domain.com%2Fregportal%2Fsso%2Flogin&state=a49a02d5-f873-453f-9148-61793f11ecf3&login=true&scope=openid
We want to replace redirect_uri from "some.domain.com" to "other.domain.com".
How to do it?
Thanks
You need to do it like this
location /auth/realms/master-realm/protocol/openid-connect/auth {
if ($args ~* "(.*)(some\.domain\.com)(.*)") {
set $args "$1other.domain.com$3";
return 301 $scheme://$host$uri$args;
}
}
Test:
curl -I "vm/auth/realms/master-realm/protocol/openid-connect/auth?response_type=code&client_id=regportal&redirect_uri=http%3A%2F%2Fsome.domain.com%2Fregportal%2Fsso%2Flogin&state=a49a02d5-f873-453f-9148-61793f11ecf3&login=true&scope=openid"
HTTP/1.1 301 Moved Permanently
Server: openresty/1.11.2.2
Date: Fri, 15 Sep 2017 06:01:51 GMT
Content-Type: text/html
Content-Length: 191
Connection: keep-alive
Location: http://vm/auth/realms/master-realm/protocol/openid-connect/authresponse_type=code&client_id=regportal&redirect_uri=http%3A%2F%2Fother.domain.com%2Fregportal%2Fsso%2Flogin&state=a49a02d5-f873-453f-9148-61793f11ecf3&login=true&scope=openid

nginx: variable expansion inside split_clients not working?

i have the following config:
map $host $variant_a {
default 'a';
}
map $host $variant_b {
default 'b';
}
map $host $variant_c {
default 'c';
}
map $host $variant_d {
default 'd';
}
map $host $variant_default {
default 'default';
}
# a/b testing
split_clients "abtest${remote_addr}${http_user_agent}${date_gmt}" $variant_chosen {
20% $variant_a;
20% $variant_b;
20% $variant_c;
20% $variant_d;
20% $variant_default;
}
server {
# defaults test independent
listen 80;
server_name _;
root /home/vagrant/www;
index index.html;
error_page 404 = 404.html;
error_page 403 = 404.html;
location / {
echo a=$variant_a,variant_chosen=$variant_chosen
}
}
when i execute a query against the server:
curl -i http://192.168.33.10/
i can see that the variables inside the 'split_clients' get never expanded.
sample output:
vagrant#precise32:~/www$ curl -i http://192.168.33.10/
HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Mon, 04 May 2015 15:46:17 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive
a=a,variant_chosen=$variant_default
anybody any idea why the variables are not expanded?
any help highly appreciated
cheers
marcel

Resources