#!/bin/sh # exit script when command fails set -e # Communityconfig CommunityDomain="fff.community" CommunityExternPrefix="extern" CommunitySubnets="10.50.0/16 10.83.0/16 fd43:5602:29bd::/48" RemoteLocation="https://git.freifunk-franken.de/freifunk-franken/dns/raw/branch/master/" DNSSECPolicy="herpf" # Serverconfig export DNSSCRIPT_CONTACT_EMAIL=info.freifunk-herpf.de. # DNSSCRIPT_SERVER_NAME must be the server given in community zone files NS entry (Full Hostname, w/o trailing dot) export DNSSCRIPT_SERVER_NAME=dns.herpf.fff.community UpdateScriptsFolder="/usr/lib/ffdns/" ZoneFilesFolder="/etc/bind/fff/" BindIncludeFileFolder="/etc/bind/" DNSSECKeyFolder="/etc/bind/keys/" TempFolder="/tmp/dnsscripts/" # specify the bird/babel or other routing table[s] # if RoutingTables is empty, the ICVPN-ACL-List will be fetched remotely (for servers that are no gateway) RoutingTables="10" # -1 -> disable bind [restart|reload] # 0 -> Debian (and like) systemctl [reload|restart] bind9 # 1 -> use rndc to [reload zone|reconfig] (recommended; rndc needs setup first) # 2 -> OpenWRT /etc/init.d/named [reload|restart] export DNSSCRIPT_BIND_RELOAD_VER=0 InternalViews="icvpn-internal-view icvpn-internal-dns64-view" ExternalView="external-view" # TTL Refresh Retry Expire Minimum TTLReReExMi="3600 2000 6400 2419200 86400" # ForwardZones: "/" ; optionaly multiple " ""/" no spaces in full filename ForwardZones="$CommunityDomain""/""$ZoneFilesFolder""db.icvpn-internal-view.""$CommunityDomain" ############################################################# cd "$UpdateScriptsFolder" . ./dns-functions.sh FirstInternal="$( echo "$InternalViews" | sed -ne 's/^\(\S\+\)\s.*$/\1/p')" BindIcvpnAclTmp="$TempFolder""icvpn-acl.conf" BindIcvpnAcl="$BindIncludeFileFolder""icvpn-acl.conf" [ -z "$CommunityExternPrefix" ] || CommunityExternDomain="$CommunityExternPrefix"".""$CommunityDomain" mkdir -p "$TempFolder""cache" for IView in $InternalViews; do rm -f "$TempFolder""$IView"".conf" done rm -f "$TempFolder""$ExternalView"".conf" CachedMasterFile="$TempFolder""cache/db.""$CommunityDomain" PreFetchMasterSerial="$(GetZoneFileSerial "$CachedMasterFile")" $(curl -s -S -f "$RemoteLocation""db.""$CommunityDomain" --output "$CachedMasterFile") PostFetchMasterSerial="$(GetZoneFileSerial "$CachedMasterFile")" ServeMasterZone="$( GetAllZoneNameservers "$CommunityDomain" "$CachedMasterFile" | awk '{for(i=NF;i>0;--i) if($i=="'"$DNSSCRIPT_SERVER_NAME"'") {printf 1}}')" if [ -n "$CommunityExternDomain" ]; then if [ -n "$ServeMasterZone" ]; then ServeExtZone="1" else ServeExtZone="$( GetAllSubNameservers "$CommunityDomain" "$CommunityExternPrefix" "$CachedMasterFile" | awk '{for(i=NF;i>0;--i) if($i=="'"$DNSSCRIPT_SERVER_NAME"'") {printf 1}}')" fi else ServeExtZone="" fi if [ -n "$ServeMasterZone" ] || [ -n "$ServeExtZone" ]; then sed -i -e '/^\s*_dnsseckeys\./d' "$CachedMasterFile" FileForExternGeneration="$CachedMasterFile" if [ -n "$ExternalView" ]; then ExternFile="$ZoneFilesFolder""db.""$ExternalView"".""$CommunityDomain" else ExternFile="$ZoneFilesFolder""db.""$CommunityExternDomain" fi LocalMasterSerial=$((PostFetchMasterSerial)) if [ -n "$ServeMasterZone" ]; then MasterFile="$ZoneFilesFolder""db.""$FirstInternal"".""$CommunityDomain" FileForExternGeneration="$MasterFile" ZoneTempFolder="$TempFolder""cache/""$CommunityDomain""/" UpdateMaster="$(UpdateDNSSECEntryCache "$CommunityDomain" "$ZoneTempFolder" "$CachedMasterFile" "$DNSSECKeyFolder")" if [ $((PostFetchMasterSerial)) -gt $((PreFetchMasterSerial)) ] || [ $UpdateMaster -ne 0 ]; then cp -f "$CachedMasterFile" "$CachedMasterFile""I" for KeyFile in "$ZoneTempFolder"*; do [ "$KeyFile" == "$ZoneTempFolder""*" ] || \ cat "$KeyFile" >> "$CachedMasterFile""I" done LocalMasterSerial="$(GetZoneFileSerial "$MasterFile")" if [ $((PostFetchMasterSerial)) -le $((LocalMasterSerial)) ]; then LocalMasterSerial=$((LocalMasterSerial+1)) sed -i -e 's/^\(\s*\)'"$PostFetchMasterSerial"'\(\s*;\s*[Ss]erial.*\)$/\1'"$LocalMasterSerial"'\3/g' "$CachedMasterFile""I" sed -i -e 's/^\(\s*\S\+\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Ss][Oo][Aa]\s\+\S\+\s\+\S\+\s\+\)'"$PostFetchMasterSerial"'\(\s\+.*\)$/\1'"$LocalMasterSerial"'\3/g' "$CachedMasterFile""I" else LocalMasterSerial=$((PostFetchMasterSerial)) fi mv "$CachedMasterFile""I" "$MasterFile" ReloadZone "$CommunityDomain" "$InternalViews" InsertZoneToViews "$InternalViews" "$ZoneFilesFolder" "$CommunityDomain" "$MasterFile" "$TempFolder" "$DNSSECPolicy" fi for Subnet in $CommunitySubnets; do ReverseDomains="$(GetReverseDomains "$Subnet")" for RDomain in $ReverseDomains; do ReverseZoneFile="$(GetReverseZoneFileFromZone "${RDomain%*.}")" ! curl -s -f "$RemoteLocation""static.""$ReverseZoneFile" \ --output "$ZoneFilesFolder""static.""$ReverseZoneFile" && \ rm -f "$ZoneFilesFolder""static.""$ReverseZoneFile" ./update-rdnszone.sh "$RDomain" "$ForwardZones" "$ZoneFilesFolder""$ReverseZoneFile" "$TTLReReExMi" "$InternalViews" for IView in $InternalViews; do InsertZoneToIncludeFile "${RDomain%*.}" "$ZoneFilesFolder""$ReverseZoneFile" "$TempFolder""$IView"".conf" done done done if [ -n "$ExternalView" ]; then InsertZoneToIncludeFile "$CommunityDomain" "$ExternFile" "$TempFolder""$ExternalView"".conf" "$DNSSECPolicy" fi fi UpdateExternView=0 if [ -n "$ExternalView" ] || [ -n "$ServeExtZone" ]; then SerialExtern="$(GetZoneFileSerial "$ExternFile")" if [ $((LocalMasterSerial)) -gt $((SerialExtern)) ]; then sed -e '/^[^;]*\s\(10.\|[fF][cdCD][0-9a-fA-F]\{2\}:\)\S*\s*\(;.*\)\?$/d; \ s/^[^;^@]*\s\+\([^;]*\)\s[Ii][Nn]\s\+[Ss][Oo][Aa]\s/@ \1 IN SOA /g' "$FileForExternGeneration" \ > "$ExternFile" UpdateExternView=1 [ -z "$ExternalView" ] || ReloadZone "$CommunityExternDomain" "$ExternalView" fi fi if [ -n "$ServeExtZone" ]; then MasterExtDomainFile="$ZoneFilesFolder""db.""$FirstInternal"".""$CommunityExternDomain" ZoneTempFolder="$TempFolder""cache/""$CommunityExternDomain""/" cp -f "$ExternFile" "$CachedMasterFile""E" sed -i -e '/^\s*_dnsseckeys\./d' "$CachedMasterFile""E" [ -n "$(sed -e '/^\s*\(@\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Nn][Ss]\)\s/!d' "$CachedMasterFile""E")" ] || \ sed -i -e 's/^\s*\(@\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Ss][Oo][Aa]\)\s\+\S\+\s\+\S\+\s/\1 '"$DNSSCRIPT_SERVER_NAME"'. '"$DNSSCRIPT_CONTACT_EMAIL"' /g' "$CachedMasterFile""E" sed -i -e 's/^\s*'"$CommunityExternPrefix"'\s/@ /g' "$CachedMasterFile""E" UpdateExternDomain="$(UpdateDNSSECEntryCache "$CommunityExternDomain" "$ZoneTempFolder" "$CachedMasterFile""E" "$DNSSECKeyFolder")" if [ $UpdateExternView -ne 0 ] || [ $UpdateExternDomain -ne 0 ]; then for KeyFile in "$ZoneTempFolder"*; do [ "$KeyFile" == "$ZoneTempFolder""*" ] || \ cat "$KeyFile" >> "$CachedMasterFile""E" done LocalExtDomainMasterSerial="$(GetZoneFileSerial "$MasterExtDomainFile")" if [ $((LocalMasterSerial)) -le $((LocalExtDomainMasterSerial)) ]; then LocalExtDomainMasterSerial=$((LocalExtDomainMasterSerial+1)) sed -i -e 's/^\(\s*\)'"$LocalMasterSerial"'\(\s*;\s*[Ss]erial.*\)$/\1'"$LocalExtDomainMasterSerial"'\3/g' "$CachedMasterFile""E" sed -i -e 's/^\(\s*\S\+\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Ss][Oo][Aa]\s\+\S\+\s\+\S\+\s\+\)'"$LocalMasterSerial"'\(\s\+.*\)$/\1'"$LocalExtDomainMasterSerial"'\3/g' "$CachedMasterFile""E" fi mv "$CachedMasterFile""E" "$MasterExtDomainFile" ReloadZone "$CommunityExternDomain" "$InternalViews" fi InsertZoneToViews "$InternalViews" "$ZoneFilesFolder" "$CommunityExternDomain" "$MasterExtDomainFile" "$TempFolder" "$DNSSECPolicy" InsertZoneToViews "$ExternalView" "$ZoneFilesFolder" "$CommunityExternDomain" "$MasterExtDomainFile" "$TempFolder" "$DNSSECPolicy" fi fi if [ -z "$MasterFile" ]; then MasterFile="$ZoneFilesFolder""db.""$FirstInternal"".""$CommunityDomain" cp -f "$CachedMasterFile" "$MasterFile" fi # set shorter TTL for Hoods TTLReReExMi="420 360 180 1800 360" Hoods="$(GetOwnHoods "$CommunityDomain" "$MasterFile")" for Hood in $Hoods; do HoodDomain="${Hood%%\#*}"".""$CommunityDomain" Subnets="$(echo "${Hood#*\#}" | sed -e 's/#/ /g')" HoodZoneFile="$ZoneFilesFolder""db.""$FirstInternal"".""$HoodDomain" if [ ! -f "$HoodZoneFile" ]; then { echo "\$TTL ${TTLReReExMi%% *}" echo "@ IN SOA $DNSSCRIPT_SERVER_NAME""."" $DNSSCRIPT_CONTACT_EMAIL (" echo " 1 ; Serial" echo " ""$(echo "$TTLReReExMi" | awk '{print $2}')"" ; Refresh" echo " ""$(echo "$TTLReReExMi" | awk '{print $3}')"" ; Retry" echo " ""$(echo "$TTLReReExMi" | awk '{print $4}')"" ; Expire" echo " ""$(echo "$TTLReReExMi" | awk '{print $5}')"" ) ; Negative Cache TTL" echo ";" echo "@ IN NS $DNSSCRIPT_SERVER_NAME"".""" GetOwnGlueRecords "$CommunityDomain" "$HoodDomain" "$MasterFile" echo ";" } > "$HoodZoneFile" fi ./update-hoodzone.sh "$HoodZoneFile" "$HoodDomain" "$Subnets" "$InternalViews" HoodForwardZones="$ForwardZones $HoodDomain""/""$HoodZoneFile" for Subnet in $Subnets; do ReverseDomains="$(GetReverseDomains "$Subnet")" for RDomain in $ReverseDomains; do ReverseZoneFileFullPath="$ZoneFilesFolder""$(GetReverseZoneFileFromZone "${RDomain%*.}")" ./update-rdnszone.sh "$RDomain" "$HoodForwardZones" "$ReverseZoneFileFullPath" "$TTLReReExMi" "$InternalViews" for IView in $InternalViews; do InsertZoneToIncludeFile "${RDomain%*.}" "$ReverseZoneFileFullPath" "$TempFolder""$IView"".conf" done done done if [ -n "$CommunityExternDomain" ]; then HoodExternDomain="${Hood%%\#*}"".""$CommunityExternDomain" else HoodExternDomain="" fi if [ -n "$ExternalView" ]; then ExternFile="$ZoneFilesFolder""db.""$ExternalView"".""$HoodDomain" elif [ -n "$HoodExternDomain" ]; then ExternFile="$ZoneFilesFolder""db.""$HoodExternDomain" else ExternFile="" fi if [ -n "$ExternFile" ]; then ./update-extzone.sh "$HoodZoneFile" "$ExternFile" "$HoodDomain" "$ExternalView" "$HoodExternDomain" "$InternalViews" fi InsertZoneToViews "$InternalViews" "$ZoneFilesFolder" "$HoodDomain" "$HoodZoneFile" "$TempFolder" "$DNSSECPolicy" InsertZoneToViews "$ExternalView" "$ZoneFilesFolder" "$HoodDomain" "$ExternFile" "$TempFolder" "$DNSSECPolicy" if [ -n "$HoodExternDomain" ]; then InsertZoneToViews "$InternalViews" "$ZoneFilesFolder" "${Hood%%\#*}"".""$CommunityExternDomain" "$ExternFile" "$TempFolder" "$DNSSECPolicy" InsertZoneToViews "$ExternalView" "$ZoneFilesFolder" "${Hood%%\#*}"".""$CommunityExternDomain" "$ExternFile" "$TempFolder" "$DNSSECPolicy" fi done ./update-public-acl.sh "$BindIcvpnAclTmp" "$RemoteLocation" "$RoutingTables" ReConfigBind=0 UpdateBindConfig() { if [ -f "$1" ] && ! cmp -s "$1" "$2"; then mv "$1" "$2" ReConfigBind=1 else rm -f "$1" fi } UpdateBindConfig "$BindIcvpnAclTmp" "$BindIcvpnAcl" for IView in $InternalViews; do UpdateBindConfig "$TempFolder""$IView"".conf" "$BindIncludeFileFolder""$IView"".conf" done if [ -n "$ExternalView" ]; then UpdateBindConfig "$TempFolder""$ExternalView"".conf" "$BindIncludeFileFolder""$ExternalView"".conf" fi if [ $ReConfigBind -ne 0 ] || [ -f "/tmp/dnsscript-forcereconf" ]; then if [ $((DNSSCRIPT_BIND_RELOAD_VER)) -eq 0 ]; then systemctl restart bind9 elif [ $((DNSSCRIPT_BIND_RELOAD_VER)) -eq 1 ]; then rndc reconfig elif [ $((DNSSCRIPT_BIND_RELOAD_VER)) -eq 2 ]; then /etc/init.d/named restart fi rm -f "/tmp/dnsscript-forcereconf" fi