#!/bin/bash # $HeadURL: https://svn.pasta.freemyip.com/main/miniade/trunk/bin/nop-sh $ $LastChangedRevision: 10133 $ # Modules . $(miniade) || { echo "${0##*/}: ERROR: miniade failed (hint: run 'miniade' to see error)" >&2; exit 1; } # Configurable stuff ZONES="$(ls /etc/bind | sed -n 's/^db\.//p' | fgrep -vx -e 0 -e 127 -e 255 -e empty -e local -e rpz-remote | paste -s -d' ')" FREEZE=false # Other globals main() { local MY_ARGS local PROGNAME # Defaults for options # Process options miniade_process_options --help-handler=help MY_ARGS "$@" && set -- "${MY_ARGS[@]}" # Process arguments [ $# = 0 ] || miniade_bad_usage # Sanity checks and derivations miniade_get_progname PROGNAME [ -f $HOME/.${PROGNAME}rc ] || touch $HOME/.${PROGNAME}rc bash -c ". $HOME/.${PROGNAME}rc" || miniade_error "~/.${PROGNAME}rc: not loadable (hint: does it contain a bash syntax error?)" ZONES=() FREEZE= . $HOME/.${PROGNAME}rc [ ${#ZONES[*]} -gt 0 ] || miniade_error "ZONES: unset or empty (hint: set ZONES=( ... ) in ~/.${PROGNAME}rc)" for WANTED_ZONE in rpz-local rpz-remote; do FOUND=false for ZONE in "${ZONES[@]}"; do if [ "X$WANTED_ZONE" = "X$ZONE" ]; then FOUND=true break fi done $FOUND || miniade_error "$WANTED_ZONE: not in zone list (hint: add '$WANTED_ZONE' to ZONES in ~/.${PROGNAME}rc)" done [[ $FREEZE =~ ^(true|false)$ ]] || miniade_error "FREEZE: unset or invalid (hint: set FREEZE=true or FREEZE=false in ~/.${PROGNAME}rc)" { ! $FREEZE; } || miniade_error "freezing is currently not support (hint: set FREEZE=false in ~/.${PROGNAME}rc)" # Guts INIT_NAMED_CONF_LOCAL_FLAG=false for ZONE in "${ZONES[@]}"; do if [ ! -f /etc/bind/db.$ZONE ]; then miniade_warning "db.$ZONE: does not exist; initialising ..." init_zone $ZONE INIT_NAMED_CONF_LOCAL_FLAG=true fi done if $INIT_NAMED_CONF_LOCAL_FLAG; then miniade_warning "named.conf.local: initialsing ..." init_named_conf_local fi { ! $FREEZE; } || freeze_or_thaw freeze miniade_debug 10 "main: making backup for comparison purposes ..." for ZONE in "${ZONES[@]}"; do cp /etc/bind/db.$ZONE /tmp/ done miniade_debug 10 "main: editing ..." for ZONE in "${ZONES[@]}"; do ${EDITOR:-vi} /tmp/db.$ZONE done miniade_debug 10 "main: checking for modifications ..." SAME_FLAG=true for ZONE in "${ZONES[@]}"; do cmp -s /etc/bind/db.$ZONE /tmp/db.$ZONE || { SAME_FLAG=false; break; } done if $SAME_FLAG; then miniade_info "no changes made" { ! $FREEZE; } || freeze_or_thaw thaw return 0 fi miniade_debug 10 "main: copying modified temporary copies back ..." for ZONE in "${ZONES[@]}"; do cat /tmp/db.$ZONE > /etc/bind/db.$ZONE done miniade_debug 10 "main: bumping serial number ..." TS=$(date +%s) for ZONE in "${ZONES[@]}"; do perl -0777 -pi -e "s/^(\\S+\\s+IN\\s+SOA\\s+\\S+\\s+\\S+\\s+\\(\\s+)(\\d+)\\b/\${1}$TS/ms" /etc/bind/db.$ZONE done echo "restarting ..." service bind9 restart { ! $FREEZE; } || freeze_or_thaw thaw # Purge nscd's cache nscd -i hosts } freeze_or_thaw() { miniade_info "${1%e}ing ..." for ZONE in "${ZONES[@]}"; do if [[ $ZONE =~ ^[0-9] ]]; then ZONE_SUFFIX=.in-addr.arpa else ZONE_SUFFIX= fi rndc $1 $ZONE$ZONE_SUFFIX done } init_zone() { local ZONE ZONE_SUFFIX ZONE=$1 if [[ $ZONE =~ ^[0-9] ]]; then ZONE_SUFFIX=.in-addr.arpa else ZONE_SUFFIX= fi p() { printf "%-38s IN %-5s %s\\n" "$1" "$2" "$3"; } { echo "; Define what gets appended to unqualified things on the left. '@' is an alias for this too." echo "\$ORIGIN $ZONE$ZONE_SUFFIX." echo "; Records may specify a TTL but we define a default." echo "\$TTL 1h" echo p @ SOA "ns.$(dnsdomainname). root.$(dnsdomainname). ( $(date +%s) 1d 2h 4w 1h )" p @ NS "$(hostname -f)." } > /etc/bind/db.$ZONE } init_named_conf_local() { local ZONE ZONE_SUFFIX for ZONE in "${ZONES[@]}"; do if [[ $ZONE =~ ^[0-9] ]]; then ZONE_SUFFIX=.in-addr.arpa else ZONE_SUFFIX= fi echo -e "zone \"$ZONE$ZONE_SUFFIX\" {" echo -e "\\ttype master;" echo -e "\\tfile \"/etc/bind/db.$ZONE\";" echo -e "};" echo done > /etc/bind/named.conf.local } main "$@"