Tuesday, November 20, 2012

djndns on CentOS6

I use DJB's dns package for a long time and I am satisfied with it. Recently I started migrating it to a CentOS6 machine.
My new requirements were following:
  • run services from init script
  • collect log messages by syslog-ng
  • have config files under /etc
There are a few guides on the net but they use DJB's svscan service to start-stop djb services and they use multilog as log collector.
There is my guide to achieve my requirements:
Install prerequisites (build environment):
yum install gcc make

Build daemontools

cd /usr/local/src
wget http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
tar xvfz daemontools-0.76.tar.gz
cd admin/daemontools-0.76
sed -i '/gcc/ s|$| -include /usr/include/errno.h|' src/conf-cc
package/compile
for i in $(cat package/commands); do cp command/$i /usr/local/bin/$i; done

Build ucspi-tcp

cd /usr/local/src
wget http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz
tar xvfz ucspi-tcp-0.88.tar.gz
cd ucspi-tcp-0.88
sed -i '/gcc/ s|$| -include /usr/include/errno.h|' conf-cc
make
make setup check

Build djbdns

cd /usr/local/src
wget http://cr.yp.to/djbdns/djbdns-1.05.tar.gz
tar xvfz djbdns-1.05.tar.gz
cd djbdns-1.05
sed -i '/gcc/ s|$| -include /usr/include/errno.h|' conf-cc
make
make setup check
UPDATE:

Add /usr/local/bin to your PATH:

sed -i '/PATH=/ s|$|:/usr/local/bin|' /root/.bash_profile
Re-login or simply add to bash session:
export PATH=$PATH:/usr/local/bin

dnscache

Create dnscache users
groupadd -g 200 djbdns
useradd --no-create-home -s /bin/false -u 201 -g 200 dnscache
useradd --no-create-home -s /bin/false -u 202 -g 200 dnslog
Setup dnscache
dnscache-conf dnscache dnslog /etc/dnscache 192.168.233.254
Specify client's address range
touch /etc/dnscache/root/ip/192.168.233
Create init script
cat >/etc/init.d/dnscache <<EOF
#!/bin/bash
#
# dnscache      DNS cache server
#
# chkconfig: 345 11 89
# Provides: dnscache
# Required-Start: \$network
# Required-Stop: \$network
# Short-Description: start and stop dnscache
# Description: Dan Bernstein (DJB) dns cache server
# ZsZs
 
# Source function library.
. /etc/rc.d/init.d/functions
 
prog=dnscache
progdir=/usr/local/bin
 
# pull in sysconfig settings
[ -f /etc/sysconfig/dnscache ] && . /etc/sysconfig/dnscache
 
start(){
    echo -n \$"Starting \$prog: "
    pid=\$(pidof \$progdir/\$prog)
    if [[ "\$pid" == "" ]]; then
        # Read up dnscache environment files and export them
        for env in \$(cd \$dnscachedir/env/; ls -1); do envs="\$envs \$env=\$(cat \$dnscachedir/env/\$env)"; done
        export \$envs
        \$progdir/envuidgid dnscache \$progdir/softlimit -o250 -d "\$DATALIMIT" \
          \$progdir/\$prog 2>&1 | (\$progdir/setuidgid dnslog /usr/bin/logger -p local4.info -t \$prog) &
        if [[ "\$?" == "0" ]]
        then
            success
            echo
        else
            failure \$"\$prog start"
            echo
            exit 1
        fi
    else
        failure \$"\$prog start"
        echo
        exit 1
    fi
}
 
stop(){
    pid=\$(pidof \$progdir/\$prog)
    if [[ "\$pid" == "" ]]
    then
        echo -n "Stopping  \$prog: "
        failure \$"\$prog not running."
        echo
    else
        echo -n "Stopping \$prog: "
        kill \$pid && success || failure \$"\$prog stop"
        echo
    fi
}
 
# See how we were called.
case "\$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        sleep 1
        start
        ;;
    *)
        echo "Usage: \$prog {start|stop|restart}"
        exit 1
esac
 
exit 0
EOF
Create dnscache config file
echo "dnscachedir=/etc/dnscache" >/etc/sysconfig/dnscache
Start dnscache service
chmod 755 /etc/init.d/dnscache
service dnscache start
chkconfig dnscache on

tinydns

Create tinydns users
useradd --no-create-home -s /bin/false -u 203 -g 200 tinydns
useradd --no-create-home -s /bin/false -u 204 -g 200 tinylog
Install tinydns
tinydns-conf tinydns tinylog /etc/tinydns your.pub.lic.ip
cd /etc/tinydns/root
Create example domain Add SOA record
./add-ns example.hu 123.123.123.123
Add host
./add-host garfield.examle.hu 123.123.123.124
Add MX record
./add-mx examle.hu 123.123.123.123
Add alias
./add-alias www.example.hu 123.123.123.123
Make data.cdb
make
Create init script
cat >/etc/init.d/tinydns <<EOF
#!/bin/bash
#
# tinydns      Authoritative DNS server
#
# chkconfig: 345 11 89
# Provides: tinydns
# Required-Start: \$network
# Required-Stop: \$network
# Short-Description: start and stop tinydns
# Description: Dan Bernstein (DJB) authoritative dns server
# ZsZs
 
# Source function library.
. /etc/rc.d/init.d/functions
 
prog=tinydns
progdir=/usr/local/bin
 
# pull in sysconfig settings
[ -f /etc/sysconfig/tinydns ] && . /etc/sysconfig/tinydns
 
start(){
    echo -n \$"Starting \$prog: "
    pid=\$(pidof \$progdir/\$prog)
    if [[ "\$pid" == "" ]]; then
        # Read up tinydns environment files and export them
        for env in \$(cd \$tinydnsdir/env/; ls -1); do envs="\$envs \$env=\$(cat \$tinydnsdir/env/\$env)"; done
        export \$envs
        \$progdir/envuidgid tinydns \$progdir/softlimit -d300000 \$progdir/\$prog 2>&1 | \
          (\$progdir/setuidgid tinylog /usr/bin/logger -p local4.info -t \$prog) &
        if [[ "\$?" == "0" ]]
        then
            success
            echo
        else
            failure \$"\$prog start"
            echo
            exit 1
        fi
    else
        failure \$"\$prog start"
        echo
        exit 1
    fi
}
 
stop(){
    pid=\$(pidof \$progdir/\$prog)
    if [[ "\$pid" == "" ]]
    then
        echo -n "Stopping  \$prog: "
        failure \$"\$prog not running."
        echo
    else
        echo -n "Stopping \$prog: "
        kill \$pid && success || failure \$"\$prog stop"
        echo
    fi
}
 
# See how we were called.
case "\$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        sleep 1
        start
        ;;
    *)
        echo "Usage: \$prog {start|stop|restart}"
        exit 1
esac
 
exit 0
EOF
Create tinydns config file
echo "tinydnsdir=/etc/tinydns" >/etc/sysconfig/tinydns
Start tinydns service
chmod 755 /etc/sysconfig/tinydns
service tinydns start
chkconfig tinydns on
Test dns server: ask it for some type of records
dnsq soa example.hu 123.123.123.123
dnsq a example.hu 123.123.123.123

axfrdns

Create axfrdns user
useradd --no-create-home -s /bin/false -u 205 -g 200 axfrlog
Install axfrdns
axfrdns-conf axfrdns axfrlog /etc/axfrdns /etc/tinydns 123.123.123.123
Allow a cleint to tranfser zone
cd /etc/axfrdns
cat >>tcp <<EOF
123.123.123.123:allow,AXFR="example.hu"
EOF
make
Create init script
cat >/etc/init.d/axfrdns <<-EOF
#!/bin/bash
#
# axfrdns      DNS zone transfer server
#
# chkconfig: 345 11 89
# Provides: axfrdns
# Required-Start: \$network
# Required-Stop: \$network
# Short-Description: start and stop axfrdns
# Description: Dan Bernstein (DJB) dns zone transfer server
# ZsZs
 
# Source function library.
. /etc/rc.d/init.d/functions
 
prog=axfrdns
progdir=/usr/local/bin
 
# pull in sysconfig settings
[ -f /etc/sysconfig/axfrdns ] && . /etc/sysconfig/axfrdns
 
start(){
    echo -n \$"Starting \$prog: "
    pid=\$(pidof \$progdir/tcpserver \$progdir/\$prog)
    if [[ "\$pid" == "" ]]; then
        # Read up axfrdns environment files and export them
        for env in \$(cd \$axfrdnsdir/env/; ls -1); do envs="\$envs \$env=\$(cat \$axfrdnsdir/env/\$env)"; done
        export \$envs
        \$progdir/envuidgid axfrlog \$progdir/softlimit -d300000 \$progdir/tcpserver -vDRHl0 -x \$axfrdnsdir/tcp.cdb -- "\$IP" 53 \
          \$progdir/\$prog 2>&1 | (\$progdir/setuidgid axfrlog /usr/bin/logger -p local4.info -t \$prog) &
        if [[ "\$?" == "0" ]]
        then
            success
            echo
        else
            failure \$"\$prog start"
            echo
            exit 1
        fi
    else
        failure \$"\$prog start"
        echo
        exit 1
    fi
}
 
stop(){
    pid=\$(pidof \$progdir/tcpserver \$progdir/\$prog)
    if [[ "\$pid" == "" ]]
    then
        echo -n "Stopping  \$prog: "
        failure \$"\$prog not running."
        echo
    else
        echo -n "Stopping \$prog: "
        kill \$pid && success || failure \$"\$prog stop"
        echo
    fi
}
 
# See how we were called.
case "\$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        sleep 1
        start
        ;;
    *)
        echo "Usage: \$prog {start|stop|restart}"
        exit 1
esac
 
exit 0
EOF
Create axfrdns config file
echo "axfrdnsdir=/etc/axfrdns" >/etc/sysconfig/axfrdns
Start axfrdns service
chmod 755 /etc/init.d/axfrdns
service axfrdns start
chkconfig axfrdns on
Test axfrdns server
tcpclient 123.123.123.123 53 axfr-get example.hu aa aa.tmp
cat aa
#1352995218 auto axfr-get
Zexample.hu:0.ns.example.hu.:hostmaster.example.hu.:1352995218:16384:2048:1048576:2560:2560
&example.hu::0.ns.example.hu.:259200
+0.ns.example.hu:123.123.123.123:259200
+garfield.example.hu:123.123.123.123:86400
@example.hu::a.mx.example.hu.:0:86400
+a.mx.example.hu:123.123.123.123:86400
+www.example.hu:123.123.123.123:86400

syslog-ng

Relevant lines of syslog-ng.conf to collect logs in sepatare log files:
destination df_djb { file("/var/log/$YEAR/$MONTH/$DAY/djb_$PROGRAM.$YEAR$MONTH$DAY.log" ); };
filter f_djb { facility(local4); };
log { source(s_sys); filter(f_djb); destination(df_djb); };

Thanks to http://www.koelzer.us/~thomas/postfix-CentOS6.html

Comments are welcome!