Nginx reverse proxy to server that's specified in the path - nginx

I have an nginx reverse proxy location setup like so:
location /192.168.0.10 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.10/;
}
location /192.168.0.11 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.11/;
}
location /192.168.0.12 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.12/;
}
location /192.168.0.13 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.13/;
}
location /192.168.0.14 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.14/;
}
location /192.168.0.15 {.....
This structure repeats about 96 times so that we can have a reverse proxy to each one. Is there a way to simplify it so that there is only one structure and that the IP in the location's path magically just appears in the proxy_pass directive? Because this is becoming a pain to manage as we add and remove servers.

I think the following regex matching location should work:
location ~ ^/(?<proxy>192\.168\.0\.(?:10|11|12|13|14|15|...))(?:/(?<path>.*))?$ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://$proxy/$path;
}
You can additionally optimize that non-capturing group (?:10|11|12|13|14|15|...), for example to match any number from 10 to 105 it can be written as (?:10[0-5]|[1-9]\d).
Update 1
As requested by OP, PCRE regex for any IPv4 address with strict checking (for matching only correct IPv4 addresses from 0.0.0.0 to 255.255.255.255, adapted from this answer) can be written as
location ~ "^/(?<proxy>(?:25[0-5]|2[0-4]\d|[01]?\d?\d\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))(?:/(?<path>.*))?$" {
...
}
Due to the curly brackets usage regex pattern must be enclosed in double quotes.
Update 2
Previous solutions won't preserve the request query string, more correct solution to keep all the request query arguments is to use proxy_pass http://$proxy/$path$is_args$args directive:
location ~ "^/(?<proxy>(?:25[0-5]|2[0-4]\d|[01]?\d?\d\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))(?:/(?<path>.*))?$" {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://$proxy/$path$is_args$args;
}

Related

Location wildcard for nginx block

Very new to nginx config, i'm trying to configure a location block to use a wildcard after "/dev/"
Example of what works below:
location /agent-d-ccp/dev/getcalltypelist/GEQ {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header x-apigw-api-id XXXX;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
set $backend XXXX;
proxy_pass $backend/dev/getcalltypelist/GEQ;
}
But I need a wildcard for anything after "/dev" because "getcalltypelist" will change and so will "GEQ"
location ~* ^/agent-d-ccp/dev/(.*) {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header x-apigw-api-id XXXX;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
set $backend XXXX;
proxy_pass $backend/dev/$is_args$args;
}
I've tried the above but just doesn't seem to work, does ^/agent-d-ccp/dev/(.*)
need to be "^/agent-d-ccp/dev/(.*)/(*.)" for example ?
Thank you to all who respond.
To share for anyone else having the same issue, see answer below:
location ~* ^/agent-d-ccp/(.*) {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header x-apigw-api-id XXXX;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
set $backend XXXXX;
proxy_pass $backend/$1$is_args$args;
}

Nginx - Reverse proxy all requests starting with a keyword

I want to redirect all requests starting with "mydomain/_dash" to "mydomain:8050/_dash" so that "mydomain/_dash-component-suites/" redirects to "mydomain:8050/_dash-component-suites/". I have added the following directive but it doesn't work. Plus, I also want to maintain the headers of each request.
location /_dash(.*)$ {
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
client_max_body_size 0;
proxy_pass http://analytics:8050/_dash(*);
}
You need to use regular expressions:
location ~ /_dash(.*)$ {
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
client_max_body_size 0;
proxy_pass http://analytics:8050/_dash$1;
}

Consolidate NGINX config for my VueJS and Flask App

I'm working on deploying my VueJS and Flask app. After watching few tutorials I came to the NginX configuration below. It works, but it's getting long. Is there a way I can consolidate the location endpoints to something like this location /*?
I've tried - location /*, location *.
server {
listen $PORT;
root /usr/share/nginx/html;
index index.html index.html;
location / {
try_files $uri /index.html =404;
}
location /ping {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_redirect default;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location /query_usdot {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_redirect default;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location /subscribe {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_redirect default;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
As nginx documentation states:
location can either be defined by a prefix string, or by a regular expression.
To join this three location blocks you can use this regexp:
location ~ ^/(?:ping|query_usdot|subscribe) {
...
}

Config nginx multiple locations case insensitive

I have my nginx as a reverse proxy set up like this:
server {
listen 80;
server_name mydomain.com anotherdomain.es 20.18.4.140;
location ^~ /service/ {
proxy_pass http://20.18.4.146/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ^~ /vm2/ {
proxy_pass http://20.18.4.146/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ^~ /vm3/ {
proxy_pass http://20.18.4.142:6001/;
#proxy_set_header Host $host;
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-Forwarded-Proto $scheme;
} location / {
proxy_pass http://20.18.4.148/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
} }
server {
listen 443 ssl;
server_name mydomain.com anotherdomain.es 20.18.4.140;
fastcgi_param HTTPS on;
include /etc/nginx/include/ssl;
location ^~ /service/ {
proxy_pass https://20.18.4.146/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ^~ /vm2/ {
proxy_pass https://20.18.4.146/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ^~ /vm3/ {
proxy_pass https://20.18.4.142:6000/;
#proxy_set_header Host $host;
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
proxy_pass https://20.18.4.148/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Now I'm accessing it correctly this way:
mydomain.com/service/... anotherdomain.es/service/...
mydomain.com/vm2/... anotherdomain.es/vm2/...
mydomain.com/vm3/... anotherdomain.es/vm3/...
mydomain.com/... anotherdomain.es/...
Redirects all traffic from a location to the appropriate server. The rest of the url (including the parameters) are unproblematic and have upper and lower case.
But I would need the locations to be case insensitive. And to be able to access it like that (or any other combination):
mydomain.com/Service/... anotherdomain.es/SERVICE/...
mydomain.com/VM2/... anotherdomain.es/Vm2/...
I don't want to repeat the locations or repeat the configuration of each one. I would like to do it better and more efficiently.
I have tried with regular Expressions but checking the syntax gives me errors and it doesn't work. For example this one:
~* ^/(vm2|Vm2|VM2)/$
~* ^/vm2/
~* /(<vm2>/g)
~* /app1/(.*)
...
Error:
nginx: [emerg] "proxy_pass" cannot have URI part in location given by
regular expression, or inside named location, or inside "if"
statement, or inside "limit_except" block in
/etc/nginx/sites-enabled/my-sites:4 nginx: configuration file
/etc/nginx/nginx.conf test failed
And also it could be the case: mydomain.com/vm2/service/15 (being regular expressions it would be 2)
I've looked and tried a lot but I don't see anything that works for me. Any ideas? Thanks.
With Richard Smith's clue , what I'd seen and new readings (nginx-case-insensitive-location) I've left it at that:
location ~* /service(?<stuff>.*)$ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
rewrite ^ /$stuff break;
proxy_pass http://20.18.4.146;
}
...
...ssl
...
location ~* /service(?<stuff>.*)$ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
rewrite ^ /$stuff break;
proxy_pass https://20.18.4.146;
}
...
location / {
proxy_pass https://20.18.4.148/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
And now "service" or "vmX" with Case Insentive, meaning Service or
SERVICE or serVice or VM2.
I hope it helps other nginx inexperienced people like me.

Nginx proxy_pass cannot load asset

I'm configuring nginx with this config:
location /test {
proxy_pass http://127.0.0.1:10000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
It works, but without all assets. I inspect element, the assets redirect to http://127.0.0.1:10000 (absolutely 404), where it should be http://127.0.0.1:10000/test/asset.css.
Need advice :)
PS: My server is using angular2 (npm start)
May the force be with you:
location / {
proxy_pass http://127.0.0.1:10000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
root /root/of/your/public/assets;
access_log off;
expires max;
}

Resources