Whitelisting your IP address for login pages on WordPress ensures that only your IP address can access the login page. It is by far one of the best security methods for preventing brute force attacks on your website.
Previously I have shown how to whitelist a single dynamic DNS address which is great security practice for your login page. However, if you have multiple admins, authors or editors you will need to whitelist multiple dynamic DNS addresses.
Dynamic DNS is a free service provided by entities like AfraidDNS to keep a dynamic DNS address synchronized with your home IP address. This tutorial shows you how to automatically whitelist multiple dynamic DNS addresses for your WordPress login page running nginx and php-fpm. You will need root access to your VPS or dedicated server to complete this tutorial.
Automatically Whitelist your Dynamic DNS Address for nginx Security
Installation overview
- Create the Dynamic DNS resolution script for multiple addresses
- Add the whitelist functionality to nginx
- Schedule the cronjob to update your IP list from Dynamic DNS addresses
Create Automatic Script for DDNS Resolution
The script uses dig to resolve the IPs from the Dynamic DNS addresses so we need dnsutils
on Debian and Ubuntu
sudo apt-get update
sudo apt-get install dnsutils -y
Create bash script
mkdir -p ~/scripts
nano ~/scripts/nginx-dynamic-multiple.sh
Paste the script and change your DDNS address below.
The script will create a file with the resolved IP each time it is run. If the fresh DNS resolution shows a different IP than what is stored in the file then nginx is reloaded.
#!/bin/bash env
# Autowhitelist multiple DDNS Addresses for nginx
# Author: Mike from https://guides.wp-bullet.com/
#define Dynamic DNS addresses here
DDNS[0]="wpbullet.chickenkiller.com"
DDNS[1]="wpbulletmobile.crabdance.com"
#create an array of the dynamic IPs
if [ ! -f /etc/nginx/conf.d/dynamicips ]; then
for DNS in "${DDNS[@]}"
do
echo "allow $(dig x +short $DNS);" >> /etc/nginx/conf.d/dynamicips
done
fi
#create current array for comparison with fresh IPs
CURRENT=($(cat /etc/nginx/conf.d/dynamicips))
#Generate fresh list
let "DNSCOUNT=${#DDNS[@]} - 1"
for i in $(eval echo "{0..$DNSCOUNT}")
do
FRESH[$i]="allow $(dig x +short ${DDNS[$i]});"
done
#compare old list and new list, create new file if there are differences
CURRENTAGG=${CURRENT[@]};
FRESHAGG=${FRESH[@]};
if [ "$CURRENTAGG" != "$FRESHAGG" ]; then
rm /etc/nginx/conf.d/dynamicips
for i in $(eval echo "{0..$DNSCOUNT}")
do
echo "${FRESH[$i]}" >> /etc/nginx/conf.d/dynamicips
done
service nginx reload
fi
Make the script executable
sudo chmod +x ~/scripts/nginx-dynamic-multiple.sh
Execute the script to do a quick test
sudo bash ~/scripts/nginx-dynamic-multiple.sh
Check the IP address contents of the dynamicip file
cat /etc/nginx/conf.d/dynamicips
You should see a line showing your IP address
allow XX.XXX.XX.XX;
allow XXX.XX.XX.XX;
Enable the nginx Whitelist
Open the nginx virtual host, in this example I’m using wordpress
. Your nginx virtual host name may be different.
sudo nano /etc/nginx/sites-available/wordpress
Add this section so only our resolved Dynamic DNS address IPs are allowed while all others are denied.
You can use this to protect any login page or location you like.
If you are not using PHP7 then change the fastcgi_pass_path
to /var/run/php/php5-fpm.sock
location = /wp-login.php {
include /etc/nginx/conf.d/dynamicips;
deny all;
include fastcgi_params;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_split_path_info ^(.+\.php)(.*)$;
}
Test nginx virtual host syntax is valid.
sudo nginx -t
If all is well reload nginx
sudo service nginx restart
Schedule the Cronjob to Keep Dynamic DNS updated
Because the script requires sudo privileges this should be done as a sudo user or root.
crontab -e
Add this line to make the script run every 10 minutes, the root user’s home folder is /root
*/10 * * * * /bin/bash /home/username/scripts/nginx-dynamic-multiple.sh
Hit Ctrl+X, Y and Enter to Save and Exit.
Enjoy your super sweet nginx and Dynamic DNS IP whitelisting solution for muliple DDNS addresses.
Any way to do this for centos?
Thank you very much for the script. Works fine for me. Regards from Germany!