LeighPudding
LeighPudding

Reputation: 61

Restricting access to files and directories on Nginx by IP

I'm trying to lock down access to WP-admin using IP restrictions on Nginx. The following seems to block wp-admin, but doesn't block wp-login.php

This is a start as it will stop anyone being able to login from any other IP, as after signing in you are redirected to wp-admin which is restricted. However, they can still get to the sign in form and in theory could still be affected by brute force attacks.

server {
    listen       80;
    server_name  website.com www.website.com dev.website.com;

    location / {
        root           /var/www/html/website.com/;
         index  index.php index.html index.htm;
         try_files $uri $uri/ /index.php?$args;
    }
     location ~ \.php$ {
         root           /var/www/html/website.com/;
         fastcgi_pass   127.0.0.1:9000;
         fastcgi_index  index.php;
         fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
         include        fastcgi_params;
     }
     location ~ ^/(wp-admin|wp-login/.php) {
         root           /var/www/html/website.com/;
         index          index.php index.html index.htm;
         allow             123.123.123.123/32;
         deny all;
     }

} 

Upvotes: 4

Views: 7073

Answers (4)

Eric
Eric

Reputation: 177

now (2018) Wordpress redirects wp-admin automaticaly to wp-login. So it's sufficient to only disallow /wp-login.php wit:

location = /wp-login.php {
allow 16.16.12.11
deny  all;
}

Just put it after the default "location `.php$" block

Upvotes: 0

DavidT
DavidT

Reputation: 2481

I know this is a little old, but your answer helped me and I have improved upon it. So for anyone else seeing this issue which I imagine is actually quite common. For me Nginx was only blocking CSS files.

I believe the issue is caused by Nginx first seeing its a php file and therefore dealing with it inside location ~ \.php$ {} before it gets to location ~ ^/(wp-admin|wp-login\.php) {}

So I did this, firstly above location ~ \.php$ {} add:

location = /wp-login.php{

    allow 12.345.6.7; #example IP address

    deny all;

    fastcgi_index index.php;
    include fastcgi_params;

}

This will block access to wp-login.php which is great, but like you said it doesnt block wp-admin so just follow up by adding the other block below location ~ \.php$ {}

location ~ ^/(wp-admin|wp-login\.php) {

    allow 12.345.6.7 #example IP address

    deny all;
}

Now, if your not coming from IP 12.345.6.7 then you can't get access to either wp-admin or wp-login.php

Upvotes: 1

LeighPudding
LeighPudding

Reputation: 61

Not a perfect solution, but I'm now using this:

server {
    listen       80;
    server_name  website.com www.website.com dev.website.com;
    root         /var/www/html/website.com/;
    error_page 403 404 500 502 503 504 = /server_error.php;
    index index.php index.html index.htm;

    location / {
         try_files $uri $uri/ /index.php?$args;
    }
     location = /wp-login.php {
         allow          123.123.123.123/32;
         deny all;
         fastcgi_pass   127.0.0.1:9000;
         fastcgi_index  index.php;
         fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
         include        fastcgi_params;
     }
     location ~ \.php$ {
         fastcgi_pass   127.0.0.1:9000;
         fastcgi_index  index.php;
         fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
         include        fastcgi_params;
     }

} 

which will keep everyone out, but doesn't mask the fact that wp-admin exists. If someone were to navigate to wp-admin, they're redirected to wp-login.php which is restricted.

Tidied up a bit too.

Upvotes: 2

Robert Lee
Robert Lee

Reputation: 1561

If you fix your context it might fix this issue. Instead of forward slash do a backslash prior to your .php

location ~ ^/(wp-admin|wp-login\.php) {
            allow 123.123.123.123/32;
            deny all;
}

Upvotes: 4

Related Questions