Auto Whitelist Multiple Dynamic DNS Addresses for nginx Security

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.

2 thoughts on “Auto Whitelist Multiple Dynamic DNS Addresses for nginx Security”

Comments are closed.