3

We just started running nginx a few weeks ago and need to block access to certain files/location. e.g.:

/wordpress/wp-admin/
/wp-admin/
/test/wp-admin/
/hudson/login
/phpmyadmin/index.php
/mysql/index.php
/myadmin/index.php
/wp-cron.php
/xmlrpc.php

In general we would like to block any file request except /index.php and also any location such as /wp-admin/, /test/wp-admin/, /wordpress/wp-admin/, etc. These files/locations don't exist, so anybody accessing them is trying to hack/abuse the system.

In Apache we would use .htaccess to block such. How do block in Nginx?

Current Conf

server {
    listen       80;
    root /home/public_html;
    index index.php;
    server_name  domain.com;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    } 


    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
    }
}
  • 1
    Read about location. From a quick look, this article might shed some light, too. – Satō Katsura May 6 '17 at 6:26
  • @SatoKatsura: That comment could well be expanded in a proper answer. – Julie Pelletier May 6 '17 at 6:40
  • @SatoKatsura do you think a customised location is necessary here? if the URI's don't exist, nginx will, by default, send a response with the 404 code and HTML with <h1>404 not found</h1> etc, I would have thought thats as good as you can do? – the_velour_fog May 6 '17 at 8:05
  • @the_velour_fog we use Laravel framework and have only one php file. So, externally nginx doesn't have a way of telling whether a request exists. We need to tell it explicitly what to ignore. Have expanded the question. – Mugoma J. Okomba May 6 '17 at 11:29
  • ok I see what you mean. yes laravel has that huge app/routes.phpfile so the app has to determine if the url is valid. yes its possible to write a location block that matches those wordpress urls and get nginx to check those first and then send all remaining requests to laravel. – the_velour_fog May 6 '17 at 11:37
6

The config below should cause nginx to respond to the "abuse" URLs with a 404 status and a basic nginx, 404 page; all other URLs ending in .php should be proxy passed to the application/php engine as usual. I've tested on some of the patterns, but you should test all the patterns that you want to be managed by nginx and not the application. I thought this config may have had be some issues on URLs like /phpmyadmin/index.php where the \.php regex of the proxy pass location had higher priority, but my testing shows it works, for me at least.
Also, yes it would be nicer if there were not so many location blocks, but I can't think of how you would achieve that.

server {
    listen       80;
    root /home/public_html;
    index index.php;
    server_name  domain.com;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    } 


    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
    }

    # The ^~ means if this prefix pattern matches use this location block
    # and don't continue onto the regex location blocks - which would load
    # the laravel application
    location ^~ /wordpress/wp-admin/ {
        return 404;
    }
    location ^~ /wp-admin/ {
        return 404;
    }
    location ^~ /test/wp-admin/ {
        return 404;
    }
    location ^~ /hudson/login {
        return 404;
    }
    location ^~ /phpmyadmin/index.php {
        return 404;
    }
    location ^~ /mysql/index.php {
        return 404;
    }
    location ^~ /myadmin/index.php {
        return 404;
    }
    location ^~ /wp-cron.php {
        return 404;
    }
    location ^~ /xmlrpc.php {
        return 404;
    }

} 
  • this looks fine. Instead of many location entries, e.g. many /wp-admin/, is it possible to use a wild card, something like location ^~ *wp-admin*. This would handle even unknown cases since hackers always try to vary URLs. We could even go more wide and use location ^~ *admin*. 2ndly, is the match case insensitive, i.e. will location ^~ /wp-admin/ also match location ^~ /wp-Admin/? – Mugoma J. Okomba May 6 '17 at 18:42
  • You can go through the below article for detailed answer of case insensitive question & related syntax. digitalocean.com/community/tutorials/… – NameNotFoundException Aug 31 '17 at 11:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.