DNS Deployment Guide

    Deploying BIND/Named DNS Server on RamNode VPS

    BIND (Berkeley Internet Name Domain) is the most widely used DNS software on the internet. This guide covers deploying a production-ready BIND9 DNS server for hosting authoritative DNS for your domains or running a private recursive resolver for your infrastructure.

    Ubuntu 22.04/24.04 or AlmaLinux 8/9
    1GB RAM (2GB recommended)
    ⏱️ 20-30 minutes

    Prerequisites

    Before starting, ensure you have:

    Server Requirements

    • • RamNode VPS with at least 1GB RAM (2GB recommended for busy servers)
    • • Ubuntu 22.04/24.04 or AlmaLinux 8/9
    • • Root or sudo access
    • • Static IP address (standard on RamNode VPS)

    Additional Requirements

    • • Domain name (for authoritative DNS)
    • • SSH access credentials
    • • Basic Linux command knowledge
    • • Understanding of DNS concepts
    2

    Installation

    Install BIND9 DNS server on your system:

    Ubuntu/Debian
    apt update && apt install -y bind9 bind9-utils bind9-dnsutils
    AlmaLinux/Rocky
    dnf install -y bind bind-utils

    ✅ BIND9 is now installed and ready for configuration.

    3

    Directory Structure

    Understanding BIND's layout helps with configuration and troubleshooting:

    PathDescription
    /etc/bind/Ubuntu config directory
    /etc/named/RHEL-based config directory
    named.confMain configuration file
    named.conf.optionsServer options (Ubuntu)
    named.conf.localZone definitions (Ubuntu)
    zones/Zone files directory (create this)
    4

    Option 1: Authoritative DNS Server

    This configuration serves DNS records for your own domains. Create the options file at /etc/bind/named.conf.options on Ubuntu, or edit /etc/named.conf on RHEL-based systems:

    /etc/bind/named.conf.options
    options {
        directory "/var/cache/bind";
        recursion no;
        version "not available";
        listen-on { 127.0.0.1; YOUR_VPS_IP; };
        listen-on-v6 { ::1; YOUR_VPS_IPV6; };
        allow-transfer { none; };
        rate-limit {
            responses-per-second 10;
            window 5;
        };
        dnssec-validation auto;
    };

    Create the log directory:

    Create Log Directory
    mkdir -p /var/log/named
    chown bind:bind /var/log/named    # Ubuntu
    chown named:named /var/log/named  # RHEL

    Define Zones

    Add to /etc/bind/named.conf.local on Ubuntu:

    /etc/bind/named.conf.local
    zone "example.com" {
        type master;
        file "/etc/bind/zones/db.example.com";
        allow-transfer { SECONDARY_DNS_IP; };
    };

    Create Zone File

    Create /etc/bind/zones/db.example.com:

    Create zones directory and zone file
    mkdir -p /etc/bind/zones
    /etc/bind/zones/db.example.com
    $TTL 86400
    @     IN  SOA   ns1.example.com. admin.example.com. (
                  2024010101     ; Serial (YYYYMMDDNN)
                  3600           ; Refresh (1 hour)
                  1800           ; Retry (30 minutes)
                  1209600        ; Expire (2 weeks)
                  86400          ; Negative TTL (1 day)
    )
          IN  NS    ns1.example.com.
          IN  NS    ns2.example.com.
    ns1   IN  A     YOUR_VPS_IP
    ns2   IN  A     SECONDARY_DNS_IP
    @     IN  A     WEB_SERVER_IP
    www   IN  A     WEB_SERVER_IP

    💡 Tip: Replace YOUR_VPS_IP, SECONDARY_DNS_IP, and WEB_SERVER_IP with your actual IP addresses. Always increment the serial number after zone file changes.

    5

    Option 2: Private Recursive Resolver

    For a caching resolver serving your infrastructure:

    ACL Configuration

    ACL Configuration (add to named.conf.options)
    acl "trusted" {
        localhost;
        10.0.0.0/8;
        172.16.0.0/12;
        192.168.0.0/16;
        YOUR_TRUSTED_IPS;
    };

    Options Configuration

    Recursive Resolver Options
    options {
        directory "/var/cache/bind";
        recursion yes;
        allow-recursion { trusted; };
        allow-query { trusted; };
        forwarders { 1.1.1.1; 1.0.0.1; 8.8.8.8; };
        forward first;
        dnssec-validation auto;
    };

    ⚠️ Important: Never enable open recursion on the internet. Always restrict recursive queries to trusted networks to prevent DNS amplification attacks.

    6

    Firewall Configuration

    Configure your firewall to allow DNS traffic:

    UFW (Ubuntu)
    ufw allow 53/tcp
    ufw allow 53/udp
    ufw reload
    firewalld (RHEL)
    firewall-cmd --permanent --add-service=dns
    firewall-cmd --reload

    For a private resolver, restrict source IPs:

    Restrict to specific network
    ufw allow from YOUR_NETWORK/24 to any port 53
    7

    Validation and Testing

    Verify your configuration and test DNS resolution:

    Check Configuration Syntax

    Validate Configuration
    named-checkconf
    named-checkzone example.com /etc/bind/zones/db.example.com

    Start and Enable Service

    RHEL-based Systems
    systemctl enable --now named
    Ubuntu
    systemctl enable --now bind9

    Test DNS Resolution

    Test DNS Queries
    dig @localhost example.com
    dig @YOUR_VPS_IP example.com +short

    ✅ If the dig commands return the expected records, your DNS server is working correctly.

    8

    Security Hardening

    Zone Transfer Restrictions

    Restrict zone transfers by specifying secondary servers explicitly:

    Zone Transfer Restriction
    allow-transfer { SECONDARY_IP; key "transfer-key"; };

    Response Rate Limiting

    Enable response rate limiting (already included in the configuration above) to mitigate DNS amplification attacks.

    Chroot Environment (RHEL)

    Enable Chroot (RHEL)
    dnf install bind-chroot
    systemctl enable --now named-chroot

    Fail2ban Integration

    Create /etc/fail2ban/jail.d/named.conf:

    /etc/fail2ban/jail.d/named.conf
    [named-refused]
    enabled = true
    port = 53
    filter = named-refused
    logpath = /var/log/named/named.log
    maxretry = 5
    bantime = 3600
    9

    Monitoring

    Statistics Channel

    Add to options block for statistics access:

    Statistics Channel Configuration
    statistics-channels {
        inet 127.0.0.1 port 8053 allow { 127.0.0.1; };
    };

    RNDC Commands

    Check BIND Status
    rndc status
    rndc stats

    Log Rotation

    Create /etc/logrotate.d/named:

    /etc/logrotate.d/named
    /var/log/named/named.log {
        weekly
        rotate 4
        compress
        missingok
        notifempty
        postrotate
            /usr/sbin/rndc reload > /dev/null 2>&1 || true
        endscript
    }
    10

    Secondary DNS Setup

    For redundancy, configure a second RamNode VPS as a secondary DNS server:

    Secondary DNS Zone Configuration
    zone "example.com" {
        type slave;
        file "/var/cache/bind/db.example.com";
        masters { PRIMARY_DNS_IP; };
    };

    💡 Tip: For production authoritative DNS, run at least two geographically separated VPS instances as primary and secondary name servers.

    11

    Common Operations

    Useful commands for managing your BIND server:

    • Reload after zone changes: rndc reload
    • Reload specific zone: rndc reload example.com
    • Clear cache (recursive resolver): rndc flush

    ⚠️ Important: Always increment the serial number after every zone file edit—BIND won't propagate changes otherwise.

    12

    Troubleshooting

    Check Logs

    View BIND Logs
    journalctl -u bind9 -f     # Ubuntu
    journalctl -u named -f     # RHEL
    tail -f /var/log/named/named.log

    Common Issues

    "zone has no NS records"

    Ensure NS records point to valid hostnames with A records.

    "network unreachable"

    Check firewall rules and listen-on directives.

    Changes not propagating

    Verify serial number was incremented in the zone file.

    Deployment Complete!

    Your BIND DNS server is now deployed and ready to serve DNS queries. This setup provides a solid foundation for either authoritative DNS hosting or a private recursive resolver on your RamNode VPS.