Task BIND
Common tasks on DNS using BIND
1. Run BIND on a server dedicated to DNS only:
#!/bin/bash
# Update the package lists for upgrades and new package installations
sudo apt-get update
# Install BIND9 and related packages
sudo apt-get install -y bind9 bind9utils bind9-doc dnsutils
# Check the status of BIND (named) service
sudo systemctl status bind9
# If not active, start the BIND service
sudo systemctl start bind9
# Enable BIND service to start on boot
sudo systemctl enable bind9
# Open the named.conf.options file in an editor
sudo nano /etc/bind/named.conf.options
# Add the following lines to the options section of the file
# replace 'your_dns_servers' with the IP addresses of your DNS servers
# forwarders {
# your_dns_servers;
# };
# Save and close the file
# Check the configuration syntax for errors
sudo named-checkconf
# If the above command doesn't return any errors, restart the BIND service
sudo systemctl restart bind9
2. Run separate authoritative and recursive DNS servers
#!/bin/bash
# Define your domain
domain="yourdomain.com"
# Define DNS data directory
dnsDataDir="/etc/bind"
# Define named.conf.options file path
optionsFile="${dnsDataDir}/named.conf.options"
# Define named.conf.local file path
localFile="${dnsDataDir}/named.conf.local"
# Configure the options file for the recursive server
echo 'options {
directory "/var/cache/bind";
recursion yes; # enables recursive queries
allow-recursion { any; }; # allows recursive queries from "any" hosts
};' > $optionsFile
# Configure the local file for the authoritative server
echo 'zone "'$domain'" {
type master;
file "/etc/bind/db.'$domain'";
};' > $localFile
# Create a basic DB file for the domain
echo '$TTL 604800
@ IN SOA ns.'$domain'. root.localhost. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
; name servers - NS records
IN NS ns.'$domain'.
; name servers - CNAME records
ns.'$domain'. IN CNAME www.'$domain'.
; 192.0.2.0/24 - CNAME records
www.'$domain'. IN CNAME ns.'$domain'.' > "${dnsDataDir}/db.${domain}"
# Restart BIND9 service
service bind9 restart
3. Prevent external access to internal data by design
// named.conf
options {
directory "/var/named";
};
view "internal" {
match-clients { 192.168.0.0/24; }; // your network
zone "example.com" {
type master;
file "internal/db.example.com"; // internal zone file
};
// additional internal zones go here
};
view "external" {
match-clients { any; };
zone "example.com" {
type master;
file "external/db.example.com"; // external zone file
};
// additional external zones go here
};
4. Have at least Two Internal DNS servers:
On dns1.example.com, your named.conf might look like this:
// named.conf on dns1.example.com
options {
directory "/var/named";
allow-transfer { dns2.example.com; }; // allow zone transfers to dns2
};
zone "example.com" {
type master;
file "db.example.com"; // zone file
};
And on dns2.example.com, your named.conf might look like this:
// named.conf on dns2.example.com
options {
directory "/var/named";
};
zone "example.com" {
type slave;
masters { dns1.example.com; }; // get zone data from dns1
file "bak.db.example.com"; // backup zone file
};
5. Point Clients to The Closest DNS Server:
# dhcpd.conf
subnet 192.168.1.0 netmask 255.255.255.0 {
option domain-name-servers 192.168.1.1; # DNS server for this subnet
# ... rest of subnet configuration ...
}
subnet 192.168.2.0 netmask 255.255.255.0 {
option domain-name-servers 192.168.2.1; # DNS server for this subnet
# ... rest of subnet configuration ...
}
6. Configure Aging and Scavenging of DNS records:
Here’s a basic example of how you might set up a BIND zone file with TTL values:
// db.example.com
$TTL 1h // default TTL is 1 hour
example.com. IN SOA ns.example.com. admin.example.com. (
2022010101 ; serial number
1d ; refresh after 1 day
2h ; retry after 2 hours
4w ; expire after 4 weeks
1h ; minimum TTL is 1 hour
)
; other DNS records go here
7. Setup PTR Records:
// named.conf
zone "1.168.192.in-addr.arpa" {
type master;
file "db.192.168.1"; // reverse zone file
};
// db.192.168.1
$TTL 1h
@ IN SOA ns.example.com. admin.example.com. (
2022010101 ; serial number
1d ; refresh after 1 day
2h ; retry after 2 hours
4w ; expire after 4 weeks
1h ; minimum TTL is 1 hour
)
@ IN NS ns.example.com.
1 IN PTR host1.example.com.
2 IN PTR host2.example.com.
8. Root Hints vs Forwarding:
Root hints are used by default in BIND, if you have a fresh installation of BIND, it will use root hints to resolve DNS queries.
#!/bin/bash
# Start the BIND service
sudo systemctl start named
# Enable the BIND service to start on boot
sudo systemctl enable named
If you want to use forwarders, you’ll need to modify the BIND configuration file (/etc/named.conf or /etc/bind/named.conf.options depending on your Linux distribution).
#!/bin/bash
# Define your forwarder DNS server
FORWARDER="8.8.8.8"
# Add the forwarder to the BIND configuration
echo "forwarders { $FORWARDER; };" | sudo tee -a /etc/named.conf
# Restart the BIND service to apply changes
sudo systemctl restart named
*9. Enable Debug Logging:
#!/bin/bash
# Define the path to the BIND log file
BIND_LOG="/var/log/named/debug.log"
# Add the logging configuration to the BIND configuration
echo "
logging {
channel debug_log {
file \"$BIND_LOG\" versions 3 size 5m;
severity dynamic;
print-time yes;
};
category default { debug_log; };
};" | sudo tee -a /etc/named.conf
# Restart the BIND service to apply changes
sudo systemctl restart named
10. Use CNAME Records for Alias (Instead of A Record):
#!/bin/bash
# Define your domain and the alias
DOMAIN="example.com."
ALIAS="www.example.com."
# Backup the original BIND zone file
sudo cp /var/named/db.$DOMAIN /var/named/db.$DOMAIN.backup
# Add the CNAME record to the BIND zone file
echo "$ALIAS IN CNAME $DOMAIN" | sudo tee -a /var/named/db.$DOMAIN
# Increment the serial number in the zone file
sudo sed -i '/Serial/ s/[0-9]\+/&+1/' /var/named/db.$DOMAIN
# Check the BIND configuration for errors
sudo named-checkconf
# Check the BIND zone file for errors
sudo named-checkzone $DOMAIN /var/named/db.$DOMAIN
# If no errors, restart the BIND service to apply changes
sudo systemctl restart named
11. Best DNS Order on Domain Controllers:
#!/bin/bash
# Define the loopback address and the address of the other domain controller
LOOPBACK_ADDRESS="127.0.0.1"
SECONDARY_DNS="192.168.1.2" # Replace with the IP address of your secondary domain controller
# Define the path to your named.conf file
NAMED_CONF="/etc/bind/named.conf.options"
# Backup the original named.conf file
cp $NAMED_CONF $NAMED_CONF.bak
# Define the new DNS settings
DNS_SETTINGS="
options {
directory \"/var/cache/bind\";
recursion yes;
allow-recursion { any; };
listen-on { $LOOPBACK_ADDRESS; $SECONDARY_DNS; };
allow-transfer { none; };
dnssec-validation auto;
auth-nxdomain no; # conform to RFC1035
listen-on-v6 { any; };
};
"
# Update the named.conf file with the new DNS settings
echo "$DNS_SETTINGS" > $NAMED_CONF
# Restart the BIND service to apply the changes
service bind9 restart
12. Domain-joined Computers Should Only Use Internal DNS Servers:
#!/bin/bash
# Define the IP address of your internal DNS server
INTERNAL_DNS="192.168.1.1"
# Backup the original resolv.conf file
sudo cp /etc/resolv.conf /etc/resolv.conf.backup
# Clear the resolv.conf file
echo "" | sudo tee /etc/resolv.conf
# Set the internal DNS server
echo "nameserver $INTERNAL_DNS" | sudo tee -a /etc/resolv.conf
13. Use Anycast and Load-balancing:
#!/bin/bash
# Define the IP address of your Anycast network
ANYCAST_IP="10.0.0.1"
# Define the network interface you want to apply the Anycast IP to
INTERFACE="eth0"
# Define the path to your BIND configuration file
BIND_CONF="/etc/bind/named.conf.options"
# Backup the original BIND configuration file
sudo cp $BIND_CONF $BIND_CONF.backup
# Clear the BIND configuration file
echo "" | sudo tee $BIND_CONF
# Set the BIND configuration for Anycast
echo "options {
listen-on { $ANYCAST_IP; };
listen-on-v6 { none; };
};" | sudo tee -a $BIND_CONF
# Restart BIND
sudo systemctl restart bind9
# Install keepalived
sudo apt-get install keepalived
# Define the path to your keepalived configuration file
KEEPALIVED_CONF="/etc/keepalived/keepalived.conf"
# Backup the original keepalived configuration file
sudo cp $KEEPALIVED_CONF $KEEPALIVED_CONF.backup
# Clear the keepalived configuration file
echo "" | sudo tee $KEEPALIVED_CONF
# Set the keepalived configuration for Anycast and Load Balancing
echo "vrrp_instance VI_1 {
state MASTER
interface $INTERFACE
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
$ANYCAST_IP
}
}" | sudo tee -a $KEEPALIVED_CONF
# Restart keepalived
sudo systemctl restart keepalived
14. Implement Unified change management:
#!/bin/bash
# Path to your zone file
ZONEFILE="/etc/bind/db.yourdomain.com"
# Function to add a DNS record
add_dns_record() {
echo "$1 IN A $2" >> $ZONEFILE
rndc reload
}
# Function to delete a DNS record
delete_dns_record() {
sed -i "/^$1/d" $ZONEFILE
rndc reload
}
# Function to list all DNS records
list_dns_records() {
cat $ZONEFILE
}
# Check command line arguments and call the appropriate function
if [ "$1" = "add" ]; then
add_dns_record $2 $3
elif [ "$1" = "delete" ]; then
delete_dns_record $2
elif [ "$1" = "list" ]; then
list_dns_records
else
echo "Usage: $0 {add|delete|list} {hostname} {ip-address}"
fi
15. Enable DNS Logging:
#!/bin/bash
# Define the path to the named.conf file
named_conf="/etc/named.conf"
# Define the logging clause
logging_clause="
logging {
channel simple_log {
file "/var/log/named/bind.log" versions 3 size 5m;
severity dynamic;
print-time yes;
print-severity yes;
print-category yes;
};
category default {
simple_log;
};
};"
# Backup the original named.conf file
cp $named_conf $named_conf.bak
# Append the logging clause to the named.conf file
echo "$logging_clause" >> $named_conf
# Restart the BIND service to apply changes
service named restart
16. Lock DNS Cache:
#!/bin/bash
# Define the path to the named.conf file
named_conf="/etc/named.conf"
# Define the options clause
options_clause="
options {
directory \"/var/named\";
dump-file \"/var/named/data/cache_dump.db\";
statistics-file \"/var/named/data/named_stats.txt\";
memstatistics-file \"/var/named/data/named_mem_stats.txt\";
allow-query { any; };
recursion yes;
allow-recursion { any; };
listen-on port 53 { any; };
allow-transfer { none; }; # This line disables zone transfers
version \"not currently available\"; # This line hides BIND version
};"
# Backup the original named.conf file
cp $named_conf $named_conf.bak
# Append the options clause to the named.conf file
echo "$options_clause" >> $named_conf
# Restart the BIND service to apply changes
service named restart
17. Filter DNS Requests to Block Malicious Domains:
#!/bin/bash
# Define the path to the named.conf file
named_conf="/etc/named.conf"
# Define the path to the file containing the list of blocked domains
blocked_domains="/etc/named/blockeddomains.conf"
# Define the options clause
options_clause="
options {
directory \"/var/named\";
response-policy { zone \"rpz\"; };
};"
# Define the rpz zone clause
rpz_zone_clause="
zone \"rpz\" {
type master;
file \"$blocked_domains\";
};"
# Backup the original named.conf file
cp $named_conf $named_conf.bak
# Append the options and rpz zone clauses to the named.conf file
echo "$options_clause" >> $named_conf
echo "$rpz_zone_clause" >> $named_conf
# Restart the BIND service to apply changes
service named restart
Keep the following format for blockeddomains.conf:
maliciousdomain1.com CNAME .
maliciousdomain2.com CNAME .
18. Firewalls should be hardened to close unneeded ports:
#!/bin/bash
# Flush all current rules from iptables
iptables -F
# Allow connections from your internal network
iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
# Allow connections from localhost
iptables -A INPUT -s 127.0.0.1 -j ACCEPT
# Allow incoming connections on ports that your DNS server needs
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
# Deny all other incoming connections
iptables -P INPUT DROP
# Allow all outgoing connections
iptables -P OUTPUT ACCEPT
# Save rules
/sbin/service iptables save
19. Disable any queries for domains you don’t own, except from your internal/local machines:
Go to named.conf
acl "trusted" {
192.168.0.0/16; # your network
127.0.0.1; # localhost
};
options {
listen-on port 53 { any; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
allow-query { trusted; }; # allow queries from "trusted" clients
recursion yes;
allow-recursion { trusted; }; # allow recursive queries from "trusted" clients
};
zone "yourdomain.com" IN {
type master;
file "yourdomain.com.zone";
allow-query { any; };
};
20. Allow queries only for your managed domains:
#!/bin/bash
# Define your domain
domain="yourdomain.com"
# Path to named.conf
named_conf="/etc/bind/named.conf.local"
# Check if domain is already in named.conf
if grep -q "\$domain" "\$named_conf"; then
echo "Domain \$domain is already configured."
else
# If not, add it
echo "
zone \"\$domain\" {
type master;
file \"/etc/bind/db.\$domain\";
};
" >> "\$named_conf"
echo "Domain \$domain has been configured."
fi
21. Require multi-factor authentication for access to DNS servers:
#!/bin/bash
# Install Google Authenticator and PAM
sudo apt-get install libpam-google-authenticator
# Run Google Authenticator
google-authenticator
# This will ask you a series of questions. Answer yes (y) to all
# Edit the PAM configuration to enable Google Authenticator
echo "auth required pam_google_authenticator.so" | sudo tee -a /etc/pam.d/sshd
# Edit the SSH configuration to enable ChallengeResponseAuthentication
sudo sed -i 's/#ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ssh/sshd_config
# Restart the SSH service to apply the changes
sudo systemctl restart sshd
22. Keep DNS servers patched and up to date:
#!/bin/bash
# Update package lists for upgrades and new package installations
sudo apt-get update
# Upgrade all the installed packages to their latest versions
sudo apt-get upgrade
# Install Livepatch to apply critical kernel patches without rebooting
sudo snap install canonical-livepatch
# Enable Livepatch (replace 'TOKEN' with your Livepatch token)
sudo canonical-livepatch enable TOKEN
# Check that Livepatch is running properly
canonical-livepatch status
23. Uninstall or disable unnecessary applications on DNS servers:
#!/bin/bash
# List all installed packages
dpkg --list
# Uninstall a package
sudo apt-get --purge remove package-name
# Disable a service
sudo systemctl disable service-name
24. Configure Access Control Lists:
#!/bin/bash
# Define the zone
zone="yourdomain.com"
# Define the ACL
acl "trusted" {
192.0.2.0/24; # Network 1
203.0.113.0/24; # Network 2
localhost;
};
# Change to the appropriate directory
cd /etc/bind
# Add the ACL to the options file
echo "acl \"trusted\" {" >> /etc/bind/named.conf.options
echo " 192.0.2.0/24; # Network 1" >> /etc/bind/named.conf.options
echo " 203.0.113.0/24; # Network 2" >> /etc/bind/named.conf.options
echo " localhost;" >> /etc/bind/named.conf.options
echo "};" >> /etc/bind/named.conf.options
# Restrict queries to the trusted ACL
echo "allow-query { trusted; };" >> /etc/bind/named.conf.options
# Restart BIND
service bind9 restart
25. Design robust server architecture to improve redundancy and capacity for resilience against failure or DDoS attacks:
options {
directory "/var/named";
recursion no;
// Enable rate limiting
rate-limit {
responses-per-second 5; // Limit the number of responses per second
window 5; // The size of the window in seconds for rate limiting
};
};
zone "example.com" in {
type master;
file "master/example.com.db";
};
26. DNSSEC Deployment:
#!/bin/bash
# Define your domain
domain="example.com"
# Change to the directory where your zone files are located
cd /etc/bind
# Generate the Key Signing Key (KSK)
dnssec-keygen -a RSASHA256 -b 2048 -n ZONE -f KSK $domain
# Generate the Zone Signing Key (ZSK)
dnssec-keygen -a RSASHA256 -b 1024 -n ZONE $domain
# Include the keys in your zone file
echo "\$INCLUDE K$domain*.key" >> db.$domain
# Sign the zone
dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) -N INCREMENT -o $domain -t db.$domain
# Reload BIND
rndc reload
# Verify the DNSSEC deployment
dig +dnssec www.$domain
27. DNSSEC Security Components Automation:
#!/bin/bash
# Define your domain
domain="example.com"
# Define the directory where your zone files are located
zone_directory="/etc/bind"
# Define the key directory
key_directory="/etc/bind/keys"
# Change to the key directory
cd $key_directory
# Generate new keys every month
if [ $(date +%m -d tomorrow) != $(date +%m) ]; then
# Generate the Key Signing Key (KSK)
dnssec-keygen -a RSASHA256 -b 2048 -n ZONE -f KSK $domain
# Generate the Zone Signing Key (ZSK)
dnssec-keygen -a RSASHA256 -b 1024 -n ZONE $domain
fi
# Change to the zone directory
cd $zone_directory
# Include the keys in your zone file
echo "\$INCLUDE $key_directory/K$domain*.key" >> db.$domain
# Sign the zone
dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) -N INCREMENT -o $domain -t db.$domain
# Reload BIND
rndc reload
# Verify the DNSSEC deployment
dig +dnssec www.$domain
28. Enable DNSSEC to ensure that DNS responses are digitally signed:
#!/bin/bash
# Edit the BIND configuration file
sudo vi /etc/named.conf
# Find and set the following directives:
# dnssec-enable yes;
# dnssec-validation yes;
# dnssec-lookaside auto;
# Save and exit the file
# Restart the BIND service to apply the changes
sudo systemctl restart named
# Test DNSSEC validation
dig . DNSKEY | grep -Ev '^ ($|;)' > root.keys
dig +sigchase +trusted-key=./root.keys . SOA | grep -i validation
29. Validate DNS Data Integrity with DNSSEC:
#!/bin/bash
# Define the zone
zone="yourdomain.com"
# Change to the appropriate directory
cd /etc/bind
# Enable DNSSEC validation
echo "dnssec-validation auto;" >> /etc/bind/named.conf.options
# Define the trusted keys for the zone
echo "trusted-keys {" >> /etc/bind/named.conf.options
echo " \"$zone\" {" >> /etc/bind/named.conf.options
echo " // Paste the public KSK for the zone here" >> /etc/bind/named.conf.options
echo " };" >> /etc/bind/named.conf.options
echo "};" >> /etc/bind/named.conf.options
# Restart BIND
service bind9 restart
Disclaimer
DISCLAIMER: The information and code provided here are intended for educational and informational purposes only. The user assumes full responsibility for the use of this information and code. The provider of this information and code makes no representations or warranties, express or implied, about the completeness, accuracy, reliability, suitability, or availability of the information and code provided. Any reliance you place on such information and any use of this code is therefore strictly at your own risk. In no event will the provider be liable for any loss or damage including without limitation, indirect or consequential loss or damage, arising out of, or in connection with, the use of this information and code.