Introduction
As you know it all begins with a story. My story is I didn’t want my DNS server directly connected to the internet. I wanted something basic and easy to use.
Say hello to dnsproxy. Its a basic and easy to use DNS proxy. Lets walk through the easy setup. I’ve even provided a script to help with setup. This setup relies on your server having a private IP address and a public IP address.
The Steps
Let’s start by updating Ubuntu. Hopefully you always update before installing new software.
> sudo apt update && sudo apt upgrade -y
Install dnsproxy.
> sudo apt install dnsproxy -y
Create /etc/dnsproxy.conf using the template below. There are place holders in ALL CAPS to highlight what you need to change.
# dnsproxy configuration file for Debian # Authoritative server # authoritative 192.168.1.2 authoritative YOUR_DNS_SERVER_IP authoritative-port 53 # It's port. Defaults to 53. authoritative-timeout 10 # Seconds to wait for answers. # Recursive resolver # recursive 192.168.1.2 recursive YOUR_DNS_SERVER_IP recursive-port 53 # It's port. Defaults to 53. recursive-timeout 90 # Seconds to wait for answers. # Local addresses and ports of dnsproxy # address and UDP port that dnsproxy use to communicate with users # listen 8.9.1.2 listen YOUR_PUBLIC_IP port 53 # address and UDP port that dnsproxy use to communicate with DNS servers. # if your DNS servers are accessed by different network interfaces, you must # use 0.0.0.0 as listen_answer. But if they are accessed by the same network # interface, just set it to the IP address that you have on that interface. listen_answer 0.0.0.0 port_answer 53003 # Security features chroot /var/spool/dnsproxy user dnsproxy # Internal networks (allowed to do recursive queries) internal 192.168.0.0/16 # Our internal network internal 172.16.0.0/12 # Another internal network internal 10.0.0.0/8 # Friendly neighbours internal 127.0.0.1 internal YOUR_PRIVATE_IP # Private network internal YOUR_PUBLIC_IP # Public IP considered as internal
Now start dnsproxy.
> sudo systemctl start dnsproxy
Test that everything is working.
Finally configure dnsproxy to start at boot.
> sudo systemctl enable dnsproxy
A Script To Make Things Easier
I’ve provided a script below that will help you set everything up.
#!/bin/bash
#
# This script sets up dnsproxy on a server.
# The server needs a private and a public network interface
#
#
# Variables
#
config_file="/etc/dnsproxy.conf"
#
# Functions
#
# Function to validate IP address
validate_ip() {
local ip=$1
local stat=1
if [[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=($ip)
IFS=$OIFS
if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]; then
stat=0
fi
fi
return $stat
}
#
# Main Script Start
#
# Check if the script is running as root
if [ "$EUID" -ne 0 ]; then
echo "This script must be run as root. Please run it with sudo or as root."
exit 1
fi
# Introduction message
echo "This script will create a dnsproxy.conf file for configuring DNS Proxy."
echo "It will also check if dnsproxy is installed, back up any existing config file, and manage the dnsproxy service."
echo ""
read -p "Do you want to continue? (y/n): " continue_script
if [[ $continue_script != "y" && $continue_script != "Y" ]]; then
echo "Exiting script."
exit 0
fi
# Check if dnsproxy is installed
if ! command -v dnsproxy &> /dev/null; then
echo "dnsproxy is not installed."
read -p "Do you want to install dnsproxy? (y/n): " install_dnsproxy
if [[ $install_dnsproxy == "y" || $install_dnsproxy == "Y" ]]; then
echo "Installing dnsproxy..."
if ! sudo apt-get update && sudo apt-get install -y dnsproxy; then
echo "Failed to install dnsproxy. Continuing without it..."
fi
else
echo "Continuing without installing dnsproxy..."
fi
fi
# Prompt for public interface IP
default_public_ip="8.9.1.2"
while true; do
read -p "Enter the public interface IP address [default: $default_public_ip]: " public_ip
public_ip=${public_ip:-$default_public_ip}
validate_ip $public_ip
if [[ $? -eq 0 ]]; then
break
else
echo "Invalid IP address. Please enter a valid IP address."
fi
done
# Prompt for private interface IP
default_private_ip="192.168.1.2"
while true; do
read -p "Enter the private interface IP address [default: $default_private_ip]: " private_ip
private_ip=${private_ip:-$default_private_ip}
validate_ip $private_ip
if [[ $? -eq 0 ]]; then
break
else
echo "Invalid IP address. Please enter a valid IP address."
fi
done
# Prompt for authoritative DNS server IP
while true; do
read -p "Enter the IP address of the authoritative DNS server: " auth_dns_ip
validate_ip $auth_dns_ip
if [[ $? -eq 0 ]]; then
break
else
echo "Invalid IP address. Please enter a valid IP address."
fi
done
# Prompt for recursive DNS server IP
while true; do
read -p "Enter the IP address of the recursive DNS server: " rec_dns_ip
validate_ip $rec_dns_ip
if [[ $? -eq 0 ]]; then
break
else
echo "Invalid IP address. Please enter a valid IP address."
fi
done
# Backup existing config file if it exists
if [ -f "$config_file" ]; then
timestamp=$(date +%Y%m%d%H%M%S)
backup_file="${config_file}.${timestamp}.bak"
cp "$config_file" "$backup_file"
echo "Existing config file backed up as $backup_file"
fi
# Create dnsproxy.conf file
cat < $config_file
# dnsproxy configuration file example for Debian
# Authoritative server
authoritative $auth_dns_ip
authoritative-port 53 # It's port. Defaults to 53.
authoritative-timeout 10 # Seconds to wait for answers.
# Recursive resolver
recursive $rec_dns_ip
recursive-port 53 # It's port. Defaults to 53.
recursive-timeout 90 # Seconds to wait for answers.
# Local addresses and ports of dnsproxy
# address and UDP port that dnsproxy use to communicate with users
listen $public_ip
port 53
# address and UDP port that dnsproxy use to communicate with DNS servers.
# if your DNS servers are accessed by different network interfaces, you must
# use 0.0.0.0 as listen_answer. But if they are accessed by the same network
# interface, just set it to the IP address that you have on that interface.
listen_answer 0.0.0.0
port_answer 53003
# Security features
chroot /var/spool/dnsproxy
user dnsproxy
# Internal networks (allowed to do recursive queries)
internal 192.168.0.0/16 # Our internal network
internal 172.16.0.0/12 # Another internal network
internal 10.0.0.0/8 # Friendly neighbours
internal 127.0.0.1
internal $private_ip # Private network
internal $public_ip # Public IP considered as internal
EOF
echo "dnsproxy.conf file created successfully."
# Check if dnsproxy is running
if pgrep dnsproxy > /dev/null; then
echo "dnsproxy is currently running. Restarting it..."
sudo systemctl restart dnsproxy
echo "dnsproxy has been restarted."
else
read -p "dnsproxy is not running. Do you want to start it? (y/n): " start_dnsproxy
if [[ $start_dnsproxy == "y" || $start_dnsproxy == "Y" ]]; then
echo "Starting dnsproxy..."
sudo systemctl start dnsproxy
sudo systemctl enable dnsproxy
echo "dnsproxy has been started and set to start on boot."
else
echo "dnsproxy was not started."
fi
fi
# Script end
echo "dnsproxy setup complete."
exit 0
You can create an empty file for pasting the script into.
> nano -w setup_dnsproxy.sh
Copy the script from the website and paste it into nano. When done exit namo and save changes.
Use the following command to run the script.
> sudo bash setup_dnsproxy.sh
Conclusion
That’s it! A quick and easy DNS proxy setup.
