- Add script 'bind_get_zonefile_by_hostname.sh'.

- bind_get_domain_by_hostname.sh: some minor changes and bug fixes.
This commit is contained in:
Christoph 2017-08-04 12:00:34 +02:00
parent efeacd0aa5
commit 9211cb8970
2 changed files with 413 additions and 22 deletions

View File

@ -28,12 +28,28 @@ usage() {
Usage: $(basename $0) [Options] <full-qualified-hostname> Usage: $(basename $0) [Options] <full-qualified-hostname>
Script checks if a given hostname is supported by this nameserver. Hostname can Script checks if a given hostname is supported by this nameserver. The concerning
alos be a TLD name. zone will be printed out.
As result the Script returns the zone (domain) of the given hostname." In silent If running in a terminal and not in silent mode (-q), the output is clearly
mode (-q), script returns an empty String, if the given hostname is not arranged in a human readable way.
supported by this nameserver.
If not running in a terminal or silent mode (-q) is set, only the name of the
zonefile will be printed out or an empty string, if the given hostname is
not supported by this nameservice.
Parameter "check" can be used, to test whether this script is accessable (e.g. from a
further script on a remote host). Nothing will be done, scripts returns '0'.
Return (Exit) Codes:
success:
0: hostname is supported
error:
10: Invalid hostname/domain given
11: the given hostname is not supported by this nameserver
12: given hostname is supported, but this nameserver is not the master of
the concerning zone
99: Fatal error
Options: Options:
@ -106,6 +122,10 @@ echo_skipped() {
fi fi
} }
trap clean_up SIGHUP SIGINT SIGTERM
# - Test whether stdout (file descriptor 1) is a terminal or not (e.g. cron # - Test whether stdout (file descriptor 1) is a terminal or not (e.g. cron
# - or if you pipe the output to some other program) # - or if you pipe the output to some other program)
# #
@ -132,10 +152,18 @@ if [[ $# -ne 1 ]] ; then
if $verbose ; then if $verbose ; then
usage "wrong number of arguments" usage "wrong number of arguments"
else else
clean_up 10 clean_up 99
fi fi
fi fi
# - Parameter "check" can be used, to test whether this script
# - is accessable (e.g. from a script on a remote host)
# -
if [[ "$1" = "check" ]]; then
info "Script \033[1m$(basename $0)\033[m was successfully invoked, but its only a test."
clean_up 0
fi
hostname=$1 hostname=$1
@ -143,7 +171,7 @@ $verbose && echo ""
if [[ -z "$hostname" ]] ; then if [[ -z "$hostname" ]] ; then
error "No hostname/domain given!" error "No hostname/domain given!"
clean_up 10 clean_up 99
fi fi
@ -187,7 +215,6 @@ fi
$verbose && echo "" $verbose && echo ""
# - Validate Syntax of given domain # - Validate Syntax of given domain
# - # -
valid_domain_regex="^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$" valid_domain_regex="^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$"
@ -206,28 +233,61 @@ else
clean_up 10 clean_up 10
fi fi
# - Is hostname supported by this nameserver?
# -
_failed=false _failed=false
_hostname=$(echo ${hostname//\./\\.}) zone=$hostname
while ! grep -E "^\s*zone\s+\"?$_hostname" $ZONES_DECLARATION_FILE > /dev/null 2>&1 ; do _zone=$(echo ${zone//\./\\.})
hostname=${hostname#*.} while ! grep -E "^\s*zone\s+\"?$_zone" $ZONES_DECLARATION_FILE > /dev/null 2>&1 ; do
_hostname=$(echo ${hostname//\./\\.}) zone=${zone#*.}
if [[ ! $_hostname =~ \. ]]; then _zone=$(echo ${zone//\./\\.})
if [[ ! $_zone =~ \. ]]; then
_failed=true _failed=true
break break
fi fi
done done
if $_failed ; then if $_failed ; then
$verbose && error "hostname \"$1\" not supported by this nameserver!" $verbose && error "hostname \"$hostname\" not supported by this nameserver!"
else clean_up 11
domain=$hostname
if $verbose ; then
info "Hosted Zone: \033[1m${domain}\033[m"
else
echo "$domain"
fi
fi fi
$verbose && echo # - Is this nameserver also the master?
# -
_found=false
_found_zonefile=false
_is_master=false
zone_file=""
regex_zone="^[[:space:]]*zone[[:space:]]+\"?$(echo ${zone//\./\\.})\""
regex_file="^[[:space:]]*file"
regex_master="type[[:space:]]+master"
while IFS='' read -r line || [[ -n "$line" ]] ; do
if [[ $line =~ $regex_zone ]]; then
_found=true
fi
if $_found ; then
if [[ $line =~ $regex_master ]]; then
_is_master=true
fi
if [[ "$line" =~ ^[[:space:]]*\}[[:space:]]*\; ]]; then
break
fi
fi
done < $ZONES_DECLARATION_FILE
if $_is_master ; then
if $verbose ; then
info "Hosted Zone: \033[1m${zone}\033[m"
else
echo "$zone"
fi
else
$verbose && error "hostname \"$hostname\" is supported but this nameserver is not the master!"
clean_up 12
fi
$verbose && echo ""
clean_up 0 clean_up 0

331
bind_get_zonefile_by_hostname.sh Executable file
View File

@ -0,0 +1,331 @@
#!/usr/bin/env bash
working_dir="$(dirname $(realpath $0))"
conf_file="${working_dir}/conf/bind.conf"
log_file="$(mktemp)"
#---------------------------------------
#-----------------------------
# Setting Defaults
#-----------------------------
#---------------------------------------
DEFAULT_CONF_FILE_DIR="/etc/bind"
#---------------------------------------
#-----------------------------
# Base Function(s)
#-----------------------------
#---------------------------------------
usage() {
echo
[ -n "$1" ] && echo -e "Error: $1\n"
cat<<EOF
Usage: $(basename $0) [Options] <full-qualified-hostname> | check
Script checks if a given hostname is supported by this nameserver. The concerning
zonefile will be printed out.
If running in a terminal and not in silent mode (-q), the output is clearly
arranged in a human readable way.
If not running in a terminal or silent mode (-q) is set, only the name of the
zonefile will be printed out or an empty string, if the given hostname is
not supported by this nameservice.
Parameter "check" can be used, to test whether this script is accessable (e.g. from a
further script on a remote host). Nothing will be done, scripts returns '0'.
Return (Exit) Codes:
success:
0: hostname is supported
error:
10: Invalid hostname/domain given
11: the given hostname is not supported by this nameserver
12: given hostname is supported, but this nameserver is not the master of
the concerning zone
99: Fatal error
Options:
-h
Prints this help.
-q
Runs in silent mode.
EOF
clean_up 1
}
clean_up() {
# Perform program exit housekeeping
rm $log_file
exit $1
}
echononl(){
if $verbose ; 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 ""
echo -e "[ \033[31m\033[1mError\033[m ]: $*"
echo ""
echo -e "\t\033[31m\033[1mScript is canceled\033[m\033[m"
echo ""
clean_up 99
}
warn (){
if $verbose ; then
echo ""
echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*"
echo ""
fi
}
info (){
if $verbose ; then
echo ""
echo -e "\t[ \033[32m\033[1mInfo\033[m ]: $*"
echo ""
fi
}
ok (){
if $verbose ; then
echo ""
echo -e "\t[ \033[36m\033[1mOk\033[m ]: $*"
echo ""
fi
}
error(){
if $verbose ; then
echo ""
echo -e "\t[ \033[31m\033[1mFehler\033[m ]: $*"
echo ""
fi
}
echo_ok() {
if $verbose ; then
echo -e "\033[75G[ \033[32mok\033[m ]"
fi
}
echo_failed(){
if $verbose ; then
echo -e "\033[75G[ \033[1;31mfailed\033[m ]"
fi
}
echo_skipped() {
if $verbose ; then
echo -e "\033[75G[ \033[33m\033[1mskipped\033[m ]"
fi
}
containsElement () {
local e
for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
return 1
}
trap clean_up SIGHUP SIGINT SIGTERM
# - Test whether stdout (file descriptor 1) is a terminal or not (e.g. cron
# - or if you pipe the output to some other program)
#
if [[ -t 1 ]] ; then
verbose=true
else
verbose=false
fi
while getopts hq opt ; do
case $opt in
q) verbose=false
;;
h) usage
;;
*)
;;
esac
done
shift $(expr $OPTIND - 1)
if [[ $# -ne 1 ]] ; then
if $verbose ; then
usage "wrong number of arguments"
else
clean_up 99
fi
fi
# - Parameter "check" can be used, to test whether this script
# - is accessable (e.g. from a script on a remote host)
# -
if [[ "$1" = "check" ]]; then
info "Script \033[1m$(basename $0)\033[m was successfully invoked, but its only a test."
clean_up 0
fi
hostname=$1
$verbose && echo ""
if [[ -z "$hostname" ]] ; then
error "No hostname/domain given!"
clean_up 99
fi
#---------------------------------------
#-----------------------------
# Load default values from bind.conf
#
# Overwrites the settings above
#
#-----------------------------
#---------------------------------------
if $verbose ; then
clear
echo ""
echo -e "\033[32mRunning script \033[1m"$(basename $0)"\033[m .."
echo ""
fi
info "Given hostname: \033[1m${hostname}\033[m"
echononl "\t 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" ]] || CONF_FILE_DIR="$DEFAULT_CONF_FILE_DIR"
[[ -n "$ZONES_DECLARATION_FILE" ]] || ZONES_DECLARATION_FILE="${CONF_FILE_DIR}/named.conf.local"
$verbose && echo ""
# - Validate Syntax of given domain
# -
valid_domain_regex="^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$"
echononl "\t Validate syntax of given domain.."
if [[ $hostname =~ $valid_domain_regex ]]; then
if [[ ! $hostname =~ \. ]]; then
echo_failed
error "Invalid hostname/domain given!"
clean_up 10
else
echo_ok
fi
else
echo_failed
error "Invalid hostname/domain given!"
clean_up 10
fi
# - Is hostname supported by this nameserver?
# -
_failed=false
zone="$hostname"
_zone=$(echo ${zone//\./\\.})
while ! grep -E "^\s*zone\s+\"?$_zone" $ZONES_DECLARATION_FILE > /dev/null 2>&1 ; do
zone=${zone#*.}
_zone=$(echo ${zone//\./\\.})
if [[ ! $_zone =~ \. ]]; then
_failed=true
break
fi
done
if $_failed ; then
$verbose && error "hostname \"$hostname\" not supported by this nameserver!"
clean_up 11
fi
# - Determine zonefile (by reading bind configuration)
# -
_found=false
_found_zonefile=false
_is_master=false
zone_file=""
regex_zone="^[[:space:]]*zone[[:space:]]+\"?$(echo ${zone//\./\\.})\""
regex_file="^[[:space:]]*file"
regex_master="type[[:space:]]+master"
while IFS='' read -r line || [[ -n "$line" ]] ; do
if [[ $line =~ $regex_zone ]]; then
_found=true
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
_found_zonefile=true
fi
break
fi
fi
done < $ZONES_DECLARATION_FILE
if $_found_zonefile ; then
if $verbose ; then
info "Zonefile for '$hostname': \033[1m${zone_file}\033[m"
else
echo "$zone_file"
fi
else
$verbose && error "hostname \"$hostname\" is supported but this nameserver is not the master!"
clean_up 12
fi
$verbose && echo
clean_up 0