Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx Block/Deny Access to multiple locations regex

I am using Nginx as a reverse proxy for my Apache instillation and as a security feature it blocks access to phpmyadmin, webalizer etc for everyone except localhost but using nginx it makes Apache think it is localhost so it displays it publicly for everyone.

<LocationMatch "^/(?i:(?:xampp|security|phpmyadmin|licenses|webalizer|server-status|server-info))">
    Order deny,allow
    Deny from all
    Allow from ::1 127.0.0.0/8 \
        fc00::/7 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 \
        fe80::/10 169.254.0.0/16

    ErrorDocument 403 /
</LocationMatch>

I need to turn the above rules pattern matching regex into the following.

location /phpmyadmin {
        proxy_pass         htt://127.0.0.1:8080/phpmyadmin;
        allow 127.0.0.1;
        deny all;
    }

Much appreciated for help from anyone who is familiar with regex in Nginx.

The following method works but breaks normal site urls that would be search engine friendly such as domain.com/forums/server-info

location ~ /(xampp|security|phpmyadmin|licenses|webalizer|server-status|server-info) {
    deny  all;
}
like image 353
C0nw0nk Avatar asked Mar 16 '13 15:03

C0nw0nk


2 Answers

As the apache regex has '^', we can put '^' to force matching from the start of the path too.

location ~ ^/(xampp|security|phpmyadmin|licenses|webalizer|server-status|server-info) {
  proxy_pass         http://127.0.0.1:8080$request_uri;
  .... allow/deny directives come here
}

[EDIT] The matched string inside the brackets is stored in $1. So you may try

http://127.0.0.1:8080/$1

if that's what you want. However, my understanding is that you want to pass the entire uri path to the apache server. In that case, it's simpler to use nginx variable $request_uri.

like image 183
Chuan Ma Avatar answered Nov 11 '22 07:11

Chuan Ma


Looks like you have it pretty much. For the security, nginx will read from top to bottom, so leave deny all for the end:

location /(xampp|security|phpmyadmin|licenses|webalizer|server-status|server-info) {
  allow from ::1;
  allow from fc00::/7;
  allow from fe80::/10;
  allow 127.0.0.0/8;
  allow 10.0.0.0/8;
  allow 172.16.0.0/12;
  allow 192.168.0.0/16;
  allow 169.254.0.0/16;
  deny all;
}

Note that this will apply to any url like /phpmyadmin, etc. Including /someplaceelse/phpmyadmin. You can prepend a ^ to this match for only http://host/phpmyadmin matches. Although from the sound of it you may have to split this into multiple location directives in this case.

I'm not sure what you mean by search engine friendly. If you want server-info to be accessible, simply remove it from the regex | cases.

For the phpmyadmin proxy:

location ^/phpmyadmin {
    proxy_pass    http://127.0.0.1:8080; 
}

nginx will take everything in the location match and append it to http://127.0.0.1:8080

You can modify this behavior using ~, for instance. http://wiki.nginx.org/HttpCoreModule#location

like image 33
Evan Cordeiro Avatar answered Nov 11 '22 08:11

Evan Cordeiro