Background
Recently, this site was under attack with attackers also trying to brute force the admin/login URLs. As you probably know, I run this site on WordPress and it now sits behind both Cloudflare and an Nginx reverse proxy. I generally only update and write on the site from home, so I wanted to ensure that no external access to /wp-admin and /wp-login pages was possible from outside the local network.
Solution
Though this could also be done in Cloudflare, I decided to do it in my reverse proxy with Nginx because I have a limit on the number of Cloudflare rules on my account and those come at a higher premium. So why not do this in Nginx?
EDIT FILE: /etc/nginx/sites-enabled/<config file>
server {
listen 443 ssl;
server_name wizworks.net;
ssl_certificate /etc/nginx/certs/wizworks.net.crt;
ssl_certificate_key /etc/nginx/certs/wizworks.net.key;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
client_max_body_size 256M;
access_log /var/log/nginx/wiz-access.log;
error_log /var/log/nginx/wiz-error.log;
location / {
#allow 10.0.0.0/8; # Uncomment and apply when placing site under maintenance
#deny all; # Uncomment and apply when placing site under maintenance
if ($remote_addr ~ "10\.*\.*\.*") {
access_log 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;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass https://web01;
}
location ~ /(wp-login|wp-admin/) {
allow 10.0.0.0/8; # Allow only local network
deny all; # Do not let the world ever see
if ($remote_addr ~ "10\.*\.*\.*") { # Do not log local access for this
access_log 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;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass https://web01;
}
# Disallow PHP In Upload Folder
location /wp-content/uploads/ {
location ~ \.php$ {
deny all;
}
if ($remote_addr ~ "10\.*\.*\.*") {
access_log 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;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass https://web01;
}
}
After making such changes, all that is left to do is: systemctl restart nginx Now, what is seen in the log is intruders getting a 403 (forbidden) response:
162.158.251.96 - - [11/Jan/2023:18:04:52 +0000] "GET /wp-login.php HTTP/1.1" 403 196 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"