Why Nginx location /dir/ does not work for /dir/ itself, but works for any /dir/file? - nginx

Please, explain me why this part in NGINX
location /a/b/ {
return 429; #error for debug
}
works only for URLs like https://example.com/a/b/something but not for https://example.com/a/b/
Adding get parameters or # anchor changes nothing.
Update: Other config parts
location /dev/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://localhost:8009/;
proxy_redirect http://$host/ /dev/;
}
# This is my current workaround
location = /dev2/editor/ {
alias /editor_html_root/;
}
# This is the place that I ask about
location /dev2/editor/ {
alias /editor_html_root/;
}
location /dev2/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://localhost:8011/;
proxy_redirect http://$host/ /dev2/;
}

Related

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

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;
}

Nginx proxy pass not rendering

I'm trying to serve some services as a subdomain but it looks like nginx is not doing it right.
I have 3 docker containers serving zabbix, webmin and mediawiki.
example.com/zabbix (works fine)
example.com/webmin (not rendering)
example.com/wiki (not rendering)
server {
listen 80;
server_name example.com;
root /var/www/html/;
location /zabbix {
proxy_pass http://192.168.0.71:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /wiki {
proxy_pass http://192.168.0.71:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /webmin {
proxy_pass http://192.168.0.71: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;
}
}
Also add in /etc/webmin/config:
webprefix=/webmin
webprefixnoredir=1
and LocalSettings.php
$wgServer = "http://example.com";
$wgArticlePath = "/wiki/$1";
$wgUsePathInfo = true;
wiki pages and webmin looks weird:
wiki screenshot
Any help will be appreciated
thanks!

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 not finding some JS files

server {
listen 80;
access_log /var/log/nginx/dashboards.access.log;
error_log /var/log/nginx/dashboards-reg.error.log;
root /usr/share/nginx/htmlresource;
location /performance-platform/landlord-reg {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://landlord-reg/dashboard/landlord-reg/pages/;
proxy_redirect http://landlord-reg/dashboard/landlord-reg/pages/ $scheme://;
}
location ~* \.(jpg|ttf|jpeg|svg|png|gif|ico|css|js|eot|woff|woff2)$ {
root /usr/share/nginx/html/dashboards/landlord-reg/pages;
proxy_pass http://landlord-reg;
}
location /performance-platform/discharges {
root /usr/share/nginx/html/dashboards/discharges/pages;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://discharges/dashboard/discharges/pages/;
proxy_redirect http://discharges/dashboard/discharges/pages/ $scheme://;
}
location ~* \.(jpg|jpeg|svg|png|gif|ico|css|js|eot|woff|woff2)$ {
root /usr/share/nginx/html/dashboards/discharges/pages;
try_files /usr/share/nginx/html/dashboard/discharges/pages $uri;
proxy_pass http://discharges;
}
}
The above is the more or less the full nginx config that is in sites-available. the upstream servers are docker containers though that shouldn't really make any difference.
This finds all but 2 of my js files.
<script src="../resource/feedconf.js"></script>
This is NOT found ^^^
where as this is
<script src="../../../assets/js/widgets/errorWidget.js"></script>
I've tried 2 different approaches to achive the same thing one for landlord and one for discharges but neither work. Ran out of ideas hence the question on here.
On a initial look of the code I understand perhaps you meant to do the following. It would be better if you shared your folder hierarchy.
server {
listen 80;
access_log /var/log/nginx/dashboards.access.log;
error_log /var/log/nginx/dashboards-reg.error.log;
root /usr/share/nginx/htmlresource;
location /performance-platform/landlord-reg {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://landlord-reg/dashboard/landlord-reg/pages/;
proxy_redirect http://landlord-reg/dashboard/landlord-reg/pages/ $scheme://;
} <-- delete this from here
location ~* \.(jpg|ttf|jpeg|svg|png|gif|ico|css|js|eot|woff|woff2)$ {
root /usr/share/nginx/html/dashboards/landlord-reg/pages;
proxy_pass http://landlord-reg;
}
} <- add this here
location /performance-platform/discharges {
root /usr/share/nginx/html/dashboards/discharges/pages;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://discharges/dashboard/discharges/pages/;
proxy_redirect http://discharges/dashboard/discharges/pages/ $scheme://;
} <-- delete this from here
location ~* \.(jpg|jpeg|svg|png|gif|ico|css|js|eot|woff|woff2)$ {
root /usr/share/nginx/html/dashboards/discharges/pages;
try_files /usr/share/nginx/html/dashboard/discharges/pages $uri;
proxy_pass http://discharges;
} <- add this here
}

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