From fd7e3f00e1adc3824efd6c941d867f4db19d3cde Mon Sep 17 00:00:00 2001 From: mortzu Date: Sun, 12 Oct 2014 13:52:26 +0200 Subject: [PATCH] added zone file --- data/me.ffhb.zone | 77 ++++++++++++++++++++ update-dns-nodes.sh | 118 ++++++++++++++++++++++++++++++ update-dns.sh | 174 +++++++++++++++++++++++++++++++------------- 3 files changed, 318 insertions(+), 51 deletions(-) create mode 100644 data/me.ffhb.zone create mode 100755 update-dns-nodes.sh diff --git a/data/me.ffhb.zone b/data/me.ffhb.zone new file mode 100644 index 0000000..f2b7e12 --- /dev/null +++ b/data/me.ffhb.zone @@ -0,0 +1,77 @@ +$TTL 1D +@ IN SOA ns01 noc.bremen.freifunk.net. ( + 2014092801 ; Serial + 4H ; Refresh + 1H ; Retry + 2W ; Expire + 1D) ; Negative Cache TTL + + NS ns01 + NS ns02 + NS ns03 + + MX 50 mail + +; pages.github.com + A 192.30.252.153 + A 192.30.252.154 + +; network stuff +gw01 A 185.55.119.1 + AAAA 2a02:2919::1 +gw02 A 185.55.119.2 + AAAA 2a02:2919::2 +noc01 A 185.55.119.18 + AAAA 2a02:2919:fdda::18 + +ns01 A 37.72.148.55 + AAAA 2a02:2918:505:101::55 +ns02 A 37.72.148.163 + AAAA 2a02:2918:506:101::163 +ns03 A 151.236.28.15 + AAAA 2a00:1768:1003:151:236:28:15:1 + +vpn01 A 185.55.119.34 + AAAA 2a02:2919:fcca::2 +vpn02 A 134.102.22.130 +vpn A 185.55.119.34 + A 134.102.22.130 + AAAA 2a02:2919:fcca::2 + +; mail +mail A 37.72.148.168 + AAAA 2a02:2918:506:101::168 + +; websites +www CNAME @ +downloads A 37.72.148.168 + AAAA 2a02:2918:506:101::168 +wiki A 37.72.148.168 + AAAA 2a02:2918:506:101::168 + +; mesh stuff +nodes NS ns01 +nodes NS ns02 +nodes NS ns03 + +node A 10.196.0.127 + AAAA fd2f:5119:f2c::127 + +mesh A 10.196.0.1 + AAAA fd2f:5119:f2c::1 + +jplitza A 10.196.0.200 + AAAA 2a02:2919:1001::c8 +wikipedia CNAME jplitza + +$ORIGIN services +1.ntp AAAA fd2f:5119:f2c::1 +1.vpn AAAA fd2f:5119:f2c::1 +2.vpn AAAA fd2f:5119:f2c::2 + +introducer.tahoe-lafs A 10.196.0.2 + +node A 10.196.0.127 + AAAA fd2f:5119:f2c::127 + +smokeping AAAA 2a02:2919:1000:0:ba27:ebff:fe69:2879 diff --git a/update-dns-nodes.sh b/update-dns-nodes.sh new file mode 100755 index 0000000..3547dba --- /dev/null +++ b/update-dns-nodes.sh @@ -0,0 +1,118 @@ +#! /usr/bin/env bash +# 2014, Moritz Kaspar Rudert (mortzu) . +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# * The names of its contributors may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# * Feel free to send Club Mate to support the work. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS +# AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +# PID file +RUN_FILE='/run/update-dns-nodes.run' + +# getting workingdir of scripts +WORK_DIR="$(dirname $(readlink -nf $0))" + +# set safe path +PATH="${WORK_DIR}:/sbin:/usr/sbin:/bin:/usr/bin" + +# alfred data file +ALFRED_DATA_FILE='/var/cache/ffhb/alfred.json' + +# create alfred data directory +mkdir -p "$(dirname $ALFRED_DATA_FILE)" + +# define variable to count loops +declare -i NUM=0 + +# tmp file +TMP_FILE="$(mktemp)" + +# if creation of tmp file failed +# exit +if [ -z "$TMP_FILE" ]; then + exit 1 +fi + +# names of zones +ZONEFILE=/var/cache/bind/ffhb.nodes.zone +RZONEFILE=/var/cache/bind/arpa.ip6.f.d.2.f.5.1.1.9.0.f.2.c.zone + +function on_exit() { + # remove tmp files + for FILE in "$TMP_FILE" "$RUN_FILE"; do + if [ -n "$FILE" ]; then + rm -f "$FILE" + fi + done +} + +trap on_exit EXIT SIGTERM SIGINT + +# write run file +if [ -f "$RUN_FILE" ]; then + echo 'Script already running!' >&2 + exit 1 +else + touch "$RUN_FILE" +fi + +# loop until data received +while true; do + # increment counter + NUM=$(($NUM+1)) + + # get data from alfred + # but limit the time + timeout -s KILL 30s alfred-json -z -r 158 >"$TMP_FILE" 2>/dev/null + + # on success leave loop + if [ $? -eq 0 ]; then + break + fi + + # if the 240th run has reached kill script + if [ $NUM -gt 240 ]; then + # exit with error code + exit 1 + fi + + # sleep to be safe CPU load don't getting higher + sleep 1 +done + +# generate forward zone +if zonegen.py <"$TMP_FILE" >"${ZONEFILE}.new"; then + mv "${ZONEFILE}.new" "${ZONEFILE}" +fi + +# generate reverse zone +if rzonegen.py 0.0.0.0.c.2.f.0.9.1.1.5.f.2.d.f.ip6.arpa <"$TMP_FILE" >"${RZONEFILE}.new"; then + mv "${RZONEFILE}.new" "${RZONEFILE}" +fi + +# reload nameserver +rndc reload >/dev/null + +# copy alfred file +cp "$TMP_FILE" "$ALFRED_DATA_FILE" diff --git a/update-dns.sh b/update-dns.sh index e3c2dcc..dd9058c 100755 --- a/update-dns.sh +++ b/update-dns.sh @@ -27,40 +27,33 @@ # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# TMP file +TMP_CONFIG_FILE="$(mktemp)" + # PID file -RUN_FILE='/run/ffhb-update-dns.run' +RUN_FILE='/run/update-dns.run' + +# destination zonefile directory +DEST_DIR='/var/cache/bind' + +DEST_CONFIG_FILE="${DEST_DIR}/zones.conf" # getting workingdir of scripts WORK_DIR="$(dirname $(readlink -nf $0))" # set safe path -PATH="${WORK_DIR}:/sbin:/usr/sbin:/bin:/usr/bin" +PATH=/sbin:/usr/sbin:/bin:/usr/bin -# alfred data file -ALFRED_DATA_FILE='/var/cache/ffhb/alfred.json' +# several sites to get IP address +GET_MY_IP=( "http://getip.planetcyb.org" "http://whatismyip.oceanus.ro" "http://www.whatismyip.us" "http://whatismyip.everdot.org" "http://www.whatismyip.ca" "http://whatismyip.com.au" "http://www.whatismyip.nl" "http://www.whatismyip.ro" "http://www.whatismyip.se" ) -# create alfred data directory -mkdir -p "$(dirname $ALFRED_DATA_FILE)" - -# define variable to count loops -declare -i NUM=0 - -# tmp file -TMP_FILE="$(mktemp)" - -# if creation of tmp file failed -# exit -if [ -z "$TMP_FILE" ]; then - exit 1 -fi - -# names of zones -ZONEFILE=/var/cache/bind/ffhb.nodes.zone -RZONEFILE=/var/cache/bind/arpa.ip6.f.d.2.f.5.1.1.9.0.f.2.c.zone +EXTERNAL_IPV4_ADDR='' +EXTERNAL_IPV6_ADDR="$(perl -MNetAddr::IP -MNet::Address::IP::Local -e "print NetAddr::IP->new6(Net::Address::IP::Local->public_ipv6)->short()" | tr '[A-Z]' '[a-z]')" +EXTERNAL_IPV6_NETWORK="$(perl -MNetAddr::IP -e "print NetAddr::IP->new6('${EXTERNAL_IPV6_ADDR}/64')->network->short()" | tr '[A-Z]' '[a-z]' | sed -e 's/::$//g')" function on_exit() { # remove tmp files - for FILE in "$TMP_FILE" "$RUN_FILE"; do + for FILE in "$RUN_FILE" "$TMP_CONFIG_FILE"; do if [ -n "$FILE" ]; then rm -f "$FILE" fi @@ -77,42 +70,121 @@ else touch "$RUN_FILE" fi -# loop until data received -while true; do - # increment counter - NUM=$(($NUM+1)) +# get IPv4 address +for URL in "${GET_MY_IP[@]}"; do + EXTERNAL_IPV4_ADDR="$(curl -m4 -4 -s -- ${URL} | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | head -n1)" - # get data from alfred - # but limit the time - timeout -s KILL 30s alfred-json -z -r 158 >"$TMP_FILE" 2>/dev/null - - # on success leave loop - if [ $? -eq 0 ]; then + if [ -n "$EXTERNAL_IPV4_ADDR" ]; then break fi - - # if the 240th run has reached kill script - if [ $NUM -gt 240 ]; then - # exit with error code - exit 1 - fi - - # sleep to be safe CPU load don't getting higher - sleep 1 done -# generate forward zone -if zonegen.py <"$TMP_FILE" >"${ZONEFILE}.new"; then - mv "${ZONEFILE}.new" "${ZONEFILE}" +# print error if determining of IP addresses failed +if [ -z "$EXTERNAL_IPV4_ADDR" -o -z "$EXTERNAL_IPV6_ADDR" ]; then + echo 'Determining of IP address failed!' >&2 + exit 1 fi -# generate reverse zone -if rzonegen.py 0.0.0.0.c.2.f.0.9.1.1.5.f.2.d.f.ip6.arpa <"$TMP_FILE" >"${RZONEFILE}.new"; then - mv "${RZONEFILE}.new" "${RZONEFILE}" +# refresh git repository +git --work-tree="${WORK_DIR}" --git-dir="${WORK_DIR}/.git" pull -q --rebase=false origin master + +# loop over zones +for FILE in ${WORK_DIR}/data/*; do + # tmp file + TMP_FILE="$(mktemp)" + + # reset some variables + OLD_SERIAL='' + NEW_SERIAL='' + + # construct realname + REAL_NAME="$(basename $FILE)" + + # construct origin + ORIGIN="$(basename "${FILE/.zone/}")" + + # build zone name from filename + declare -a DOMAIN_PARTS + IFS='.' read -a DOMAIN_PARTS <<< "$ORIGIN" + DOMAIN='' + for (( idx=${#DOMAIN_PARTS[@]}-1 ; idx>=0 ; idx-- )) ; do + [ -n "$DOMAIN" ] && DOMAIN="$DOMAIN.${DOMAIN_PARTS[idx]}" || DOMAIN="${DOMAIN_PARTS[idx]}" + done + + # replace the first dash with a slash + # for RDNS zones smaller than /24 + if [ $(grep -o '-' <<<"$DOMAIN" | wc -l) -gt 1 ]; then + DOMAIN="$(sed -e 's#-#/#' <<< $DOMAIN)" + fi + + # write new config entry + cat >> "$TMP_CONFIG_FILE" <"$TMP_FILE" + + # if zone already exists + if [ -f "${DEST_DIR}/${REAL_NAME}" ]; then + # save old serial number + OLD_SERIAL="$(grep -Eho "20[0-1][0-9]{7}" "${DEST_DIR}/${REAL_NAME}")" + + # strip serial from old and new files + # diff is easier without different serial numbers + TMP_FILE_OLD="$(mktemp)" + TMP_FILE_NEW="$(mktemp)" + sed -e '/20[0-1][0-9]\{7\}/d' "${DEST_DIR}/${REAL_NAME}" >"$TMP_FILE_OLD" + sed -e '/20[0-1][0-9]\{7\}/d' "$TMP_FILE" >"$TMP_FILE_NEW" + + # check if update is necessary + if diff -q "$TMP_FILE_OLD" "$TMP_FILE_NEW" >/dev/null 2>&1; then + # if zones are identically + # remove tmp files + for FILE in "$TMP_FILE" "$TMP_FILE_OLD" "$TMP_FILE_NEW"; do + if [ -n "$FILE" ]; then + rm -f "$FILE" + fi + done + continue + fi + fi + + # check if zone is valid + if ! named-checkzone "$DOMAIN" "$TMP_FILE" >/dev/null 2>&1; then + echo "$FILE is not valid!" >&2 + for FILE in "$TMP_FILE" "$TMP_FILE_OLD" "$TMP_FILE_NEW"; do + if [ -n "$FILE" ]; then + rm -f "$FILE" + fi + done + continue + fi + + # update serial + if [ -n "$OLD_SERIAL" ]; then + NEW_SERIAL=$(($OLD_SERIAL + 1)) + else + NEW_SERIAL=$(date +'%Y%m%d%H') + fi + sed -e 's/20[0-1][0-9]\{7\}/'${NEW_SERIAL}'/g' -i "$TMP_FILE" + + # move the file to real place + mv "$TMP_FILE" "${DEST_DIR}/${REAL_NAME}" + + # fix permissions + chmod 0644 "${DEST_DIR}/${REAL_NAME}" +done + +if [ ! -f "$DEST_CONFIG_FILE" ] || ( [ -n "$(cat $TMP_CONFIG_FILE)" ] && ! diff -q "$TMP_CONFIG_FILE" "$DEST_CONFIG_FILE" >/dev/null 2>&1 ); then + mv "$TMP_CONFIG_FILE" "$DEST_CONFIG_FILE" + chmod 0644 "$DEST_CONFIG_FILE" fi # reload nameserver rndc reload >/dev/null - -# copy alfred file -cp "$TMP_FILE" "$ALFRED_DATA_FILE"