Wednesday, January 21, 2015

TUTORIAL: Syncing DNS Zones from Windows DNS Server to Linux Bind9 DNS Server


Windows Setup 

First step is to dump the DNS zones from Windows into a file. Then generate an FTP command file which will upload the DNS zone file dump to your bind server. I've created a batch script to handle all of this:

@echo off
dnscmd /enumzones > dns.zones.txt
echo user ftp_bind_user> ftpcmd.dat
echo ftp_bind_password>> ftpcmd.dat
echo bin>> ftpcmd.dat
echo put dns.zones.txt>> ftpcmd.dat
echo quit>> ftpcmd.dat
ftp -n -s:ftpcmd.dat 192.168.1.101

del ftpcmd.dat
del dns.zones.txt

Some notes about the above script:
192.168.1.101 is the bind9 server's IP address.
ftp_bind_user is the ftp user name setup on the bind9 server
ftp_bind_password is the ftp password setup on the bind9 server

I have this batch script run every hour, on the hour, using the Window task scheduler. This script will most likely need to run as an administrator in order to dump the DNS zones to a file.

Linux Setup

Now we setup the bash script. This script will first parse and format dns.zones.txt into a usable bind format, then it will scan all the current zone files and remove any that are not listed in the updated zone file. I set this script to run every hour, ten minutes after each hour. This script assumes you have bind running as user "bind" in group "bind", please change the chown line accordingly.

#!/bin/bash

ZONE_PATH="/home/bind"
BIND_PATH="/var/lib/bind"
TMP=$(mktemp)
FC="dns.zones.txt"

for ZONE in $(awk '$2=="Primary" {print $1}' "${ZONE_PATH}/${FC}")
do
 printf "zone ${ZONE} {\n\ttype slave;\n\tmasters { 192.168.1.100; };\n\tfile \"${BIND_PATH}/${ZONE}.zone\";\n};\n"
done > ${TMP}

for ZONE in "$BIND_PATH"/*.zone
do
  grep -q "${ZONE}" "${TMP}" || rm -rf "${ZONE}"
done

mv ${TMP} /etc/bind/named.conf.slave-zones
chown bind:bind /etc/bind/named.conf.slave-zones

rndc reload

Some notes about the above script:
ZONE_PATH is where the dns.zones.txt file is uploaded to, this is of course determined by your FTP server setup (I setup proftpd with SQL backend, but you could easily setup vsftpd)
BIND_PATH is where we are telling bind to store the zone files.
192.168.1.100 is the IP Address of the Windows DNS Server
/etc/bind/named.conf.slave-zones is setup to be included in the "named.conf" file with the line:
    include "/etc/bind/named.conf.slave-zones";






TUTORIAL: Compile bind9 on linux with Response Rate Limiting (to prevent DDoS DNS attacks)

This tutorial can easily be applied to most any linux system. I went through these steps on Debian 7 server.

First let's setup the environment, this tutorial assumes you have no previous install of bind on the server.

mkdir -p /var/local/cache/bind
mkdir -p /usr/local/etc/bind

groupadd -g 5005 bind
useradd -u 5005 -g 5005 -d /var/local/cache/bind -M -s /bin/false bind

Now let's download the bind9 source code. This tutorial assumes you have the required dependencies installed. The only one I found tricky to locate was libkrb5-dev (on Debian you can install it with apt-get install libkrb5-dev)

cd /usr/src

wget http://ftp.isc.org/isc/bind9/cur/9.9/bind-9.9.5-P1.tar.gz

tar zxvf bind-9.9.5-P1.tar.gz

cd bind-9.9.5-P1

./configure '--enable-threads' '--enable-largefile' '--with-libtool' '--enable-shared' '--enable-static' '--with-openssl=/usr' '--with-gssapi=/usr' '--with-gnu-ld' '--with-geoip=/usr' '--enable-ipv6' '--enable-rrl'

make

make install

wget --user=ftp --password=ftp ftp://ftp.rs.internic.net/domain/db.cache -O /usr/local/etc/bind/db.root

Last step is to install the configuration files and startup scripts.

rndc-confgen -a -c /usr/local/etc/bind/rndc.key

cat > /etc/named.conf <<EOT
include "
/usr/local/etc/bind/rndc.key";
include "/usr/local/etc/bind/named.conf";

EOT
cat > /usr/local/etc/named.conf <<EOT
#
controls {
        inet 127.0.0.1 port 953
        allow { 127.0.0.1; 192.168.1.100; } keys { "rndc-key"; };
};

options {
        directory "/var/local/cache/bind";
        allow-new-zones yes;
        transfers-in 500;
        empty-zones-enable yes;
        //forwarders { 8.8.8.8; 8.8.4.4; };
        recursion yes;
        //allow-transfer {"none";};
        allow-query { any; };
        allow-recursion { any; };

        dnssec-validation auto;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };

        rate-limit {
            responses-per-second 5;
            #window 5;
            #log-only yes;
        };
};

zone "." {
        type hint;
        file "/usr/local/etc/bind/db.root";
};

EOT
 

chown bind:bind -R /var/local/cache/bind
chown bind:bind -R /usr/local/etc/bind

Please note the init.d scripts only work on Debian based systems. I do not have init.d scripts for any other distribution.

Download the init.d script here
Download the init.d default file here

Copy the init.d script to /etc/init.d/bind9
Copy the init.d default file to /etc/default/bind9

chmod +x /etc/init.d/bind9

/etc/init.d/bind9 start

Redirect to new blog page

https://blog.voipxswitch.com/2015/03/06/syncing-dns-zones-from-windows-dns-server-to-linux-bind9-dns-server//