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.