Whitelisting your IP address for login pages on WordPress, WooCommerce or any CMS is one of the best security methods for protection from hackers. Most ISPs use dynamic IP addressing which means your IP address will change from time to time. This poses a convenience problem since you will be denied access to site served by nginx if your IP has changed.
Dynamic DNS is a free service provided by places like Afraid DNS to keep a dynamic DNS address synchronized with your home IP address or mobile phone. This tutorial shows you how to automatically whitelist your home IP address resolved from your dynamic DNS address and add the access rule to nginx. This way you are safely whitelisted with maximum convenience so you don’t have to update the nginx virtual host manually.
Automatically Whitelist your Dynamic DNS Address for nginx Security
Installation overview
- Create the automatic script for Dynamic DNS Resolution
- Add the rules to nginx virtual host
- Schedule the script to run automatically
Create Automatic Script for Dynamic DNS Resolution
The script uses dig to resolve the IPs from the Dynamic DNS address 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.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
# nginx auto whitelist Dynamic DNS script
# Author Mike from https://guides.wp-bullet.com/
DDNS="wpbullet.chickenkiller.com"
# Populate dynamic IP if file doesn't exist
if [ ! -f /etc/nginx/conf.d/dynamicip ]; then
echo "allow $(dig x +short $DDNS);" > /etc/nginx/conf.d/dynamicip
fi
CURRENT=$(cat /etc/nginx/conf.d/dynamicip)
FRESH="allow $(dig x +short $DDNS);"
#Test if current IP is same as fresh and reload nginx if not
if [ "$CURRENT" != "$FRESH" ]; then
echo "allow $(dig x +short $DDNS);" > /etc/nginx/conf.d/dynamicip
service nginx reload
fi
Make the script executable
sudo chmod +x ~/scripts/nginx-dynamic.sh
Execute the script to do a quick test
sudo bash ~/scripts/nginx-dynamic.sh
Check the IP address contents of the dynamicip file
cat /etc/nginx/conf.d/dynamicip
You should see a line showing your IP address
allow XX.XXX.XX.XX;
Enable the nginx IP Whitelist
Open the nginx virtual host, I’m using WordPress but your virtual host may differ.
sudo nano /etc/nginx/sites-available/wordpress
Add this section so only our resolved Dynamic DNS address IP is 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/dynamicip;
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 home folder for the root user is /root
not /home/root
*/10 * * * * /bin/bash /home/username/scripts/nginx-dynamic.sh
Hit Ctrl+X, Y and Enter to Save and Exit.
Enjoy your super sweet nginx and Dynamic DNS IP whitelisting solution.
If you would like to whitelist multiple Dynamic DNS addresses then read this guide.
A future guide will also show you how to ban these bots that try to access forbidden URLs with fail2ban automatically.
Sources
Dynamic DNS Filtering nginx
Reverse DNS in bash
Check if 2 Arrays are Equal
Check file’s existence in bash
Adding cronjobs