Auto Whitelist your Dynamic DNS Address for nginx Security

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