#!/bin/sh # SPDX-License-Identifier: GPL-3.0 # # freifunk-franken dns-scipts (c) 2016 mayosemmel # (c) 2020-2021 Fabian Bläse # (c) 2021 Blackyfff # exit script when command fails set -e . /etc/ffdns/community.conf . /etc/ffdns/local.conf export DNSSCRIPT_CONTACT_EMAIL export DNSSCRIPT_SERVER_NAME export DNSSCRIPT_BIND_RELOAD_VER cd /usr/lib/ffdns/ . ./dns-functions.sh MasterDomain="$CommunityDomain" [ -z "$SubCommunityDomain" ] || MasterDomain="$SubCommunityDomain"".""$MasterDomain" if [ -n "$CommunityExternPrefix" ];then MasterExternDomain="$CommunityExternPrefix"".""$CommunityDomain" [ -z "$SubCommunityDomain" ] || MasterExternDomain="$SubCommunityDomain"".""$MasterExternDomain" fi FirstInternal="$( echo "$InternalViews" | sed -ne 's/^\(\S\+\)\s.*$/\1/p')" # ForwardZones: "/" ; optionaly multiple " ""/" no spaces in full filename ForwardZones="$MasterDomain""/""$ZoneFilesFolder""db.""$FirstInternal"".""$MasterDomain" BindIcvpnAclTmp="$TempFolder""icvpn-acl.conf" BindIcvpnAcl="$BindIncludeFileFolder""icvpn-acl.conf" [ -n "$DNSSECPolicy" ] || DNSSECKeyFolder="" mkdir -p "$TempFolder""cache" for IView in $InternalViews; do rm -f "$TempFolder""$IView"".conf" done rm -f "$TempFolder""$ExternalView"".conf" CachedMasterFile="$TempFolder""cache/db.""$MasterDomain" PreFetchMasterSerial="$(GetZoneFileSerial "$CachedMasterFile")" curl -s -S -f "$RemoteLocation""db.""$MasterDomain" --output "$CachedMasterFile" && [ -f "$CachedMasterFile" ] && echo "" >> "$CachedMasterFile" || : PostFetchMasterSerial="$(GetZoneFileSerial "$CachedMasterFile")" [ -n "$SubCommunityDomain" ] || ServeMasterZone="$( GetAllZoneNameservers "$MasterDomain" "$CachedMasterFile" | awk '{for(i=NF;i>0;--i) if($i=="'"$DNSSCRIPT_SERVER_NAME"'") {printf 1}}')" if [ -n "$MasterExternDomain" ]; 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 UpdateExternal() { CachedZoneFile="$TempFolder""cache/db.""$InternalDomain""E" UpdateExternView=0 if [ -n "$ExternalView" ] || [ -n "$ExternDomain" ]; then SerialExtern="$(GetZoneFileSerial "$ExternalZoneFile")" if [ $((SerialIntern)) -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' "$InternalZoneFile" \ > "$ExternalZoneFile" UpdateExternView=1 ReloadZone "$InternalDomain" "$ExternalView" "$ZoneFilesFolder" fi fi if [ -n "$ExternDomain" ]; then ExtDomainFile="$ZoneFilesFolder""db.""$FirstInternal"".""$ExternDomain" ZoneTempFolder="$TempFolder""cache/""$ExternDomain""/" cp -f "$ExternalZoneFile" "$CachedZoneFile" [ -z "$DNSSECKeyFolder" ] || sed -i -e '/^\s*_dnsseckeys\./d' "$CachedZoneFile" [ -n "$(sed -e '/^\s*\(@\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Nn][Ss]\)\s/!d' "$CachedZoneFile")" ] || \ 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' "$CachedZoneFile" sed -i -e 's/^\s*'"$CommunityExternPrefix"'\s/@ /g;/^\s*\S\+\.\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Dd][Ss]\s/d' "$CachedZoneFile" UpdateExternDomain="$(UpdateDNSSECEntryCache "$ExternDomain" "$ZoneTempFolder" "$CachedZoneFile" "$DNSSECKeyFolder")" if [ $UpdateExternView -ne 0 ] || [ $UpdateExternDomain -ne 0 ]; then for KeyFile in "$ZoneTempFolder"*; do [ "$KeyFile" = "$ZoneTempFolder""*" ] || \ cat "$KeyFile" >> "$CachedZoneFile" done LocalExtDomainMasterSerial="$(GetZoneFileSerial "$ExtDomainFile")" if [ $((SerialIntern)) -le $((LocalExtDomainMasterSerial)) ]; then LocalExtDomainMasterSerial=$((LocalExtDomainMasterSerial+1)) sed -i -e 's/^\(\s*\)'"$SerialIntern"'\(\s*;\s*[Ss]erial.*\)$/\1'"$LocalExtDomainMasterSerial"'\3/g' "$CachedZoneFile" sed -i -e 's/^\(\s*\S\+\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Ss][Oo][Aa]\s\+\S\+\s\+\S\+\s\+\)'"$SerialIntern"'\(\s\+.*\)$/\1'"$LocalExtDomainMasterSerial"'\3/g' "$CachedZoneFile" fi mv "$CachedZoneFile" "$ExtDomainFile" ReloadZone "$ExternDomain" "$InternalViews" "$ZoneFilesFolder" ReloadZone "$ExternDomain" "$ExternalView" "$ZoneFilesFolder" fi InsertZoneToViews "$InternalViews" "$ZoneFilesFolder" "$ExternDomain" "$ExtDomainFile" "$TempFolder" "$DNSSECPolicy" InsertZoneToViews "$ExternalView" "$ZoneFilesFolder" "$ExternDomain" "$ExtDomainFile" "$TempFolder" "$DNSSECPolicy" fi } if [ -n "$ServeMasterZone" ] || [ -n "$ServeExtZone" ]; then sed -i -e '/^\s*_dnsseckeys\./d' "$CachedMasterFile" FileForExternGeneration="$CachedMasterFile" if [ -n "$ExternalView" ]; then ExternFile="$ZoneFilesFolder""db.""$ExternalView"".""$MasterDomain" else ExternFile="$ZoneFilesFolder""db.extern.""$MasterDomain" fi LocalMasterSerial=$((PostFetchMasterSerial)) if [ -n "$ServeMasterZone" ]; then MasterFile="$ZoneFilesFolder""db.""$FirstInternal"".""$MasterDomain" FileForExternGeneration="$MasterFile" ZoneTempFolder="$TempFolder""cache/""$MasterDomain""/" UpdateMaster="$(UpdateDNSSECEntryCache "$MasterDomain" "$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 "$MasterDomain" "$InternalViews" "$ZoneFilesFolder" InsertZoneToViews "$InternalViews" "$ZoneFilesFolder" "$MasterDomain" "$MasterFile" "$TempFolder" "$DNSSECPolicy" fi if [ -n "$ExternalView" ]; then InsertZoneToIncludeFile "$MasterDomain" "$ExternFile" "$TempFolder""$ExternalView"".conf" "$DNSSECPolicy" fi fi InternalZoneFile="$FileForExternGeneration" ExternalZoneFile="$ExternFile" InternalDomain="$MasterDomain" ExternDomain="$MasterExternDomain" SerialIntern="$LocalMasterSerial" UpdateExternal fi if [ -z "$MasterFile" ]; then MasterFile="$ZoneFilesFolder""db.""$FirstInternal"".""$MasterDomain" cp -f "$CachedMasterFile" "$MasterFile" 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 # set shorter TTL for Hoods TTLReReExMi="420 360 180 1800 360" Hoods="$(GetOwnHoods "$MasterDomain" "$MasterFile")" DNSSECKeyFolder="" for Hood in $Hoods; do HoodDomain="${Hood%%\#*}"".""$MasterDomain" 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 "$MasterDomain" "$HoodDomain" "$MasterFile" echo ";" } > "$HoodZoneFile" fi ZoneTempFolder="$TempFolder""cache/""$HoodDomain""/" ./update-hoodzone.sh "$HoodZoneFile" "$HoodDomain" "$Subnets" "$InternalViews" "$ZoneTempFolder" "$ZoneFilesFolder" InsertZoneToViews "$InternalViews" "$ZoneFilesFolder" "$HoodDomain" "$HoodZoneFile" "$TempFolder" "$DNSSECPolicy" 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 "$MasterExternDomain" ]; then HoodExternDomain="${Hood%%\#*}"".""$MasterExternDomain" 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 if [ -n "$ExternalView" ]; then InsertZoneToIncludeFile "$HoodDomain" "$ExternFile" "$TempFolder""$ExternalView"".conf" "$DNSSECPolicy" fi InternalZoneFile="$HoodZoneFile" ExternalZoneFile="$ExternFile" InternalDomain="$HoodDomain" ExternDomain="$HoodExternDomain" SerialIntern="$(GetZoneFileSerial "$InternalZoneFile")" UpdateExternal 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