From 2124a5bbffecfeb62b210888cf7419e0c2d79b41 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 1 Aug 2017 01:29:48 +0200 Subject: [PATCH] - Add configuration directory for scripts. - Add sample configuratin file 'bind.conf.sample'. - Redisign script 'bind_change_SOA.sh'. - Add script 'bind_remove_domain.sh'. --- .gitignore | 2 + bind_change_SOA.sh | 539 ++++++++++++++++++++++++++++++++---- bind_remove_domain.sh | 623 ++++++++++++++++++++++++++++++++++++++++++ conf/bind.conf.sample | 58 ++++ 4 files changed, 1166 insertions(+), 56 deletions(-) create mode 100755 bind_remove_domain.sh create mode 100644 conf/bind.conf.sample diff --git a/.gitignore b/.gitignore index a149b6f..d261c88 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ +*.swp +conf/*.conf /BAK/* diff --git a/bind_change_SOA.sh b/bind_change_SOA.sh index e3f6edf..939faae 100755 --- a/bind_change_SOA.sh +++ b/bind_change_SOA.sh @@ -1,88 +1,502 @@ #!/usr/bin/env bash -#_zone_files_dir="/etc/bind/master" -_zone_files_dir=/root/tmp/master +working_dir="$(dirname $(realpath $0))" +conf_file="${working_dir}/conf/bind.conf" -## - Settings SOA Record -## - -_soa_nameserver="a\.ns\.oopen\.de" -_soa_admin="domreg\.oopen\.de" +log_file="$(mktemp)" +backup_date="$(date +%Y-%m-%d-%H%M)" -cp -a $_zone_files_dir ${_zone_files_dir}.BAK-`date +%Y-%m-%d-%H%M` -## --- some functions -## --- +#--------------------------------------- +#----------------------------- +# Base Function(s) +#----------------------------- +#--------------------------------------- + +usage() { + echo + [ -n "$1" ] && echo -e "Error: $1\n" + + cat< /tmp/shprompt$$ - if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then - echo -e -n "$*\\c" 1>&2 - else - echo -e -n "$*" 1>&2 + if $terminal && $LOGGING ; then + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ fi - rm /tmp/shprompt$$ } fatal(){ echo "" - echo -e "[ \033[31m\033[1mError\033[m ]: $*" + if $terminal ; then + echo -e "[ \033[31m\033[1mError\033[m ]: $*" + echo "" + echo -e "\t\033[31m\033[1mScript was interupted\033[m!" + else + echo " [ Fatal ]: $*" + echo "" + echo " Script was terminated...." + fi echo "" - echo -e "\t\033[31m\033[1mInstalllation wird abgebrochen\033[m\033[m" - echo "" - exit 1 + clean_up 1 +} + +info (){ + if $terminal && $LOGGING ; then + echo "" + echo -e "\t[ \033[32m\033[1mInfo\033[m ]: $*" + echo "" + else + if $LOGGING ; then + echo "" + echo "Info: $*" + echo "" + fi + fi } warn (){ echo "" - echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*" + if $terminal ; then + echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*" + else + echo "Warning: $*" + fi echo "" } +error (){ + echo "" + if $terminal ; then + echo -e "\t[ \033[31m\033[1mError\033[m ]: $*" + else + echo "Error: $*" + fi + echo "" +} + +echo_done() { + if $terminal && $LOGGING ; then + echo -e "\033[75G[ \033[32mdone\033[m ]" + else + if $LOGGING ; then + echo " [ done ]" + fi + fi +} echo_ok() { - echo -e "\033[75G[ \033[32mok\033[m ]" + if $terminal && $LOGGING ; then + echo -e "\033[75G[ \033[32mok\033[m ]" + else + if $LOGGING ; then + echo " [ ok ]" + fi + fi } echo_failed(){ - echo -e "\033[75G[ \033[1;31mfailed\033[m ]" + if $terminal && $LOGGING ; then + echo -e "\033[75G[ \033[1;31mfailed\033[m ]" + else + if $LOGGING ; then + echo " [ failed ]" + fi + fi } echo_skipped() { - echo -e "\033[75G[ \033[33m\033[1mskipped\033[m ]" + if $terminal && $LOGGING ; then + echo -e "\033[75G[ \033[33m\033[1mskipped\033[m ]" + else + if $LOGGING ; then + echo " [ skipped ]" + fi + fi } -## --- -## --- END: functions + +trap clean_up SIGHUP SIGINT SIGTERM -echo "" -echo "" -echo -e "\033[32m--\033[m" -echo "" -echo "" +#--------------------------------------- +#----------------------------- +# Check some prerequisites +#----------------------------- +#--------------------------------------- -## - Read list of zonefiles -## - -while IFS='' read -r -d '' zone_file ; do +if [[ -t 1 ]] ; then + terminal=true + LOGGING=true +else + terminal=false + LOGGING=false +fi + +while getopts hq opt ; do + case $opt in + q) LOGGING=false + ;; + h) usage + ;; + *) usage + esac +done + + + +#--------------------------------------- +#----------------------------- +# Setting Defaults +#----------------------------- +#--------------------------------------- + +DEFAULT_CONF_FILE_DIR="/etc/bind" + + + +#--------------------------------------- +#----------------------------- +# Load default values from bind.conf +# +# Overwrites the settings above +# +#----------------------------- +#--------------------------------------- + +if $LOGGING ; then + clear + echo "" + echo "" + echononl " Loading default Configuration values from $(basename ${conf_file}).." + if [[ ! -f "$conf_file" ]]; then + echo_skipped + else + source "${conf_file}" > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + fatal "$(cat $log_file)" + fi + fi + + echo "" + + + [[ -n "$CONF_FILE_DIR" ]] && DEFAULT_CONF_FILE_DIR="$CONF_FILE_DIR" + if [[ -n "$ZONE_FILE_MASTER_DIR" ]] ; then + DEFAULT_ZONE_FILE_MASTER_DIR="$ZONE_FILE_MASTER_DIR" + else + DEFAULT_ZONE_FILE_MASTER_DIR="${DEFAULT_CONF_FILE_DIR}/master" + fi + if [[ -n "$ZONE_FILE_SLAVE_DIR" ]] ; then + DEFAULT_ZONE_FILE_SLAVE_DIR="$ZONE_FILE_SLAVE_DIR" + else + DEFAULT_ZONE_FILE_SLAVE_DIR="${DEFAULT_CONF_FILE_DIR}/slave" + fi + [[ -n "$ZONES_DECLARATION_FILE" ]] && DEFAULT_ZONES_DECLARATION_FILE="$ZONES_DECLARATION_FILE" + + [[ -n "$SOA_PRIMARY_MASTER" ]] && DEFAULT_SOA_PRIMARY_MASTER=$SOA_PRIMARY_MASTER + [[ -n "$SOA_ADMIN_EMAIL" ]] && DEFAULT_SOA_ADMIN_EMAIL=$SOA_ADMIN_EMAIL + + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Insert SOA primary master for all the zones." + echo "" + SOA_PRIMARY_MASTER="" + + if [[ -n "$DEFAULT_SOA_PRIMARY_MASTER" ]]; then + echononl "Primary Master (SOA-Record) [${DEFAULT_SOA_PRIMARY_MASTER}]" + read SOA_PRIMARY_MASTER + if [[ "X${SOA_PRIMARY_MASTER}" = "X" ]]; then + SOA_PRIMARY_MASTER="$DEFAULT_SOA_PRIMARY_MASTER" + fi + else + echononl "Primary Master (SOA-Record): " + read SOA_PRIMARY_MASTER + while [ "X$SOA_PRIMARY_MASTER" = "X" ] ; do + echo -e "\n\t\033[33m\033[1mSetting 'Primary Master' is required!\033[m\n" + echononl "Primary Master (SOA-Record): " + read SOA_PRIMARY_MASTER + done + fi + + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Insert SOA admin e-mail address for all the zones." + echo "" + SOA_ADMIN_EMAIL="" + + if [[ -n "$DEFAULT_SOA_ADMIN_EMAIL" ]]; then + echononl "Admin E-Mail Address (SOA-Record) [${DEFAULT_SOA_ADMIN_EMAIL}]" + read SOA_ADMIN_EMAIL + if [[ "X${SOA_ADMIN_EMAIL}" = "X" ]]; then + SOA_ADMIN_EMAIL="$DEFAULT_SOA_ADMIN_EMAIL" + fi + else + echononl "Admin E-Mail Address (SOA-Record): " + read SOA_ADMIN_EMAIL + while [ "X$SOA_ADMIN_EMAIL" = "X" ] ; do + echo -e "\n\t\033[33m\033[1mSetting 'Admin E-Mail Address' is required!\033[m\n" + echononl "Admin E-Mail Address (SOA-Record): " + read SOA_ADMIN_EMAIL + done + fi + + + echo "" + echo "" + echo -e "\033[32m--\033[m" + echo "Common parameters" + echo -e "\033[32m--\033[m" + + + echo "" + echo "Insert directory containing the bind configuration files." + echo "" + CONF_FILE_DIR="" + if [[ -n "$DEFAULT_CONF_FILE_DIR" ]] ; then + echononl "Bind Configuration Directory [${DEFAULT_CONF_FILE_DIR}]: " + read CONF_FILE_DIR + if [[ "X$CONF_FILE_DIR" = "X" ]]; then + CONF_FILE_DIR="$DEFAULT_CONF_FILE_DIR" + fi + else + echononl "Bind Configuration Directory: " + read CONF_FILE_DIR + while [ "X$CONF_FILE_DIR" = "X" ] ; do + echo -e "\n\t\033[33m\033[1mSetting 'Bind Configuration Directory' is required!\033[m\n" + echononl "Bind Configuration Directory: " + read CONF_FILE_DIR + done + fi + + [[ -n "$ZONES_DECLARATION_FILE" ]] || DEFAULT_ZONES_DECLARATION_FILE="${CONF_FILE_DIR}/named.conf.local" + [[ -n "$ZONE_FILE_MASTER_DIR" ]] || ZONE_FILE_MASTER_DIR="${CONF_FILE_DIR}/master" + + + echo "" + echo -e "\033[32m--\033[m" + + echo "" + echo "Insert zones declaration file." + echo "" + ZONES_DECLARATION_FILE="" + if [[ -n "$DEFAULT_ZONES_DECLARATION_FILE" ]] ; then + echononl "Zones Declaration File [${DEFAULT_ZONES_DECLARATION_FILE}]: " + read ZONES_DECLARATION_FILE + if [[ "X$ZONES_DECLARATION_FILE" = "X" ]]; then + ZONES_DECLARATION_FILE="$DEFAULT_ZONES_DECLARATION_FILE" + fi + else + echononl "Zones Declaration File: " + read ZONES_DECLARATION_FILE + while [ "X$ZONES_DECLARATION_FILE" = "X" ] ; do + echo -e "\n\t\033[33m\033[1mSetting 'Zones Declaration File' is required!\033[m\n" + echononl "Zones Declaration File: " + read ZONES_DECLARATION_FILE + done + fi + + # - replace '@' character with '.' + # - + SOA_ADMIN_EMAIL="${SOA_ADMIN_EMAIL/@/.}" + + echo "" + echo "" + echo -e "\033[1;32mSettings for \033[1;37mChange SOA Record\033[m Script" + echo "" + echo -e "\tSOA Primary Master..................: $SOA_PRIMARY_MASTER" + echo -e "\tSOA Admin E-Mail Address............: $SOA_ADMIN_EMAIL" + echo "" + echo -e "\tBind Configuration Directory........: $CONF_FILE_DIR" + echo -e "\tZones Declaration File..............: $ZONES_DECLARATION_FILE" + + echo "" + info "Repace Primary Master \033[37m\033[1m${SOA_PRIMARY_MASTER}\033[m and Admin E-Mail \033[37m\033[1m${SOA_PRIMARY_MASTER}\033[m in all SOA Records" + echo -n "To continue type uppercase 'YES': " + read OK + echo "" + if [[ "$OK" != "YES" ]] ; then + fatal "Abort by user request - Answer as not 'YES'" + fi + +else # if $LOGGING + + if [[ ! -f "$conf_file" ]]; then + fatal "Configuration file '$conf_file' not found!" + else + echononl " Loading default Configuration values from $(basename ${conf_file}).." + source "${conf_file}" > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + fatal "$(cat $log_file)" + fi + fi + + if [[ -z "$CONF_FILE_DIR" ]]; then + CONF_FILE_DIR="$DEFAULT_CONF_FILE_DIR" + fi + if [[ ! -d "$CONF_FILE_DIR" ]] ; then + fatal "Directory contaning bind configurations not found (see CONF_FILE_DIR)!" + fi + + [[ -n "${ZONE_FILE_MASTER_DIR}" ]] || ZONE_FILE_MASTER_DIR="${CONF_FILE_DIR}/master" + + if [[ -z "$ZONES_DECLARATION_FILE" ]] ; then + ZONES_DECLARATION_FILE="${CONF_FILE_DIR}/named.conf.local" + fi + + [[ -z "$SOA_ADMIN_EMAIL" ]] && fatal "Missing SOA Admin E-Mail Address (see SOA_ADMIN_EMAIL)" + [[ -z "$SOA_PRIMARY_MASTER" ]] && fatal "Missing SOA Primary Master (see SOA_PRIMARY_MASTER)" + + # - replace '@' character with '.' + # - + SOA_ADMIN_EMAIL="${SOA_ADMIN_EMAIL/@/.}" + +fi + +if [[ ! -f "$ZONES_DECLARATION_FILE" ]]; then + fatal "Zone declaration file '${ZONES_DECLARATION_FILE}' not found!" +fi + +declare -a zone_file_arr=() + +_found=false +_is_master=false +zone_file="" +regex_master="type[[:space:]]+master" +regex_file="^[[:space:]]*file" +while IFS='' read -r _line || [[ -n $_line ]] ; do + + if [[ $_line =~ ^[[:space:]]*zone[[:space:]]+ ]]; then + _found=true + zone="$(echo $_line | awk '{print$2}')" + shopt -s extglob + if [[ $zone =~ \; ]]; then + zone=${zone%%*(\;)} + fi + if [[ $zone =~ ^\" ]]; then + zone=${zone##*(\")} + zone=${zone%%*(\")} + fi + shopt -u extglob + fi + if $_found ; then + if [[ $_line =~ $regex_file ]]; then + zone_file=$(echo $_line | awk '{print$2}') + shopt -s extglob + if [[ $zone_file =~ \; ]]; then + zone_file=${zone_file%%*(\;)} + fi + if [[ $zone_file =~ ^\" ]]; then + zone_file=${zone_file##*(\")} + zone_file=${zone_file%%*(\")} + fi + shopt -u extglob + fi + if [[ $_line =~ $regex_master ]]; then + _is_master=true + fi + if [[ "$_line" =~ ^[[:space:]]*\}[[:space:]]*\; ]]; then + if $_is_master && [[ -n "$zone_file" ]]; then + zone_file_arr+=("${zone_file}:$zone") + fi + _is_master=false + _found=false + zone_file="" + fi + fi +done < "$ZONES_DECLARATION_FILE" + +echononl "\tBackup directory '${ZONE_FILE_MASTER_DIR}'.." +cp -a "${ZONE_FILE_MASTER_DIR}" "${ZONE_FILE_MASTER_DIR}.${backup_date}" > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + fatal "$(cat $log_file)" +fi + + +for _val in "${zone_file_arr[@]}" ; do + + IFS=':' read -a _val_arr <<< "${_val}" declare -i _serial_new=`date +%Y%m%d01` - filename=$(basename "$zone_file") - zone="${filename%.*}" + zone_file="${_val_arr[0]}" + zone="${_val_arr[1]}" - echo "" - echo -e "\tlooking at $zone_file.." + if $LOGGING ; then + echo "" + echo -e "\tPreparing zone file \033[37m\033[1m${zone_file}\033[m" + fi ## - calculate new serial ## - - declare -i __serial=`grep -e "[0-9]\{10\}" $zone_file | grep serial | awk '{print$1}'` - while [ ! $_serial_new -gt $__serial ]; do + echononl "\tCalculate new serial.." + declare -i __serial=$(grep -E "^\s*[0-9]{10}\s+;?(serial)?" $zone_file | awk '{print$1}') + if [[ -z "$__serial" ]]; then + echo_failed + continue + fi + while [[ ! $_serial_new -gt $__serial ]]; do let _serial_new++ done + if [[ $? -gt 0 ]]; then + echo_failed + else + echo_ok + fi - echononl "\t Changing SOA Record.." - if ! grep -E "^.*IN\s+SOA\s+${_soa_nameserver}\.\s+${_soa_admin}\.\s+\(" > /dev/null 2>&1 $zone_file ; then - perl -i -n -p -e "s/^(.*IN\s+SOA).*$/\1 ${_soa_nameserver}. ${_soa_admin}. \(/" $zone_file - if [ "$?" = "0" ]; then - echo_ok - else + echononl "\tChanging SOA Record.." + if ! $(grep -q -E "^.*IN\s+SOA\s+${SOA_PRIMARY_MASTER}\.\s+${SOA_ADMIN_EMAIL}\.\s+\(" $zone_file) ; then + perl -i -n -p -e "s/^(.*IN\s+SOA).*$/\1 ${SOA_PRIMARY_MASTER}. ${SOA_ADMIN_EMAIL}. \(/" $zone_file + if [[ $? -gt 0 ]]; then echo_failed + else + echo_ok fi else echo_skipped @@ -91,27 +505,40 @@ while IFS='' read -r -d '' zone_file ; do ## - Set new serial ## - - echononl "\t Renew serial.." + echononl "\tRenew serial.." perl -i -n -p -e "s#^(\s*) $__serial(.*)#\1 $_serial_new\2#" $zone_file - if [ "$?" = "0" ]; then - echo_ok - else + if [[ $? -gt 0 ]]; then echo_failed + else + echo_ok fi ## - Reload Zone ## - - echononl "\t Reload Zone $zone.." + echononl "\tReload Zone ${zone}.." /usr/sbin/rndc reload $zone > /dev/null 2>&1 - if [ "$?" = "0" ]; then - echo_ok - else + if [[ $? -gt 0 ]]; then echo_failed + else + echo_ok fi sleep 1 +done -done < <(find $_zone_files_dir -mindepth 1 -maxdepth 1 -type f -print0) +if [[ -d "${ZONE_FILE_MASTER_DIR}.${backup_date}" ]] ; then + diff -Nur "${ZONE_FILE_MASTER_DIR}" "${ZONE_FILE_MASTER_DIR}.${backup_date}" > /dev/null 2>&1 + if [[ $? -eq 0 ]]; then + info "No zone file has changed.\n\t Removing previously created backup" + echononl "\tDelete '${ZONE_FILE_MASTER_DIR}.${backup_date}'.." + rm -rf "${ZONE_FILE_MASTER_DIR}.${backup_date}" > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + fi + fi +fi -echo "" -exit +$LOGGING && echo "" +clean_up 0 diff --git a/bind_remove_domain.sh b/bind_remove_domain.sh new file mode 100755 index 0000000..ad41b53 --- /dev/null +++ b/bind_remove_domain.sh @@ -0,0 +1,623 @@ +#!/usr/bin/env bash + +working_dir="$(dirname $(realpath $0))" +conf_file="${working_dir}/conf/bind.conf" + +log_file="$(mktemp)" + +#--------------------------------------- +#----------------------------- +# Base Function(s) +#----------------------------- +#--------------------------------------- + +usage() { + echo + [ -n "$1" ] && echo -e "Error: $1\n" + + cat< + The name of the domain, which is requested for deletion. + + -h + Prints this help. + + -q + Be quiet. If '-q' is used, also a domain must be given using + parameter '-d'. + +EOF +clean_up 1 +} + + +clean_up() { + + # Perform program exit housekeeping + rm $log_file + exit $1 +} + +trim() { + local var="$*" + var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters + var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters + echo -n "$var" +} + +echononl(){ + if $terminal && $LOGGING ; then + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ + fi +} + +fatal(){ + echo "" + if $terminal ; then + echo -e "[ \033[31m\033[1mError\033[m ]: $*" + echo "" + echo -e "\t\033[31m\033[1mScript was interupted\033[m!" + else + echo " [ Fatal ]: $*" + echo "" + echo " Script was terminated...." + fi + echo "" + clean_up 1 +} + +info (){ + echo "" + if $terminal && $LOGGING ; then + echo -e "\t[ \033[32m\033[1mInfo\033[m ]: $*" + else + if $LOGGING ; then + echo "Info: $*" + fi + fi + echo "" +} + +warn (){ + echo "" + if $terminal ; then + echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*" + else + echo "Warning: $*" + fi + echo "" +} + +error (){ + echo "" + if $terminal ; then + echo -e "\t[ \033[31m\033[1mError\033[m ]: $*" + else + echo "Error: $*" + fi + echo "" +} + +echo_done() { + if $terminal && $LOGGING ; then + echo -e "\033[75G[ \033[32mdone\033[m ]" + else + if $LOGGING ; then + echo " [ done ]" + fi + fi +} +echo_ok() { + if $terminal && $LOGGING ; then + echo -e "\033[75G[ \033[32mok\033[m ]" + else + if $LOGGING ; then + echo " [ ok ]" + fi + fi +} +echo_failed(){ + if $terminal && $LOGGING ; then + echo -e "\033[75G[ \033[1;31mfailed\033[m ]" + else + if $LOGGING ; then + echo " [ failed ]" + fi + fi +} +echo_skipped() { + if $terminal && $LOGGING ; then + echo -e "\033[75G[ \033[33m\033[1mskipped\033[m ]" + else + if $LOGGING ; then + echo " [ skipped ]" + fi + fi +} + +trap clean_up SIGHUP SIGINT SIGTERM + + + +#--------------------------------------- +#----------------------------- +# Check some prerequisites +#----------------------------- +#--------------------------------------- + +if [[ -t 1 ]] ; then + terminal=true + LOGGING=true +else + terminal=false + LOGGING=false +fi + +while getopts d:hq opt ; do + case $opt in + d) DOMAIN_REQUESTED_TO_REMOVE="$OPTARG" + ;; + q) LOGGING=false + ;; + h) usage + ;; + *) usage + esac +done + +if ! $LOGGING && [[ -z "$DOMAIN_REQUESTED_TO_REMOVE" ]] ; then + usage "Giving Domain for deletion (option '-d') is required if using option '-q'." +fi + + + +#--------------------------------------- +#----------------------------- +# Setting Defaults +#----------------------------- +#--------------------------------------- + +DEFAULT_CONF_FILE_DIR="/etc/bind" + + +#--------------------------------------- +#----------------------------- +# Load default values from bind.conf +# +# Overwrites the settings above +# +#----------------------------- +#--------------------------------------- + +if $LOGGING ; then + clear + echo "" + echo "" + echononl " Loading default Configuration values from $(basename ${conf_file}).." + if [[ ! -f "$conf_file" ]]; then + echo_skipped + else + source "${conf_file}" > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + fatal "$(cat $log_file)" + fi + fi + + [[ -n "$CONF_FILE_DIR" ]] && DEFAULT_CONF_FILE_DIR="$CONF_FILE_DIR" + if [[ -n "$ZONE_FILE_MASTER_DIR" ]] ; then + DEFAULT_ZONE_FILE_MASTER_DIR="$ZONE_FILE_MASTER_DIR" + else + DEFAULT_ZONE_FILE_MASTER_DIR="${DEFAULT_CONF_FILE_DIR}/master" + fi + if [[ -n "$ZONE_FILE_SLAVE_DIR" ]] ; then + DEFAULT_ZONE_FILE_SLAVE_DIR="$ZONE_FILE_SLAVE_DIR" + else + DEFAULT_ZONE_FILE_SLAVE_DIR="${DEFAULT_CONF_FILE_DIR}/slave" + fi + [[ -n "$ZONES_DECLARATION_FILE" ]] && DEFAULT_ZONES_DECLARATION_FILE="$ZONES_DECLARATION_FILE" + + + echo "" + + + if [[ -z "$DOMAIN_REQUESTED_TO_REMOVE" ]] ;then + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Insert domain which you want to be removed from bind nameservice." + echo "" + DOMAIN_REQUESTED_TO_REMOVE="" + echononl "Remove Domain: " + read DOMAIN_REQUESTED_TO_REMOVE + while [ "X$DOMAIN_REQUESTED_TO_REMOVE" = "X" ] ; do + echo -e "\n\t\033[33m\033[1mSetting 'Remove Domain' is required!\033[m\n" + echononl "Remove Domain: " + read DOMAIN_REQUESTED_TO_REMOVE + done + fi + + + echo "" + echo "" + echo -e "\033[32m--\033[m" + echo "Common parameters" + echo -e "\033[32m--\033[m" + + + echo "" + echo "Insert directory containing the bind configuration files." + echo "" + CONF_FILE_DIR="" + if [[ -n "$DEFAULT_CONF_FILE_DIR" ]] ; then + echononl "Bind Configuration Directory [${DEFAULT_CONF_FILE_DIR}]: " + read CONF_FILE_DIR + if [[ "X$CONF_FILE_DIR" = "X" ]]; then + CONF_FILE_DIR="$DEFAULT_CONF_FILE_DIR" + fi + else + echononl "Bind Configuration Directory: " + read CONF_FILE_DIR + while [ "X$CONF_FILE_DIR" = "X" ] ; do + echo -e "\n\t\033[33m\033[1mSetting 'Bind Configuration Directory' is required!\033[m\n" + echononl "Bind Configuration Directory: " + read CONF_FILE_DIR + done + fi + + [[ -n "$DEFAULT_ZONES_DECLARATION_FILE" ]] || DEFAULT_ZONES_DECLARATION_FILE="${CONF_FILE_DIR}/named.conf.local" + + + echo "" + echo -e "\033[32m--\033[m" + + echo "" + echo "Insert zones declaration file." + echo "" + ZONES_DECLARATION_FILE="" + if [[ -n "$DEFAULT_ZONES_DECLARATION_FILE" ]] ; then + echononl "Zones Declaration File [${DEFAULT_ZONES_DECLARATION_FILE}]: " + read ZONES_DECLARATION_FILE + if [[ "X$ZONES_DECLARATION_FILE" = "X" ]]; then + ZONES_DECLARATION_FILE="$DEFAULT_ZONES_DECLARATION_FILE" + fi + else + echononl "Zones Declaration File: " + read ZONES_DECLARATION_FILE + while [ "X$ZONES_DECLARATION_FILE" = "X" ] ; do + echo -e "\n\t\033[33m\033[1mSetting 'Zones Declaration File' is required!\033[m\n" + echononl "Zones Declaration File: " + read ZONES_DECLARATION_FILE + done + fi + + + echo "" + echo "" + echo -e "\033[1;32mSettings for \033[1;37mRemove Domain\033[m Script" + echo "" + echo -e "\tDomain requested to remove..........: $DOMAIN_REQUESTED_TO_REMOVE" + echo "" + echo -e "\tBind Configuration Directory........: $CONF_FILE_DIR" + echo -e "\tZones Declaration File..............: $ZONES_DECLARATION_FILE" + + echo "" + info "Remove Domain \033[37m\033[1m${DOMAIN_REQUESTED_TO_REMOVE}\033[m.." + echo -n "To continue type uppercase 'YES': " + read OK + echo "" + if [[ "$OK" != "YES" ]] ; then + fatal "Abort by user request - Answer as not 'YES'" + fi + +else # if $LOGGING + + if [[ ! -f "$conf_file" ]]; then + fatal "Configuration file '$conf_file' not found!" + else + echononl " Loading default Configuration values from $(basename ${conf_file}).." + source "${conf_file}" > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + fatal "$(cat $log_file)" + fi + fi + + if [[ -z "$CONF_FILE_DIR" ]]; then + fatal "Directory contaning bind configurations not set (see CONF_FILE_DIR)!" + fi + + [[ -n "$ZONES_DECLARATION_FILE" ]] || ZONES_DECLARATION_FILE="${CONF_FILE_DIR}/named.conf.local" + +fi + +if [[ ! -f "$ZONES_DECLARATION_FILE" ]]; then + fatal "Zone declaration file '${ZONES_DECLARATION_FILE}' not found!" +fi + +if ! grep -q -E "^\s*zone\s+\"?${DOMAIN_REQUESTED_TO_REMOVE}\"?\s+\{" $ZONES_DECLARATION_FILE 2> /dev/null ; then + fatal "No decleration for domain '${DOMAIN_REQUESTED_TO_REMOVE}' found!" +fi + +backup_date=$(date +%Y-%m-%d-%H%M) + +echononl " Backup '$ZONES_DECLARATION_FILE'.." +cp -a "$ZONES_DECLARATION_FILE" "${ZONES_DECLARATION_FILE}.$backup_date" > $log_file 2>&1 +if [[ $? -gt 0 ]]; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + +declare -i line_number=0 + +_found=false +declare -i _first_line=0 +declare -i _last_line=0 +while IFS='' read -r _line || [[ -n $_line ]] ; do + let line_number++ + if [[ "$_line" =~ ^[[:space:]]*zone[[:space:]]+\"?${DOMAIN_REQUESTED_TO_REMOVE}\"?[[:space:]]+\{ ]]; then + _found=true + _first_line=$line_number + fi + if $_found ; then + if [[ "$_line" =~ ^[[:space:]]*file[[:space:]]+\"? ]]; then + zone_file="$(echo $_line | awk '{print$2}')" + shopt -s extglob + if [[ "$zone_file" =~ \;$ ]]; then + zone_file=${zone_file%%*(;)} + fi + if [[ "$zone_file" =~ ^\" ]]; then + zone_file=${zone_file##*(\")} + zone_file=${zone_file%%*(\")} + fi + shopt -u extglob + fi + if [[ "$_line" =~ ^[[:space:]]*key-directory[[:space:]]+\"? ]]; then + key_directory="$(echo $_line | awk '{print$2}')" + shopt -s extglob + if [[ "$key_directory" =~ \;$ ]]; then + key_directory=${key_directory%%*(;)} + fi + if [[ "$key_directory" =~ ^\" ]]; then + key_directory=${key_directory##*(\")} + key_directory=${key_directory%%*(\")} + fi + shopt -u extglob + fi + if [[ "$_line" =~ ^[[:space:]]*\}[[:space:]]*\; ]]; then + _found=false + _last_line=$line_number + fi + elif [[ $_last_line -gt 0 ]] ; then + if [[ "$_line" =~ ^[[:space:]]*$ ]] ; then + _last_line=$line_number + fi + break; + fi + +done < "$ZONES_DECLARATION_FILE" + +$LOGGING && echo "" +echononl " Delete zone declaration for domain '${DOMAIN_REQUESTED_TO_REMOVE}'" +sed -i "${_first_line},${_last_line}d" "$ZONES_DECLARATION_FILE" > $log_file 2>&1 +if [[ $? -gt 0 ]]; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + +$LOGGING && echo "" +echononl " Create directory '$(dirname ${zone_file})/DELETED'.." +if [[ ! -d "$(dirname ${zone_file})/DELETED" ]] ; then + mkdir "$(dirname ${zone_file})/DELETED" > $log_file 2>&1 + if [[ $? -gt 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +else + echo_skipped +fi + +echononl " Move zone file '$(basename $zone_file)' into directory 'DELETED'" +if [[ ! -f "$zone_file" ]] ; then + echo_failed + error "Concerning zone file '$zone_file' not found!" +else + mv "${zone_file}" "$(dirname ${zone_file})/DELETED" > $log_file 2>&1 + if [[ $? -gt 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +fi + +while IFS='' read -r -d '' _file ; do + echononl " Move file '$(basename $_file)' into directory 'DELETED'" + mv "$_file" "$(dirname ${zone_file})/DELETED" > $log_file 2>&1 + if [[ $? -gt 0 ]]; then + echo_failed + #error "$(cat $log_file)" + else + echo_ok + fi +done < <(find $(dirname ${zone_file}) -mindepth 1 -maxdepth 1 -type f -name "${DOMAIN_REQUESTED_TO_REMOVE}.*" -print0) + + +if [[ -n "$key_directory" ]]; then + + $LOGGING && echo "" + + _dir="$(dirname ${key_directory})/DELETED" + echononl " Create directory '${_dir}'.." + if [[ ! -d "${_dir}" ]] ; then + mkdir "${_dir}" > $log_file 2>&1 + if [[ $? -gt 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi + else + echo_skipped + fi + + _dir="$(dirname ${key_directory})/DELETED/$(basename ${key_directory})" + echononl " Create directory '${_dir}'.." + if [[ ! -d "${_dir}" ]] ; then + mkdir "${_dir}" > $log_file 2>&1 + if [[ $? -gt 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi + else + echo_skipped + fi + + while IFS='' read -r -d '' _file ; do + echononl " Move file '$(basename $_file)' into directory 'DELETED'" + mv "$_file" "$(dirname ${key_directory})/DELETED/$(basename ${key_directory})" > $log_file 2>&1 + if [[ $? -gt 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi + done < <(find $key_directory -mindepth 1 -maxdepth 1 -type f -name "K${DOMAIN_REQUESTED_TO_REMOVE}.*" -print0) + + if [[ ! "$(ls -A $key_directory)" ]] ; then + echononl " Remove empty key directory '$(basename $key_directory)'.." + rmdir $key_directory > $log_file 2>&1 + if [[ $? -gt 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi + fi +fi + +$LOGGING && echo "" + +echononl " Reeload bind configuration" +rndc reconfig > $log_file 2>&1 +if [[ $? -gt 0 ]]; then + echo_failed + error "$(cat $log_file)" +else + echo_done +fi + + +#echo "zone file: $zone_file" +#echo "$line_number - $_first_line , $_last_line" + + +$LOGGING && echo "" +clean_up 0 + + + + + +echo "" +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "" + + + + +## - Read list of zonefiles +## - +while IFS='' read -r -d '' zone_file ; do + + declare -i _serial_new=`date +%Y%m%d01` + + filename=$(basename "$zone_file") + zone="${filename%.*}" + + echo "" + echo -e "\tlooking at $zone_file.." + + + ## - calculate new serial + ## - + declare -i __serial=`grep -e "[0-9]\{10\}" $zone_file | grep serial | awk '{print$1}'` + while [ ! $_serial_new -gt $__serial ]; do + let _serial_new++ + done + + echononl "\t Changing SOA Record.." + if ! grep -E "^.*IN\s+SOA\s+${_soa_nameserver}\.\s+${_soa_admin}\.\s+\(" > /dev/null 2>&1 $zone_file ; then + perl -i -n -p -e "s/^(.*IN\s+SOA).*$/\1 ${_soa_nameserver}. ${_soa_admin}. \(/" $zone_file + if [ "$?" = "0" ]; then + echo_ok + else + echo_failed + fi + else + echo_skipped + continue + fi + + ## - Set new serial + ## - + echononl "\t Renew serial.." + perl -i -n -p -e "s#^(\s*) $__serial(.*)#\1 $_serial_new\2#" $zone_file + if [ "$?" = "0" ]; then + echo_ok + else + echo_failed + fi + + ## - Reload Zone + ## - + echononl "\t Reload Zone $zone.." + /usr/sbin/rndc reload $zone > /dev/null 2>&1 + if [ "$?" = "0" ]; then + echo_ok + else + echo_failed + fi + + sleep 1 + +done < <(find $_zone_files_dir -mindepth 1 -maxdepth 1 -type f -print0) + +echo "" +clean_up 0 diff --git a/conf/bind.conf.sample b/conf/bind.conf.sample new file mode 100644 index 0000000..141d2df --- /dev/null +++ b/conf/bind.conf.sample @@ -0,0 +1,58 @@ +# ---------------------------------------------------- +# --- +# - Parameter Settings for bind administration scripts. +# --- +# ---------------------------------------------------- + +# - CONF_FILE_DIR +# - +# - Directory containing bind configuration files +# - +# - Defaults to "/etc/bind" +# - +#CONF_FILE_DIR="/etc/bind" + + +# - ZONE_FILE_MASTER_DIR +# - +# - Directory containing the zone files (master) +# - +# - Defaults to "${CONF_FILE_DIR}/master" +# - +#ZONE_FILE_MASTER_DIR="${CONF_FILE_DIR}/master" + + +# - ZONE_FILE_SLAVE_DIR +# - +# - Directory containing the zone files (slave) +# - +# - Defaults to "${CONF_FILE_DIR}/slave" +# - +#ZONE_FILE_SLAVE_DIR="${CONF_FILE_DIR}/slave" + + +# - ZONES_DECLARATION_FILE +# - +# - File containing zone declarations +# - +# - Defaults to ${CONF_FILE_DIR}/named.conf.local +# - +#ZONES_DECLARATION_FILE="${CONF_FILE_DIR}/named.conf.local" + + + +# ----- +# - bind_change_SOA.sh +# ----- + +# - SOA_PRIMARY_MASTER +# - +# - Primary master for all zones +# - +SOA_PRIMARY_MASTER="a.ns.oopen.de" + +# - SOA_ADMIN_EMAIL +# - +# - mail address of the responsible of all zones +# - +SOA_ADMIN_EMAIL="domreg@oopen.de"