I am the small business owner and runs my own web-site. I have noticed increased cracking activity against by blog. What’s the best way to block WordPress URLs such as example.com/blog/wp-login.php and example.com/blog/wp-admin/ in the nginx web-server?
Tutorial details
Difficulty level Advanced
Root privileges Yes
Requirements Linux+Nginx
Est. reading time N/A

Attacks on WordPress based sites are not new. However, recently many news outlets reported that there’s a fairly large brute force attack happening on WordPress users on multiple hosts. The attacker is brute force attacking the WordPress administrative portals (example.com/wp-admin/), using the username “admin” and trying thousands of passwords.

Nginx block access WordPress administrative portals

Edit the file nginx.conf, enter:
# vi /etc/nginx/nginx.conf
Append the following all and deny all nginx config directives in server context:

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

If your blog located in /blog/ sub-directory, try:

  location ~ ^/blog/(wp-admin|wp-login\.php) {
                deny all;

Replace with your actual static IP address. Here is a sample config file

upstream apachebackend  {
 server weight=6;
 server weight=5; 
 server weight=5; 
 server weight=5; 
 #server weight=1; 
server {
      access_log  /var/log/nginx/access.log;
      error_log   /var/log/nginx/error.log;
      index       index.html;
      listen default;
      root        /usr/share/nginx/html;
      server_name cyberciti.biz www.cyberciti.biz;
  ## PROXY - Web
      location / {
        proxy_pass  http://apachebackend;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        proxy_redirect off;
        proxy_buffering off;
        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 ~ ^/(wp-admin|wp-login\.php) {
           deny all;
           proxy_pass  http://apachebackend;
           proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
           proxy_set_header        Host            $host;
           proxy_set_header        X-Real-IP       $remote_addr;
           proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

Restart / reload the nginx web-server, enter:
# /etc/init.d/nginx reload

Test it

Visit your blog url such as http://www.cyberciti.biz/cms/wp-login.php or http://bash.cyberciti.biz/wp-admin/
Sample outputs:

Fig.01: Nginx blocking WordPress Admin Portal

How do I customize 403 error page?

See create a custom static HTTP 404 or HTTP 403 error page for more information.

Other recommendations

First, set SSL certificate on nginx. Edit the file wp-config.php and append the following directive:

define('FORCE_SSL_ADMIN', true);

Save and close the file. The FORCE_SSL_ADMIN option force WordPress to secure logins and the admin area so that both passwords and cookies are never sent in the clean over http. Use the curl command to see http headers, enter:
$ curl -I http://www.cyberciti.biz/cms/wp-admin/

HTTP/1.1 302 Found
Server: nginx
Date: Sun, 14 Apr 2013 09:01:44 GMT
Content-Type: text/html
Connection: keep-alive
Keep-Alive: timeout=60
Vary: Cookie
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
Location: https://www.cyberciti.biz/cms/wp-admin/

I also suggest that you add the following firewall rules so that SSL part is only accessible to you:

## Open port 443 to you only ##
## Allow your home/office static IP at port 443
/sbin/iptables -A INPUT -s  -m state --state NEW -p tcp --dport 443 --destination YOUR-Web-Server-SSL-IP-HERE -j ACCEPT
## Make sure  you DROP the rest of the world for for TCP port 443 ###
##/sbin/iptables -A INPUT -s 0/0  -m state --state NEW -p tcp --dport 443 --destination YOUR-Web-Server-SSL-IP-HERE -j DROP
See also

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 4 comments so far... add one

CategoryList of Unix and Linux commands
Disk space analyzersdf duf ncdu pydf
File Managementcat cp mkdir tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Modern utilitiesbat exa
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg glances gtop jobs killall kill pidof pstree pwdx time vtop
Searchingag grep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
4 comments… add one
  • Urdu Videos Feb 24, 2015 @ 14:07

    Well, Thanks for your Post. It really helps.

  • F May 5, 2015 @ 15:44

    This breaks AJAX on your site:

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

    Because admin-ajax.php – which is used for frontend pages as well – resides in /wp-admin.


  • Liviu Macsen May 11, 2015 @ 6:43


    Then whitelist your server IP address. ;)

    • Pedro Jul 14, 2015 @ 22:26

      admin-ajax.php is used by themes and plugins to send data to visitors, so you can’t just whitelist one ip or so.

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum