Bind
From GarrettHoneycutt
Contents |
puppet
classes
# # # BIND # # class bind { include generic $bindBasePath = "/var/named/chroot/" package { "bind": ensure => installed; "bind-chroot": ensure => installed, require => Package["bind"]; "bind-utils": ensure => installed, require => Package["bind"]; } file { "/etc/named.conf": ensure => link, target => "${bindBasePath}etc/named.conf"; "${bindBasePath}etc/named.conf": require => Package["bind-chroot"], notify => Service["named"]; } service { "named" : ensure => running, enable => true, require => [ Package["bind-chroot"], File["/etc/named.conf"] ], } } # Caching nameserver class bind::cache inherits bind { package { "caching-nameserver": } # $named_listen_ips and $named_allowed_nets defined in site.pp File["${bindBasePath}etc/named.conf"] { content => template("bind/named.caching-nameserver.erb"), } # our updated hints file that includes nsrepo1 file { "${bindBasePath}var/named/named.root": source => "puppet:///bind/named.root", notify => Service["named"], require => [ Package["bind-chroot"], Package["caching-nameserver"] ], group => "named", mode => "640"; } } # Caching nameserver that forwards to a recursive nameserver class bind::forwarder inherits bind::cache { File [ "${bindBasePath}etc/named.conf" ] { content => template("bind/named.forwarding-nameserver.erb"), } } # Authoritative NS - Master specific class bind::master inherits bind { include generic include pam include ssh include svn pam::accesslogin {"dnsreposvn":} realize Generic::Mkuser[dnsreposvn] ssh::private_key { "dnsreposvn": user => "dnsreposvn", require => Generic::Mkuser[dnsreposvn], } ssh::authorized_keys { "dnsreposvn": users => [ "dnsreposvn-dnsmaster" ], require => Generic::Mkuser[dnsreposvn], } svn::checkout { "dns $dns_branch": reposerver => "puppetrepo.garretthoneycutt.com", method => "https", repopath => "dns", workingdir => "/var/named/chroot/var/named/zones", branch => "$dns_branch", remoteuser => "dnsreposvn", localuser => "dnsreposvn", require => Ssh::Private_key["dnsreposvn"], } # directory for reverse zones, not included in the RH bind layout File["${bindBasePath}etc/named.conf"] { content => template("bind/named.authoritative-only-master.erb"), } } # # Authoritative NS - Slave specific # class bind::slave inherits bind { # bind_master_ips and named_listen_ips are defined in site.pp File["${bindBasePath}etc/named.conf"] { content => template("bind/named.authoritative-only-slave.erb"), notify => Service["named"], } } # dns repository class bind::repo { include apache::ssl include pam include generic include ssh include svn::repo package { "bind": } svn::server::setup { "dns": base => "/opt/svn/", } realize Apache::Ssl::Set_cert["default"] apache::vhost { "dnsrepo": content => template("bind/dnsrepo.conf.erb"), } realize Generic::Mkuser[dnsreposvn] file {"/opt/bin/dns-svn-push": source => "puppet:///bind/dns-svn-push", mode => "750", } # setup private key for post-commit ssh::private_key { "dnsreposvn": user => "dnsreposvn", require => Generic::Mkuser[dnsreposvn] } # setup authorized key for post-commit ssh::authorized_keys { "dnsreposvn": users => [ "dnsreposvn-dnsrepo" ], require => Generic::Mkuser[dnsreposvn] } pam::accesslogin { "dnsreposvn": } }
templates
dnsrepo.conf.erb
# SVN
DocumentRoot /var/www/html
<Directory /opt/svn/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
<Location /dns>
DAV svn
SVNPath /opt/svn/dns
SVNListParentPath on
AuthType Basic
AuthName "DNS Repository"
AuthBasicProvider ldap
AuthLDAPURL "ldap://ldap.garretthoneycutt.com/dc=garretthoneycutt,dc=com?uid" TLS
AuthLDAPGroupAttributeIsDN off
AuthLDAPGroupAttribute memberUid
<LimitExcept GET PROPFIND OPTIONS REPORT>
require ldap-group cn=dnsadmins,ou=Groups,dc=garretthoneycutt,dc=com
</LimitExcept>
</Location>scripts
Some simple bash scripts to aid in auditing DNS and ensuring its integrity
ping_zone.sh
#!/bin/bash # # ping ip's in a zone file and return ip's that answer # # usage: ./ping_zone.sh <zone file> <ip range> # # example: ./ping_zone.sh foo.zone 10.111 # # returns 0 on sucess and non-zero on failure # # garrett honeycutt - gh@garretthoneycutt.com - 2009 - released under ISC # # ensure arguments are passed if [ $# -lt 2 ]; then echo "Usage: $0 <zone file> <ip range>" exit 1 fi # ensure that zone file exists if [ ! -r $1 ]; then echo "Fail: $1 is not a readable file." exit 1 fi for ip in $(/bin/grep $2 $1 | /usr/bin/awk '{print $4}' | /bin/sort -u) do /bin/ping -c 1 $ip 1>/dev/null if [ $? -eq 0 ]; then echo $ip fi done exit 0
check_zone.sh
#!/bin/bash # # purpose: checks the validity of a zone file using bind's named-checkzone # # usage: ./check_zone <filename.zone> # # return: 0 on success and non zero on error # # example: for zone in $(/usr/bin/find . -type f -name \*.zone | /usr/bin/awk -F ^./ '{print $2}'); do ./check_zone.sh $zone; done # # garrett honeycutt - gh@garretthoneycutt.com - 2009 - released under ISC # NCZ='/usr/sbin/named-checkzone' # ensure argument is passed if [ $# -lt 1 ]; then echo "Usage: $0 <filename.zone>" exit 1 fi # ensure that zone file exists if [ ! -r $1 ]; then echo "Fail: $1 is not a readable file." exit 1 fi # ensure that named-checkzone is executable if [ ! -x $NCZ ]; then echo "Fail: $NCZ is not executable." exit 1 fi # determine if we are using a reverse echo $1 | /bin/grep '[0-9]\{1,3\}\.[0-9]\{1,3\}\.zone$' 1>/dev/null # if its a reverse if [ $? -ne 1 ]; then # strip rev/ if it begins with that echo $1 | /bin/grep ^'rev' 1>/dev/null if [ $? -eq 0 ]; then oc1=$(echo $1 | /usr/bin/awk -F ^rev/ '{print $2}' | /usr/bin/awk -F . '{print $1}') oc2=$(echo $1 | /usr/bin/awk -F ^rev/ '{print $2}' | /usr/bin/awk -F . '{print $2}') else oc1=$(echo $1 | /usr/bin/awk -F . '{print $1}') oc2=$(echo $1 | /usr/bin/awk -F . '{print $2}') fi zone=$(echo $oc2.$oc1.IN-ADDR.ARPA) # if it is a fwd else zone=$(echo $1 | /usr/bin/awk -F .zone '{print $1}') fi # check zone OUTPUT=$($NCZ -f text $zone $1) # throw an error if the zone is bad if [ $? -ne 0 ]; then echo "Fail: $OUTPUT" exit 1 fi exit 0
check_for_reverse.sh
#!/bin/bash # # usage: ./check_for_reverse.sh <fwd zone file> # # returns 0 on success, non zero on failure # # examples: # # for zone in $(ls *.zone); do ./check_for_reverse.sh $zone | grep ^== ; done # # for ip in $(for zone in $(ls *.zone); do ./check_for_reverse.sh $zone | grep ^== ; done | awk '{print $5}'); do grep $ip *.zone | grep -v ^\; ; done # # garrett honeycutt - gh@garretthoneycutt.com - 2009 - released under ISC # # ensure argument is passed if [ $# -lt 1 ]; then echo "Usage: $0 <fwd zone file>" exit 1 fi # ensure that zone file exists if [ ! -r $1 ]; then echo "Fail: $1 is not a readable file." exit 1 fi # do a reverse lookup on all the ip's listed for ip in $(grep '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' $1 | /bin/grep -v ^\; | /usr/bin/awk '{print $4}' | /bin/sort -u) do /usr/bin/dig -x $ip 2>/dev/null | /bin/grep -ve ^$ -e ^\; | grep PTR # if the return is non zero, then reverse is not setup if [ $? -ne 0 ]; then echo "============== NO REVERSE for $ip ==============" fi done exit 0