+
windows
neo4j
hapi
+
phpstorm
apex
fiber
#
|>
mongo
+
+
+
+
toml
+
โˆฉ
0x
surrealdb
+
!!
+
+
zorin
+
gentoo
+
+
+
scala
+
โˆช
couchdb
dynamo
+
emacs
rider
fastapi
+
+
+
prometheus
+
vite
+
+
cosmos
marko
+
vb
graphdb
linux
ฮป
alpine
+
prettier
vim
raspbian
objc
eslint
+
redis
tcl
gradle
&
+
termux
+
ts
+
+
+
+
+
+
grafana
preact
::
+
+
+
!==
jasmine
+
+
+
+=
bun
+
Back to Blog
๐ŸŒ AlmaLinux DNS Server Configuration: Complete BIND & Named Guide
AlmaLinux DNS Server BIND

๐ŸŒ AlmaLinux DNS Server Configuration: Complete BIND & Named Guide

Published Sep 17, 2025

Master DNS server configuration on AlmaLinux! Learn BIND9, DNS zones, security, caching, and performance optimization. Complete beginner-friendly guide with real examples and best practices.

44 min read
0 views
Table of Contents

๐ŸŒ AlmaLinux DNS Server Configuration: Complete BIND & Named Guide

Welcome to the fascinating world of DNS server configuration on AlmaLinux! ๐ŸŽ‰ Think of DNS servers as the internetโ€™s phone book - they translate human-friendly domain names into the IP addresses that computers need to communicate! Whether youโ€™re setting up internal name resolution for your network, hosting your own domains, or learning about the backbone of internet infrastructure, mastering DNS configuration is absolutely essential! ๐Ÿ“ž

DNS servers might seem mysterious at first, but theyโ€™re actually quite logical and incredibly important! ๐Ÿ’ช From resolving your first domain name to implementing advanced security features and load balancing, weโ€™ll learn everything step by step. Get ready to become a DNS expert and take control of domain name resolution! โœจ

๐Ÿค” Why is DNS Server Configuration Important?

DNS server configuration is fundamental to network operations! Hereโ€™s why you should master it:

  • ๐Ÿ  Internal Name Resolution: Provide fast, local DNS resolution for your network
  • ๐ŸŽฏ Control and Performance: Optimize DNS queries and reduce external dependencies
  • ๐Ÿ›ก๏ธ Security Enhancement: Implement DNS security features and filtering
  • ๐Ÿ’ฐ Cost Reduction: Reduce bandwidth usage with local DNS caching
  • ๐ŸŒ Custom Domains: Host your own domains and subdomains
  • ๐Ÿ“Š Network Monitoring: Monitor and analyze DNS traffic patterns
  • ๐Ÿ”„ High Availability: Implement redundant DNS infrastructure
  • ๐ŸŽญ Split DNS: Provide different answers for internal vs external queries

๐ŸŽฏ What You Need

Before we start configuring DNS servers, make sure you have:

โœ… AlmaLinux 8 or 9 installed and running โœ… Static IP address for the DNS server โœ… Root or sudo access to install and configure DNS software โœ… Domain name for testing (optional but helpful) โœ… Basic networking knowledge (IP addresses, subnets) โœ… Understanding of DNS concepts (zones, records, hierarchy) โœ… Firewall configuration access (weโ€™ll open DNS ports)

๐Ÿ“ Understanding DNS Concepts

Letโ€™s start by understanding how DNS works! ๐ŸŽ“

DNS Hierarchy and Components

# DNS hierarchy explanation:
echo "DNS Hierarchy:"
echo "Root (.) โ†’ Top-Level Domain (.com) โ†’ Second-Level (example.com) โ†’ Subdomain (www.example.com)"

echo ""
echo "DNS Record Types:"
echo "A - Maps domain to IPv4 address"
echo "AAAA - Maps domain to IPv6 address"
echo "CNAME - Canonical name (alias)"
echo "MX - Mail exchange server"
echo "NS - Name server"
echo "PTR - Reverse DNS lookup"
echo "SOA - Start of Authority"
echo "TXT - Text records"

# Check current DNS configuration
cat /etc/resolv.conf
# Output: Shows current DNS servers

# Test DNS resolution
nslookup google.com
dig google.com
# Output: Shows DNS query results

DNS Server Planning

# Plan DNS server configuration
echo "DNS Server Planning:"
echo "- Primary DNS: 192.168.1.10 (master)"
echo "- Secondary DNS: 192.168.1.11 (slave)"
echo "- Zone files location: /var/named/"
echo "- Configuration: /etc/named.conf"
echo "- Logs: /var/log/named/"

# Check if DNS is already running
sudo netstat -tlnp | grep :53
ps aux | grep named
# Output: Shows if DNS services are running

# Check available system resources
free -h
df -h /var
# Output: Shows memory and disk space

๐Ÿ”ง Installing BIND DNS Server

Basic BIND Installation

# Install BIND DNS server
sudo dnf install bind bind-utils -y
# Output: Installs BIND DNS server and utilities

# Start and enable DNS service
sudo systemctl start named
sudo systemctl enable named
# Output: Starts DNS server and enables it at boot

# Check DNS service status
sudo systemctl status named
# Output: Shows DNS service status

# Configure firewall for DNS
sudo firewall-cmd --permanent --add-service=dns
sudo firewall-cmd --reload
# Output: Opens DNS port (53)

# Test DNS server installation
dig @localhost google.com
# Output: Tests DNS resolution through local server

# Check BIND version
named -v
# Output: Shows BIND version information

Basic BIND Configuration

# Backup original configuration
sudo cp /etc/named.conf /etc/named.conf.backup

# Edit main BIND configuration
sudo nano /etc/named.conf

# Basic BIND configuration:
//
// named.conf
//
// Configuration for BIND DNS server
//

options {
    listen-on port 53 { 127.0.0.1; 192.168.1.10; };
    listen-on-v6 port 53 { ::1; };
    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";
    secroots-file "/var/named/data/named.secroots";
    recursing-file "/var/named/data/named.recursing";
    allow-query { localhost; 192.168.1.0/24; };
    allow-transfer { none; };

    // Path to ISC DLV key
    bindkeys-file "/etc/named.root.key";
    managed-keys-directory "/var/named/dynamic";
    pid-file "/run/named/named.pid";
    session-keyfile "/run/named/session.key";

    // Security settings
    version "DNS Server";
    hostname none;
    server-id none;
};

logging {
    channel default_debug {
        file "data/named.run";
        severity dynamic;
    };

    channel query_log {
        file "/var/log/named/query.log" versions 3 size 100m;
        severity info;
        print-time yes;
        print-category yes;
    };

    category queries { query_log; };
};

zone "." IN {
    type hint;
    file "named.ca";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

# Create log directory
sudo mkdir -p /var/log/named
sudo chown named:named /var/log/named

# Test BIND configuration
sudo named-checkconf
# Output: Should show no errors

# Restart DNS service
sudo systemctl restart named
# Output: Restarts DNS with new configuration

๐ŸŒŸ Creating DNS Zones

Forward DNS Zone Configuration

# Create forward zone for example.com
sudo nano /etc/named.conf

# Add zone configuration:
zone "example.com" IN {
    type master;
    file "example.com.zone";
    allow-update { none; };
    allow-transfer { 192.168.1.11; };
};

# Create zone file
sudo nano /var/named/example.com.zone

# Add zone content:
$TTL 86400
@   IN  SOA ns1.example.com. admin.example.com. (
        2025091701  ; Serial number (YYYYMMDDNN)
        3600        ; Refresh (1 hour)
        1800        ; Retry (30 minutes)
        1209600     ; Expire (2 weeks)
        86400       ; Minimum TTL (1 day)
)

; Name servers
@       IN  NS      ns1.example.com.
@       IN  NS      ns2.example.com.

; A records
ns1     IN  A       192.168.1.10
ns2     IN  A       192.168.1.11
@       IN  A       192.168.1.20
www     IN  A       192.168.1.20
mail    IN  A       192.168.1.21
ftp     IN  A       192.168.1.22

; CNAME records
web     IN  CNAME   www.example.com.
webmail IN  CNAME   mail.example.com.

; MX records
@       IN  MX  10  mail.example.com.

; TXT records
@       IN  TXT     "v=spf1 mx ~all"
_dmarc  IN  TXT     "v=DMARC1; p=quarantine; rua=mailto:[email protected]"

# Set proper ownership and permissions
sudo chown root:named /var/named/example.com.zone
sudo chmod 640 /var/named/example.com.zone

# Check zone file syntax
sudo named-checkzone example.com /var/named/example.com.zone
# Output: Should show "OK"

# Reload DNS configuration
sudo systemctl reload named
# Output: Reloads DNS with new zone

Reverse DNS Zone Configuration

# Create reverse zone for 192.168.1.0/24
sudo nano /etc/named.conf

# Add reverse zone configuration:
zone "1.168.192.in-addr.arpa" IN {
    type master;
    file "192.168.1.rev";
    allow-update { none; };
    allow-transfer { 192.168.1.11; };
};

# Create reverse zone file
sudo nano /var/named/192.168.1.rev

# Add reverse zone content:
$TTL 86400
@   IN  SOA ns1.example.com. admin.example.com. (
        2025091701  ; Serial number
        3600        ; Refresh
        1800        ; Retry
        1209600     ; Expire
        86400       ; Minimum TTL
)

; Name servers
@       IN  NS      ns1.example.com.
@       IN  NS      ns2.example.com.

; PTR records
10      IN  PTR     ns1.example.com.
11      IN  PTR     ns2.example.com.
20      IN  PTR     www.example.com.
21      IN  PTR     mail.example.com.
22      IN  PTR     ftp.example.com.

# Set ownership and permissions
sudo chown root:named /var/named/192.168.1.rev
sudo chmod 640 /var/named/192.168.1.rev

# Check reverse zone syntax
sudo named-checkzone 1.168.192.in-addr.arpa /var/named/192.168.1.rev
# Output: Should show "OK"

# Reload DNS configuration
sudo systemctl reload named
# Output: Reloads DNS with reverse zone

# Test forward and reverse DNS
dig @localhost example.com
dig @localhost -x 192.168.1.20
# Output: Tests forward and reverse resolution

โœ… Advanced DNS Features

DNS Security (DNSSEC)

# Install DNSSEC tools
sudo dnf install bind-dnssec-utils -y
# Output: Installs DNSSEC utilities

# Generate DNSSEC keys for zone
cd /var/named
sudo dnssec-keygen -a RSASHA256 -b 2048 -n ZONE example.com
sudo dnssec-keygen -a RSASHA256 -b 2048 -n ZONE -f KSK example.com
# Output: Generates zone signing keys

# Sign the zone
sudo dnssec-signzone -A -3 $(head -c 1000 /dev/urandom | sha1sum | cut -b 1-16) \
    -N INCREMENT -o example.com -t example.com.zone
# Output: Creates signed zone file

# Update named.conf for signed zone
sudo nano /etc/named.conf

# Update zone configuration:
zone "example.com" IN {
    type master;
    file "example.com.zone.signed";
    allow-update { none; };
    allow-transfer { 192.168.1.11; };
    key-directory "/var/named";
    auto-dnssec maintain;
    inline-signing yes;
};

# Set proper permissions for keys
sudo chown named:named /var/named/K*
sudo chmod 640 /var/named/K*

# Restart BIND to load signed zone
sudo systemctl restart named

# Verify DNSSEC
dig @localhost example.com DNSKEY
dig @localhost example.com DS
# Output: Shows DNSSEC records

DNS Views and Split DNS

# Configure split DNS with views
sudo nano /etc/named.conf

# Add view configuration:
acl "internal" {
    192.168.1.0/24;
    localhost;
    localnets;
};

acl "external" {
    !192.168.1.0/24;
    any;
};

view "internal" {
    match-clients { "internal"; };
    recursion yes;

    zone "example.com" IN {
        type master;
        file "example.com.internal";
    };

    zone "1.168.192.in-addr.arpa" IN {
        type master;
        file "192.168.1.rev";
    };

    include "/etc/named.rfc1912.zones";
};

view "external" {
    match-clients { "external"; };
    recursion no;

    zone "example.com" IN {
        type master;
        file "example.com.external";
    };
};

# Create internal zone file
sudo cp /var/named/example.com.zone /var/named/example.com.internal

# Create external zone file
sudo nano /var/named/example.com.external

# External zone with public IPs:
$TTL 86400
@   IN  SOA ns1.example.com. admin.example.com. (
        2025091702  ; Serial number
        3600        ; Refresh
        1800        ; Retry
        1209600     ; Expire
        86400       ; Minimum TTL
)

; Name servers
@       IN  NS      ns1.example.com.
@       IN  NS      ns2.example.com.

; Public A records
ns1     IN  A       203.0.113.10
ns2     IN  A       203.0.113.11
@       IN  A       203.0.113.20
www     IN  A       203.0.113.20
mail    IN  A       203.0.113.21

; MX records
@       IN  MX  10  mail.example.com.

# Set permissions
sudo chown root:named /var/named/example.com.external
sudo chmod 640 /var/named/example.com.external

# Test views
dig @localhost example.com
# Should return internal IP for internal clients

DNS Caching and Forwarding

# Configure DNS caching and forwarding
sudo nano /etc/named.conf

# Add forwarders to options section:
options {
    // ... existing options ...

    // DNS Forwarders
    forwarders {
        8.8.8.8;        // Google DNS
        8.8.4.4;        // Google DNS
        1.1.1.1;        // Cloudflare DNS
        1.0.0.1;        // Cloudflare DNS
    };

    forward first;      // Try forwarders first, then root servers

    // Cache settings
    max-cache-size 256M;
    max-cache-ttl 86400;
    max-ncache-ttl 3600;

    // Query limits
    recursive-clients 1000;
    tcp-clients 100;

    // Response rate limiting
    rate-limit {
        responses-per-second 10;
        window 5;
    };
};

# Monitor DNS cache statistics
sudo rndc stats
sudo cat /var/named/data/named_stats.txt
# Output: Shows DNS cache statistics

# Flush DNS cache
sudo rndc flush
# Output: Clears DNS cache

# Dump cache contents
sudo rndc dumpdb -cache
sudo cat /var/named/data/cache_dump.db | head -20
# Output: Shows cached DNS entries

๐ŸŽฎ Quick Examples

Example 1: Corporate DNS Infrastructure

# Set up corporate DNS with multiple zones
sudo dnf install bind bind-utils -y

# Configure corporate DNS server
sudo nano /etc/named.conf

# Corporate DNS configuration:
acl "corporate" {
    192.168.0.0/16;
    10.0.0.0/8;
    172.16.0.0/12;
    localhost;
};

options {
    listen-on port 53 { any; };
    directory "/var/named";
    allow-query { "corporate"; };
    allow-recursion { "corporate"; };

    forwarders {
        8.8.8.8;
        8.8.4.4;
    };

    dnssec-enable yes;
    dnssec-validation yes;

    // Logging
    querylog yes;
};

// Corporate zones
zone "corp.company.com" IN {
    type master;
    file "corp.company.com.zone";
};

zone "dev.company.com" IN {
    type master;
    file "dev.company.com.zone";
};

zone "test.company.com" IN {
    type master;
    file "test.company.com.zone";
};

# Create corporate zone file
sudo nano /var/named/corp.company.com.zone

# Corporate zone content:
$TTL 3600
@   IN  SOA ns1.corp.company.com. admin.company.com. (
        2025091701  ; Serial
        3600        ; Refresh
        1800        ; Retry
        1209600     ; Expire
        3600        ; Minimum TTL
)

; Name servers
@           IN  NS      ns1.corp.company.com.
@           IN  NS      ns2.corp.company.com.

; Infrastructure
ns1         IN  A       192.168.1.10
ns2         IN  A       192.168.1.11
dc1         IN  A       192.168.1.20
dc2         IN  A       192.168.1.21

; Services
mail        IN  A       192.168.1.30
web         IN  A       192.168.1.31
ftp         IN  A       192.168.1.32
proxy       IN  A       192.168.1.33

; Departments
finance     IN  A       192.168.2.10
hr          IN  A       192.168.2.11
it          IN  A       192.168.2.12

; Aliases
intranet    IN  CNAME   web.corp.company.com.
webmail     IN  CNAME   mail.corp.company.com.

# Create development zone
sudo nano /var/named/dev.company.com.zone

# Development zone content:
$TTL 1800
@   IN  SOA ns1.corp.company.com. admin.company.com. (
        2025091701
        1800
        900
        604800
        1800
)

@           IN  NS      ns1.corp.company.com.

; Development servers
app1        IN  A       192.168.10.10
app2        IN  A       192.168.10.11
db1         IN  A       192.168.10.20
db2         IN  A       192.168.10.21
cache       IN  A       192.168.10.30

; Load balancer
api         IN  A       192.168.10.100

# Create DNS management script
sudo nano /usr/local/bin/dns-manager.sh

# Add this content:
#!/bin/bash
# Corporate DNS management script

ZONE_DIR="/var/named"
CONF_FILE="/etc/named.conf"
LOG_FILE="/var/log/dns-manager.log"

# Function to log messages
log_msg() {
    echo "$(date '+%Y-%m-%d %H:%M:%S'): $1" >> "$LOG_FILE"
}

# Function to add DNS record
add_record() {
    local zone=$1
    local name=$2
    local type=$3
    local value=$4

    local zone_file="$ZONE_DIR/${zone}.zone"

    if [ ! -f "$zone_file" ]; then
        log_msg "ERROR: Zone file $zone_file not found"
        return 1
    fi

    # Add record to zone file
    echo "${name}    IN  ${type}    ${value}" >> "$zone_file"

    # Increment serial number
    local today=$(date +%Y%m%d)
    local current_serial=$(grep -o "${today}[0-9][0-9]" "$zone_file" | tail -1)
    local new_serial="${today}01"

    if [ -n "$current_serial" ]; then
        local num=$(echo "$current_serial" | tail -c 3)
        local new_num=$(printf "%02d" $((10#$num + 1)))
        new_serial="${today}${new_num}"
    fi

    sed -i "s/[0-9]\{10\}/${new_serial}/" "$zone_file"

    # Check zone syntax
    if named-checkzone "$zone" "$zone_file" >/dev/null 2>&1; then
        systemctl reload named
        log_msg "Added record: $name $type $value to zone $zone"
        return 0
    else
        log_msg "ERROR: Invalid zone syntax after adding record"
        return 1
    fi
}

# Function to remove DNS record
remove_record() {
    local zone=$1
    local name=$2

    local zone_file="$ZONE_DIR/${zone}.zone"

    # Remove record from zone file
    sed -i "/^${name}\s/d" "$zone_file"

    # Increment serial number (same logic as add_record)
    local today=$(date +%Y%m%d)
    local current_serial=$(grep -o "${today}[0-9][0-9]" "$zone_file" | tail -1)
    local new_serial="${today}01"

    if [ -n "$current_serial" ]; then
        local num=$(echo "$current_serial" | tail -c 3)
        local new_num=$(printf "%02d" $((10#$num + 1)))
        new_serial="${today}${new_num}"
    fi

    sed -i "s/[0-9]\{10\}/${new_serial}/" "$zone_file"

    systemctl reload named
    log_msg "Removed record: $name from zone $zone"
}

# Usage examples:
case "$1" in
    add)
        add_record "$2" "$3" "$4" "$5"
        ;;
    remove)
        remove_record "$2" "$3"
        ;;
    *)
        echo "Usage: $0 {add|remove} zone name [type] [value]"
        echo "Examples:"
        echo "  $0 add corp.company.com server1 A 192.168.1.50"
        echo "  $0 remove corp.company.com server1"
        exit 1
        ;;
esac

# Make script executable
sudo chmod +x /usr/local/bin/dns-manager.sh

# Set proper permissions and start services
sudo chown root:named /var/named/*.zone
sudo chmod 640 /var/named/*.zone
sudo systemctl restart named
sudo systemctl enable named

# Test corporate DNS
dig @localhost corp.company.com
dig @localhost ns1.corp.company.com

Example 2: High-Availability DNS Cluster

# Set up DNS master-slave configuration
# Primary DNS Server (192.168.1.10)

sudo nano /etc/named.conf

# Master DNS configuration:
options {
    listen-on port 53 { any; };
    directory "/var/named";
    allow-query { any; };
    allow-transfer { 192.168.1.11; 192.168.1.12; };
    also-notify { 192.168.1.11; 192.168.1.12; };

    notify yes;
    notify-source 192.168.1.10;

    forwarders {
        8.8.8.8;
        8.8.4.4;
    };
};

zone "ha.example.com" IN {
    type master;
    file "ha.example.com.zone";
    allow-transfer { 192.168.1.11; 192.168.1.12; };
    notify yes;
};

# Secondary DNS Server configuration (192.168.1.11)
sudo nano /etc/named.conf

# Slave DNS configuration:
options {
    listen-on port 53 { any; };
    directory "/var/named";
    allow-query { any; };

    forwarders {
        8.8.8.8;
        8.8.4.4;
    };
};

zone "ha.example.com" IN {
    type slave;
    file "slaves/ha.example.com.zone";
    masters { 192.168.1.10; };
};

# Create DNS monitoring script
sudo nano /usr/local/bin/dns-ha-monitor.sh

# Add this content:
#!/bin/bash
# DNS High Availability monitoring script
PRIMARY_DNS="192.168.1.10"
SECONDARY_DNS="192.168.1.11"
TERTIARY_DNS="192.168.1.12"
VIP="192.168.1.100"
INTERFACE="eth0"
LOG_FILE="/var/log/dns-ha.log"

# Function to log messages
log_msg() {
    echo "$(date '+%Y-%m-%d %H:%M:%S'): $1" >> "$LOG_FILE"
}

# Function to check DNS server
check_dns() {
    local dns_server=$1
    local test_query="ha.example.com"

    if dig @"$dns_server" "$test_query" +time=5 >/dev/null 2>&1; then
        return 0  # DNS server is working
    else
        return 1  # DNS server is down
    fi
}

# Function to activate virtual IP
activate_vip() {
    ip addr add "$VIP/24" dev "$INTERFACE" 2>/dev/null
    log_msg "Virtual IP $VIP activated on $(hostname)"
}

# Function to deactivate virtual IP
deactivate_vip() {
    ip addr del "$VIP/24" dev "$INTERFACE" 2>/dev/null
    log_msg "Virtual IP $VIP deactivated on $(hostname)"
}

# Main monitoring logic
CURRENT_IP=$(ip addr show "$INTERFACE" | grep inet | awk '{print $2}' | cut -d'/' -f1 | grep -v 127)

if [ "$CURRENT_IP" = "$PRIMARY_DNS" ]; then
    # This is the primary DNS server
    if systemctl is-active named >/dev/null; then
        activate_vip
        log_msg "Primary DNS server operational"
    else
        log_msg "Primary DNS server down, starting service"
        systemctl start named
    fi

elif [ "$CURRENT_IP" = "$SECONDARY_DNS" ]; then
    # This is the secondary DNS server
    if ! check_dns "$PRIMARY_DNS"; then
        log_msg "Primary DNS down, activating secondary"
        activate_vip
        systemctl start named
    else
        deactivate_vip
        log_msg "Primary DNS operational, secondary on standby"
    fi

elif [ "$CURRENT_IP" = "$TERTIARY_DNS" ]; then
    # This is the tertiary DNS server
    if ! check_dns "$PRIMARY_DNS" && ! check_dns "$SECONDARY_DNS"; then
        log_msg "Primary and secondary DNS down, activating tertiary"
        activate_vip
        systemctl start named
    else
        deactivate_vip
        log_msg "Higher priority DNS servers operational"
    fi
fi

# DNS health check and statistics
QUERIES_TODAY=$(grep "$(date +'%d-%b-%Y')" /var/log/named/query.log 2>/dev/null | wc -l)
log_msg "DNS queries processed today: $QUERIES_TODAY"

# Make script executable and schedule
sudo chmod +x /usr/local/bin/dns-ha-monitor.sh
echo "* * * * * /usr/local/bin/dns-ha-monitor.sh" | sudo crontab -

# Test DNS cluster
for server in $PRIMARY_DNS $SECONDARY_DNS $TERTIARY_DNS; do
    echo "Testing DNS server $server:"
    dig @"$server" ha.example.com +short
done

Example 3: DNS Security and Monitoring System

# Set up comprehensive DNS security and monitoring
sudo dnf install bind bind-utils fail2ban -y

# Configure DNS security
sudo nano /etc/named.conf

# Secure DNS configuration:
options {
    listen-on port 53 { localhost; 192.168.1.0/24; };
    directory "/var/named";

    // Security settings
    version "Secure DNS Server";
    hostname none;
    server-id none;

    // Access control
    allow-query { localhost; 192.168.1.0/24; };
    allow-recursion { localhost; 192.168.1.0/24; };
    allow-transfer { none; };

    // Rate limiting
    rate-limit {
        responses-per-second 10;
        window 5;
        slip 2;
    };

    // DNSSEC
    dnssec-enable yes;
    dnssec-validation yes;

    // Blacklist known malicious domains
    response-policy { zone "rpz.local"; };
};

// Response Policy Zone for security
zone "rpz.local" {
    type master;
    file "rpz.local.zone";
};

# Create RPZ zone for blocking malicious domains
sudo nano /var/named/rpz.local.zone

# Add RPZ content:
$TTL 300
@   IN  SOA localhost. admin.localhost. (
        2025091701
        3600
        1800
        604800
        300
)

@       IN  NS  localhost.

; Block malicious domains
malware.example.com     IN  CNAME   .
phishing.example.com    IN  CNAME   .
spam.example.com        IN  CNAME   .

# Configure fail2ban for DNS protection
sudo nano /etc/fail2ban/jail.d/named.conf

# Add fail2ban configuration:
[named-refused]
enabled = true
filter = named-refused
action = iptables[name=named-refused, port=53, protocol=udp]
logpath = /var/log/named/security.log
maxretry = 3
bantime = 3600
findtime = 600

# Create fail2ban filter
sudo nano /etc/fail2ban/filter.d/named-refused.conf

# Add filter content:
[Definition]
failregex = client <HOST>#\d+.*: query \(cache\) '.*' denied
            client <HOST>#\d+.*: query '.*' denied

ignoreregex =

# Create comprehensive DNS monitoring script
sudo nano /usr/local/bin/dns-security-monitor.sh

# Add this content:
#!/bin/bash
# DNS Security Monitoring Script
LOG_FILE="/var/log/dns-security.log"
ALERT_EMAIL="[email protected]"
QUERY_LOG="/var/log/named/query.log"
SECURITY_LOG="/var/log/named/security.log"

# Function to log messages
log_msg() {
    echo "$(date '+%Y-%m-%d %H:%M:%S'): $1" >> "$LOG_FILE"
}

# Function to send alert
send_alert() {
    local subject="$1"
    local message="$2"
    echo "$message" | mail -s "$subject" "$ALERT_EMAIL"
    log_msg "ALERT: $subject"
}

# Check for DNS anomalies
check_dns_anomalies() {
    # Check for high query rate from single IP
    local high_query_ips=$(tail -1000 "$QUERY_LOG" | awk '{print $1}' | sort | uniq -c | awk '$1 > 50 {print $2}')

    for ip in $high_query_ips; do
        local count=$(tail -1000 "$QUERY_LOG" | grep "$ip" | wc -l)
        if [ "$count" -gt 50 ]; then
            send_alert "High DNS Query Rate" "IP $ip has made $count queries in recent logs"
        fi
    done

    # Check for failed queries
    local failed_queries=$(grep "REFUSED" "$SECURITY_LOG" 2>/dev/null | tail -100 | wc -l)
    if [ "$failed_queries" -gt 20 ]; then
        send_alert "High DNS Refusal Rate" "Found $failed_queries refused queries in recent logs"
    fi

    # Check for suspicious domain queries
    local suspicious_domains=$(grep -E "(malware|phishing|spam|botnet)" "$QUERY_LOG" 2>/dev/null | tail -10)
    if [ -n "$suspicious_domains" ]; then
        send_alert "Suspicious Domain Queries" "Detected queries for suspicious domains:\n$suspicious_domains"
    fi
}

# Monitor DNS performance
monitor_dns_performance() {
    # Check response time
    local response_time=$(dig @localhost google.com | grep "Query time" | awk '{print $4}')
    if [ -n "$response_time" ] && [ "$response_time" -gt 1000 ]; then
        log_msg "WARNING: High DNS response time: ${response_time}ms"
    fi

    # Check cache hit ratio
    rndc stats
    local cache_hits=$(grep "cache hits" /var/named/data/named_stats.txt | tail -1 | awk '{print $1}')
    local cache_misses=$(grep "cache misses" /var/named/data/named_stats.txt | tail -1 | awk '{print $1}')

    if [ -n "$cache_hits" ] && [ -n "$cache_misses" ]; then
        local total=$((cache_hits + cache_misses))
        if [ "$total" -gt 0 ]; then
            local hit_ratio=$((cache_hits * 100 / total))
            log_msg "Cache hit ratio: ${hit_ratio}%"
            if [ "$hit_ratio" -lt 80 ]; then
                log_msg "WARNING: Low cache hit ratio: ${hit_ratio}%"
            fi
        fi
    fi
}

# Generate security report
generate_security_report() {
    local report_file="/tmp/dns-security-report-$(date +%Y%m%d).txt"

    cat > "$report_file" << EOF
DNS Security Report - $(date)
============================

Service Status:
$(systemctl status named --no-pager -l)

Recent Query Statistics:
$(tail -1000 "$QUERY_LOG" | awk '{print $7}' | sort | uniq -c | sort -rn | head -10)

Top Querying IPs:
$(tail -1000 "$QUERY_LOG" | awk '{print $1}' | sort | uniq -c | sort -rn | head -10)

Recent Security Events:
$(tail -50 "$SECURITY_LOG" 2>/dev/null || echo "No security events logged")

Cache Statistics:
$(rndc stats && cat /var/named/data/named_stats.txt | tail -20)
EOF

    echo "Security report generated: $report_file"
    log_msg "Security report generated: $report_file"
}

# Main monitoring execution
log_msg "Starting DNS security monitoring"
check_dns_anomalies
monitor_dns_performance

# Generate daily report if it's midnight
if [ "$(date +%H:%M)" = "00:00" ]; then
    generate_security_report
fi

log_msg "DNS security monitoring completed"

# Make script executable and schedule
sudo chmod +x /usr/local/bin/dns-security-monitor.sh
echo "*/10 * * * * /usr/local/bin/dns-security-monitor.sh" | sudo crontab -

# Start and enable security services
sudo systemctl start named fail2ban
sudo systemctl enable named fail2ban

# Test security configuration
dig @localhost malware.example.com
dig @localhost google.com

๐Ÿšจ Fix Common Problems

Problem 1: DNS Server Not Responding

Symptoms: DNS queries timeout or fail

Solution:

# Check if DNS service is running
sudo systemctl status named
sudo netstat -tlnp | grep :53

# Check DNS configuration syntax
sudo named-checkconf
sudo named-checkconf -z

# Check zone file syntax
sudo named-checkzone example.com /var/named/example.com.zone

# Check firewall settings
sudo firewall-cmd --list-services
sudo firewall-cmd --list-ports

# Test DNS locally
dig @localhost google.com
nslookup google.com localhost

# Check DNS logs for errors
sudo tail -f /var/log/messages | grep named
sudo journalctl -u named -f

# Restart DNS service
sudo systemctl restart named

# Check if DNS is binding to correct interfaces
sudo ss -tulnp | grep :53

Problem 2: Zone Transfer Issues

Symptoms: Secondary DNS servers not receiving zone updates

Solution:

# Check zone transfer configuration
sudo named-checkconf | grep -A 5 -B 5 transfer

# Test zone transfer manually
dig @primary-dns-ip AXFR example.com

# Check if notify is working
sudo rndc notify example.com

# Check secondary server logs
sudo tail -f /var/log/messages | grep "transfer of"

# Verify allow-transfer settings
sudo grep -r "allow-transfer" /etc/named.conf

# Force zone refresh on secondary
sudo rndc refresh example.com

# Check serial numbers
dig @primary-dns SOA example.com
dig @secondary-dns SOA example.com

# Update serial number and reload
sudo nano /var/named/example.com.zone
# Increment serial number
sudo systemctl reload named

Problem 3: DNS Resolution Problems

Symptoms: Domains not resolving correctly

Solution:

# Check if domain exists in zone file
grep -i "domain-name" /var/named/example.com.zone

# Test different record types
dig @localhost domain-name A
dig @localhost domain-name AAAA
dig @localhost domain-name CNAME

# Check forwarders configuration
dig @8.8.8.8 external-domain.com
dig @localhost external-domain.com

# Clear DNS cache
sudo rndc flush
sudo rndc flushname domain-name

# Check recursion settings
sudo grep -r "recursion" /etc/named.conf

# Test with different DNS servers
dig @8.8.8.8 domain-name
dig @1.1.1.1 domain-name

# Check client DNS configuration
cat /etc/resolv.conf
nslookup domain-name

# Trace DNS resolution path
dig +trace domain-name

๐Ÿ“‹ Simple Commands Summary

CommandPurposeExample
systemctl start namedStart DNS serversudo systemctl start named
named-checkconfCheck DNS configsudo named-checkconf
named-checkzoneCheck zone filesudo named-checkzone example.com /var/named/example.com.zone
dig @server domainTest DNS querydig @localhost google.com
rndc reloadReload DNS configsudo rndc reload
rndc flushClear DNS cachesudo rndc flush
nslookup domainDNS lookupnslookup google.com
firewall-cmd --add-service=dnsAllow DNS trafficsudo firewall-cmd --permanent --add-service=dns

๐Ÿ’ก Tips for Success

Here are proven strategies to master DNS server configuration! ๐ŸŒŸ

Best Practices

  • ๐Ÿ“Š Monitor Continuously: Keep track of DNS queries, performance, and errors
  • ๐Ÿ›ก๏ธ Security First: Implement DNSSEC, rate limiting, and access controls
  • ๐Ÿ’พ Regular Backups: Backup zone files and configurations regularly
  • ๐Ÿ”„ Update Serial Numbers: Always increment serial numbers when updating zones
  • ๐Ÿ“ Document Everything: Maintain detailed records of DNS configurations and changes
  • ๐Ÿงช Test Thoroughly: Test all DNS changes before implementing in production
  • ๐Ÿ“ˆ Plan for Growth: Design DNS infrastructure to handle increasing query loads
  • ๐ŸŽฏ High Availability: Implement redundant DNS servers for reliability

Performance Optimization

  • Use appropriate TTL values for different record types โฐ
  • Implement DNS caching to reduce external queries ๐Ÿ’พ
  • Monitor and optimize forwarder performance ๐Ÿš€
  • Use anycast for global DNS distribution ๐ŸŒ
  • Implement query rate limiting to prevent abuse ๐Ÿ›ก๏ธ
  • Regular monitoring of cache hit ratios ๐Ÿ“Š
  • Optimize zone file organization and structure ๐Ÿ“‹
  • Use views for split DNS and geographic optimization ๐Ÿ—บ๏ธ

๐Ÿ† What You Learned

Congratulations! Youโ€™ve mastered DNS server configuration on AlmaLinux! ๐ŸŽ‰ Hereโ€™s what you can now do:

โœ… Install and Configure BIND: Set up authoritative DNS servers with BIND9 โœ… Manage DNS Zones: Create and maintain forward and reverse DNS zones โœ… Implement Security: Configure DNSSEC, access controls, and security monitoring โœ… High Availability: Set up master-slave DNS configurations and failover systems โœ… Advanced Features: Implement views, caching, forwarding, and split DNS โœ… Monitor and Maintain: Set up comprehensive monitoring and alerting systems โœ… Troubleshoot Issues: Diagnose and fix common DNS server problems โœ… Optimize Performance: Configure DNS servers for optimal query response times

๐ŸŽฏ Why This Matters

Mastering DNS server configuration is fundamental to network infrastructure! ๐Ÿš€ With these skills, you can:

  • Control Name Resolution: Provide fast, reliable DNS services for your organization ๐ŸŒ
  • Enhance Security: Implement DNS-based security measures and threat protection ๐Ÿ›ก๏ธ
  • Improve Performance: Optimize DNS queries and reduce network latency โšก
  • Enable Scalability: Build DNS infrastructure that grows with your needs ๐Ÿ“ˆ
  • Ensure Reliability: Implement redundant DNS systems for high availability ๐Ÿ”„
  • Support Compliance: Meet regulatory requirements for DNS logging and security ๐Ÿ“‹

DNS is the foundation of internet communications! Whether youโ€™re managing a small network or enterprise infrastructure, these skills will help you build reliable, secure, and efficient name resolution services. Remember, when DNS works well, nobody notices - but when it fails, everything stops working! โญ

Excellent work on mastering DNS server configuration on AlmaLinux! You now have the expertise to build and manage enterprise-grade DNS infrastructure that forms the backbone of network communications! ๐Ÿ™Œ