Browse Source

Added option to read globally when arguments is left out and better logging

root 6 years ago
parent
commit
ae17f2ac09
2 changed files with 160 additions and 29 deletions
  1. 86 2
      README.md
  2. 74 27
      dnssec-signer

+ 86 - 2
README.md

@@ -2,5 +2,89 @@
 
 DNSSEC sign DNS zone(s) in one command. DNSSEC-ninja!
 
-## Usage?
-See source code by now.
+## Requirements
+
+* dnssec
+* haveged (optional, but absolutely a must have to speed up things!)
+
+This script follows a special kind of structure, to more easily understand where to look up and read DNS zones, e.g:
+
+```
+/path/to/zones/<domain.tld>/
+```
+
+The zone file, without any DNSSEC entries, must be called `db` and be placed in the root of the folder `<domain.tld>/`. 
+
+Personally this is an easier folder-structure to look-up and read when I'm working on a server, and the reason why I decided to have it like this.
+
+## Installation
+
+1. Clone this repository ```bash
+git clone giaever@git.giaever.org:joachimmg/dnssec-signer.git && cd "dnssec-signer"
+```
+
+2. Make `dnssec-signer` executable ```bash
+chmod +x dnssec-signer
+```
+
+3. Edit `dnssec-signer` and alter the configuration section:
+	1. NAMEDZONES (default: `/etc/bind/named.conf.local`): The `named`-file with the zones you're authoritative for. This file is used to only sign active zones when arguments aren't given when executing the script. Typically used when running the script as a deamon.
+	2. ZONESDIR (default: `/etc/bind/zones`): The `zones`-folder (see: Requirements) where you store your zones.
+	3. CHECKZONE (default: `/usr/sbin/named-checkzone`): Where the application `named-checkzone` is located on in your OS.
+	4. CHECKCONF (default: `/usr/sbin/named-checkconf`): Where the application `named-checkconf` is located on in your OS.
+	5. KEYGEN (default: `/usr/sbin/dnssec-keygen`): Where the application `dnssec-keygen` is located on in your OS.
+	6. SIGNZONE (default: `/usr/sbin/dnssec-signzone`): Where the application `dnssec-signzone` is located on in your OS.
+	7. SYSCTL (default: `/bin/systemctl`): Where the application `systemctl` is located on in your OS.
+	7. DNSSERVICE (default: `bind.service`): Which DNS service you're using and that `systemctl` will have to restart.
+	8. LOGGER (default: `/usr/bin/logger`): Which logger application you will use and where it reside in your OS.
+	9. LOGGERFLAGN (default: `-t "<username>" -p daemon.info`): Flags you want to pass to the `logger` when logging successful messages.
+	9. LOGGERFLAGE (default: `-t "<username>" -p daemon.err`): Flags you want to pass to the `logger` when logging error messages.
+
+If you like, you can link the file to a `bin`-directory, to globally access the script from any working directory.
+
+```bash
+ln -s /not/a/relative/path/to/dnssec-signer /usr/bin/
+```
+## Usage
+
+A signed zone will be stored in a file called `db.signed` and is the one you have to refer to (or change) in the `named`-file.  This is something you only need to do once, after you signed the zone. 
+
+Please dont delete the `db`-file!
+1. You will do changes to a zone in this file (and not `db.signed`) and sign the zone again afterwards, which will generate a new `db.signed`-file for you. It's more or less impossible to do changes in the signed file.
+2. If you're re-signing a zone it will always read the `db`-file and generate a new `db.signed`-file.
+
+Please don't delete the **KEYS**! They are stored in the `<domain.tld>/`-directory, and they should be kept there for resigning.
+
+The first time a zone is signed there is generated a file called `dsset-<domain.tld>`. To gain `the chain of trust` you must add these keys, in the `dsset`-file, with your registrar.
+
+### Sign a single zone:
+```bash
+./dnssec-signer <zone>
+```
+
+### Sign several zones:
+```bash
+./dnssec-signer <zone> <zone> ... <zone>
+```
+Note: This won't require the zone(s) to be in the `named`-file
+
+### Sign every "active" zone:
+```bash
+./dnssec-signer
+```
+Note: This will check that that zones is in your `named`-file before processing it, as
+this is typically used in a cron-job to update the hash for the zone.
+
+#### Create crontab?
+Edit crontab for the root
+```
+sudo crontab -e
+```
+and add the following
+```
+0 0 */3 * * /path/to/dnssec-signer
+```
+This updates active zones every `3`'rd day. 
+
+## Note
+This is only tested under Bind9 on Ubuntu 16.04.03

+ 74 - 27
dnssec-signer

@@ -27,11 +27,14 @@
 #
 ######################################################
 
+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
@@ -39,31 +42,47 @@ KEYGEN=/usr/sbin/dnssec-keygen
 SIGNZONE=/usr/sbin/dnssec-signzone
 SYSCTL=/bin/systemctl
 DNSSERVICE="bind9.service"
+LOGGER=/usr/bin/logger
+LOGGERFLAGN="-t $(whoami) -p daemon.info"
+LOGGERFLAGE="-t $(whoami) -p daemon.err"
 
 ######################################################
 # 	   	    END OF CONFIG		     #
 ######################################################
 
-# Collect arguments
-ZONES="${*}"
-IFS=' ', read -r -a ZONES <<< "${ZONES}"
+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}
-	echo "* Generating missing keys for ZONE ${ZONE}"
+	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
 }
 
@@ -71,10 +90,10 @@ function genkeys {
 # The actual signing process.
 function sign {
 	ZONE="${1}"
-	echo " * Signing ZONE ${ZONE}"
+	note_msg "${ZONE}" "Signing ZONE"
 
 	if ! [ -d "${2}" ]; then
-		echo "! Error, path ${2} doesnt exist, abort."
+		error_msg "${ZONE}" "Path ${2} doesnt exist"
 		return 1
 	fi
 
@@ -84,7 +103,7 @@ function sign {
 	F="db"
 
 	if ! [ -w "${F}" ]; then
-		echo "! Missing $(pwd)/${F}, abort."
+		error_msg "${ZONE}" "Missing $(pwd)/${F}"
 		return 1
 	fi
 
@@ -106,7 +125,6 @@ function sign {
 
 		genkeys "${ZONE}"
 		if [ $? -ne 0 ]; then
-			echo "! Error generating keys, abort."
 			return 1
 		fi
 
@@ -123,16 +141,17 @@ function sign {
 	${SIGNZONE} -A -3 "${SALT}" -N increment -f "${ZONEF}" -o "${ZONE}" -t "${ZONEINCF}"
 
 	if [ $? -ne 0 ]; then
-		echo "! Error signing zone ${ZONE}, abort."
+		error_msg "${ZONE}" "Error signing zone"
 		return 2
 	fi
 
-	echo "* Checking configuration: "
+	note_msg "${ZONE}" "Checking zone-file"
 	${CHECKZONE} "${ZONE}" "${ZONEF}"
 	if [ $? -ne 0 ]; then
-		echo "! Error in configuration for ${ZONE} => ${SONEF}."
+		error_msg "${ZONE}" "Error zone-file'${SONEF}'"
 		return 2
 	fi
+	note_msg "${ZONE}" "Signing successul!"
 	return 0
 }
 
@@ -148,23 +167,51 @@ function signzone {
 	return ${RET}
 }
 
-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
-		echo "! Error in configruation, not reloading Bind"
+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
+	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 "${SYSCTL}" "Restarting ${DNSSERVICE}"
+			${SYSCTL} restart "${DNSSERVICE}"
+		fi
 	else
-		echo "* Restarting ${DNSSERVICE}"
-		${SYSCTL} restart "${DNSSERVICE}"
+		error_msg "${DNSSERVICE}" "Errors in configuration(s) for zone(s), not restarting."
 	fi
 else
-	echo "Errors in some configurations, not restarting bind."
+	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