123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- #!/usr/bin/env bash
- #####################################################
- # This script require the following
- #
- # * A path structure like this:
- # [..path..]/<domainname.tld>/
- # * This path contains a zone file named `db`
- #
- # Your named.conf.local file must link to a
- # filed named `db.signed`, e.g
- #
- # zone "domain.tld" {
- # type master;
- # file "[..path..]/domain.tld/db.signed";
- # };
- #
- # USAGE:
- #
- # 1. Make `dnssec-signer` executable:
- # chmod +x /path/to/dnssec-signer
- #
- # 2. Run:
- # ./path/to/dnssec-signer <domain.tld>
- # 3. Or, for every domain in path
- # ./path/to/dnssec-signer
- #
- ######################################################
- SELF="$(basename ${0})"
- ######################################################
- # START OF CONFIG #
- ######################################################
- # SET YOU SYSTEM SPECIFIC DATA (which systemctl e.g) #
- NAMEDZONES="/etc/bind/named.conf.local"
- ZONESDIR="/etc/bind/zones"
- CHECKZONE=/usr/sbin/named-checkzone
- CHECKCONF=/usr/sbin/named-checkconf
- KEYGEN=/usr/sbin/dnssec-keygen
- SIGNZONE=/usr/sbin/dnssec-signzone
- SYSCTL=/bin/systemctl
- JOURCTL=/bin/journalctl
- DNSSERVICE="bind9.service"
- LOGGER=/usr/bin/logger
- LOGGERFLAGN="-t $(whoami) -p daemon.info"
- LOGGERFLAGE="-t $(whoami) -p daemon.err"
- ######################################################
- # END OF CONFIG #
- ######################################################
- function error_msg {
- FOR=${1}
- ERRMSG="${2}"
- echo -e "\e[31m[${SELF}:\e[1m${FOR}\e[21m]:\e[0m ${ERRMSG}"
- ${LOGGER} ${LOGGERFLAGE} "[${SELF}:${FOR}]: ${ERRMSG}"
- }
- function note_msg {
- FOR=${1}
- NOTEMSG="${2}"
- echo -e "\e[32m[${SELF}:\e[1m${FOR}\e[21m]:\e[0m ${NOTEMSG}"
- ${LOGGER} ${LOGGERFLAGN} "[${SELF}:${FOR}]: ${NOTEMSG}"
- }
- # Generating keys for zone
- # Note, this doesnt check if they exists!
- function genkeys {
- ZONE=${1}
- note_msg "${ZONE}" "Generating missing ZSK and KSK"
- ${KEYGEN} -a NSEC3RSASHA1 -b 2048 -n ZONE "${ZONE}"
- if [ $? -ne 0 ]; then
- error_msg "${ZONE}" "Failed to generate Zone Signing Key (ZSK)"
- return 1
- fi
- ${KEYGEN} -f KSK -a NSEC3RSASHA1 -b 4096 -n ZONE "${ZONE}"
- if [ $? -ne 0 ]; then
- error_msg "${ZONE}" "Failed to generate Key Signing Key (KSK)"
- return 1
- fi
-
- note_msg "${ZONE}" "ZSK and KSK generated"
- return 0
- }
- # Sign zone
- # The actual signing process.
- function sign {
- ZONE="${1}"
- note_msg "${ZONE}" "Signing ZONE"
- if ! [ -d "${2}" ]; then
- error_msg "${ZONE}" "Path ${2} doesnt exist"
- return 1
- fi
- cd "${2}"
- echo `pwd`
- F="db"
- if ! [ -w "${F}" ]; then
- error_msg "${ZONE}" "Missing $(pwd)/${F}"
- return 1
- fi
- ZONEF="db.zone"
- ZONEINCF="${ZONEF}.include"
- note_msg "${ZONE}" "Validating unsigned zone file"
- ${CHECKZONE} "${ZONE}" "${F}"
- if [ $? -ne 0 ]; then
- error_msg "${ZONE}" "Error(s) in zone file"
- if [ -r "${ZONEF}" ]; then
- note_msg "${ZONE}" "Existing signed zone, allowing restart"
- return 1
- else
- note_msg "${ZONE}" "No existing signed zone, disallowing restart"
- return 2
- fi
- fi
-
- KEYS=()
-
- for KEY in $(ls "./"); do
- if [[ "${KEY}" == "K${ZONE}"* ]] && [[ "${KEY}" == *key ]]; then
- KEYS[${#KEYS[@]}]="${KEY}"
- fi
- done
-
- if [ "${#KEYS[@]}" -ne 2 ]; then
- if [ "${#KEYS[@]}" -ne 0 ]; then
- rm "${KEYS[@]}"
- fi
- genkeys "${ZONE}"
- if [ $? -ne 0 ]; then
- return 1
- fi
- sign "${ZONE}" "${2}"
- return $?
- fi
- cat "${F}" > "${ZONEINCF}"
- for KEY in "${KEYS[@]}"; do
- echo "\$INCLUDE ${KEY}" >> "${ZONEINCF}"
- done
- SALT=$(head -c 1000 /dev/random | sha1sum | cut -b 1-16)
- ${SIGNZONE} -A -3 "${SALT}" -N increment -f "${ZONEF}" -o "${ZONE}" -t "${ZONEINCF}"
- if [ $? -ne 0 ]; then
- error_msg "${ZONE}" "Error signing zone"
- return 2
- fi
- note_msg "${ZONE}" "Checking zone-file"
- ${CHECKZONE} "${ZONE}" "${ZONEF}"
- if [ $? -ne 0 ]; then
- error_msg "${ZONE}" "Error zone-file'${SONEF}'"
- return 2
- fi
- note_msg "${ZONE}" "Signing successul!"
- return 0
- }
- # Sign zone;
- # Checks that dir exists first...
- # and ensures we're entering and leaving correctly
- function signzone {
- SIGN="${1}"
- CWDIR=$(pwd)
- sign "${1}" "${ZONESDIR}/${SIGN}"
- RET=$?
- cd "${CWDIR}"
- return ${RET}
- }
- note_msg "date" "$(date)"
- if [[ ${EUID} -ne 0 ]]; then
- error_msg "${USER}" "Must execute file as root."
- exit 1
- fi
- # Collect arguments (zones)
- ZONES="${*}"
- IFS=' ', read -r -a ZONES <<< "${ZONES}"
- if [ ${#ZONES[@]} -ne 0 ]; then
- note_msg "${#ZONES[@]}" "Start signing zones"
- ERR=0
- for ZONE in "${ZONES[@]}"; do
- signzone "${ZONE}"
- if [ $? -eq 2 ]; then
- # To prevent restarting dns if failure
- ERR=1
- fi
- done;
- if [ ${ERR} -eq 0 ]; then
- ${CHECKCONF}
- if [ $? -ne 0 ]; then
- error_msg "${CHECKCONF}" "Error in configruation, not reloading"
- else
- note_msg "$(basename ${SYSCTL})" "Restarting ${DNSSERVICE}"
- ${SYSCTL} restart "${DNSSERVICE}"
- if [ $? -ne 0 ]; then
- ${JOURCTL} -n 10 --unit "${DNSSERVICE}" | xargs -0
- fi
- fi
- else
- error_msg "${DNSSERVICE}" "Errors in configuration(s) for zone(s), not restarting."
- fi
- else
- note_msg "${ZONESDIR}" "Finding zones to sign corresponding to ${NAMEDZONES}"
- CWD=$(pwd)
- cd "${ZONESDIR}"
- NAMED=$(cat $NAMEDZONES)
- for ZONE in $(ls -d */); do
- ACTIVE=$(cat $NAMEDZONES | grep "\"$(basename ${ZONE})\"" | tr -d '[:space:]')
- if [[ "${ACTIVE}" == zone* ]]; then
- ZONES[${#ZONES[@]}]=$(basename ${ZONE})
- fi
- done
- cd ${CWD}
- note_msg "" "Found ${#ZONES[@]} zone(s) active"
- if [ "${#ZONES[@]}" -ne 0 ]; then
- ${SELF} "${ZONES[@]}"
- fi
- fi
|