diff --git a/usr/lib/ffdns/dns-functions.sh b/usr/lib/ffdns/dns-functions.sh index b8f18fe..ab4ae6e 100755 --- a/usr/lib/ffdns/dns-functions.sh +++ b/usr/lib/ffdns/dns-functions.sh @@ -1,7 +1,7 @@ #!/bin/sh # SPDX-License-Identifier: GPL-3.0 # -# freifunk-franken dns-scipts (c) 2021 Blackyfff +# freifunk-franken dns-scipts (c) 2021-2022 Blackyfff GetZoneFileSerial() { if [ -f "$1" ]; then @@ -204,17 +204,23 @@ GetOwnKeysForZone () { Domain="$2" if [ -n "$DNSSECKeyFolder" ];then for OwnKeyFile in "$DNSSECKeyFolder""K""$Domain"".+"*".key"; do - Removed="$(sed -ne 's/^; Delete: \(\S\{12\}\).*/\1/p' "$OwnKeyFile")" - if [ -n "$Removed" ]; then - Removed="$(date -u -d "$Removed" '+%s')" - CurDate="$(date -u '+%s')" - if [ $((CurDate - Removed)) -le 172800 ]; then - Removed="" + if ! [ "$OwnKeyFile" = "$DNSSECKeyFolder""K""$Domain"".+*.key" ]; then + Removed="$(sed -ne 's/^; Delete: \(\S\{12\}\).*/\1/p' "$OwnKeyFile")" + RemovedSeconds="$(date -u -d "$Removed" '+%s' 2>/dev/null)" + if [ -z "$RemovedSeconds" ]; then + RemovedSeconds="$( echo "$Removed" | sed -ne 's/\(.\{4\}\)\(.\{2\}\)\(.\{2\}\)\(.\{2\}\)\(.\{2\}\).*/\1-\2-\3T\4:\5/p')" + RemovedSeconds="$(date -u -d "$RemovedSeconds" '+%s' 2>/dev/null)" + fi + if [ -n "$RemovedSeconds" ]; then + CurDate="$(date -u '+%s')" + if [ $((CurDate - RemovedSeconds)) -le 72000 ]; then + RemovedSeconds="" + fi + fi + if [ -z "$RemovedSeconds" ]; then + sed -ne '/^;/d;s/^'"$Domain"'\.\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Dd][Nn][Ss][Kk][Ee][Yy]\s\+\(.*\)$/_dnsseckeys\.'"$Domain"'\.\tIN TXT\t\"\2\"/p' "$OwnKeyFile" | \ + NormalizeZoneFileFormatting fi - fi - if [ -z "$Removed" ]; then - sed -ne '/^;/d;s/^'"$Domain"'\.\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Dd][Nn][Ss][Kk][Ee][Yy]\s\+\(.*\)$/_dnsseckeys\.'"$Domain"'\.\tIN TXT\t\"\2\"/p' "$OwnKeyFile" | \ - NormalizeZoneFileFormatting fi done fi @@ -225,9 +231,9 @@ UpdateDNSSECEntryCache () { CachedZoneFile="$3" DNSSECKeyFolder="$4" UpstreamIP="$5" - UpdateMaster=0 + TempFolder="$6" - [ -z "$UpstreamIP" ] || UpstreamIP="-b ""$UpstreamIP"" " + [ -z "$UpstreamIP" ] || UpstreamIP="-b""$UpstreamIP" Nameservers="$(GetAllZoneNameservers "$Domain" "$CachedZoneFile")" @@ -239,17 +245,24 @@ UpdateDNSSECEntryCache () { if [ -n "$DNSSECKeyFolder" ]; then for Nameserver in $Nameservers; do if [ "$Nameserver" = "$DNSSCRIPT_SERVER_NAME" ]; then - DNSKEYS="$( GetOwnKeysForZone "$DNSSECKeyFolder" "$Domain" )" + { + GetOwnKeysForZone "$DNSSECKeyFolder" "$Domain" | sort + GetDSForZone "$DNSSECKeyFolder" "$Domain" "$TempFolder" | NormalizeZoneFileFormatting + } > "$ZoneTempFolder""Keys.""$Nameserver" else - DNSKEYS="$(delv @"$Nameserver" "$UpstreamIP"_dnsseckeys."$Domain" TXT 2>/dev/null | \ + { + delv @"$Nameserver" "$UpstreamIP" "_dnsseckeys.""$Domain" TXT 2>/dev/null | \ sed -ne '/^;/d;s/^.*\sIN\s\+TXT\s\+"\(.*\)"$/'"$Domain"'.\tIN DNSKEY\t\1/p' | \ - NormalizeZoneFileFormatting )" + NormalizeZoneFileFormatting | sort + delv @"$Nameserver" "$UpstreamIP" "_cdskey.""$Domain" TXT 2>/dev/null | \ + sed -ne '/^;/d;s/^.*\sIN\s\+TXT\s\+"\(.*\)"$/'"$Domain"'.\tIN CDS\t\1/p' | \ + NormalizeZoneFileFormatting | sort + } > "$ZoneTempFolder""Keys.""$Nameserver" fi - if [ -n "$DNSKEYS" ] && [ "$DNSKEYS" != "$(cat "$ZoneTempFolder""OldKeys.""$Nameserver" 2>/dev/null)" ]; then - echo "$DNSKEYS" > "$ZoneTempFolder""Keys.""$Nameserver" - UpdateMaster=1 + if [ -n "$(cat "$ZoneTempFolder""Keys.""$Nameserver")" ] && ! cmp -s "$ZoneTempFolder""Keys.""$Nameserver" "$ZoneTempFolder""OldKeys.""$Nameserver"; then + echo "1" elif [ -f "$ZoneTempFolder""OldKeys.""$Nameserver" ]; then - mv "$ZoneTempFolder""OldKeys.""$Nameserver" "$ZoneTempFolder""Keys.""$Nameserver" + mv -f "$ZoneTempFolder""OldKeys.""$Nameserver" "$ZoneTempFolder""Keys.""$Nameserver" fi done fi @@ -257,23 +270,23 @@ UpdateDNSSECEntryCache () { SEDDomain="$(SEDifyHostname "$Domain")" ChildServers="$( sed -ne '/^\s*\(@\|'"$SEDDomain"'\.\)\s/!s/^\s*\(\S\+\)\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Nn][Ss]\s\+\(\S\+\);\?.*$/\1#\3/p' "$CachedZoneFile" | \ sed -e 's/\([^.]\)$/\1\.'"$Domain"'\./g;s/\.$//g;s/\([^.]\)#/\1\.'"$Domain"'\.#/g;s/\.#/#/g' )" - for ChildServer in $ChildServers; do - DNSKEYS="$(delv @"${ChildServer##*\#}" "$UpstreamIP""${ChildServer%%\#*}" CDS 2>/dev/null | \ - sed -ne '/^;/d;s/^.*\sIN\s\+CDS\s\+\(.*\)$/'"${ChildServer%%\#*}"'.\tIN DS\t\1/p' | \ - NormalizeZoneFileFormatting )" - if [ -n "$DNSKEYS" ]; then - DNSKEYS="$(echo "$DNSKEYS" | sed -e '/\sIN\s\+DS\s\+0\s\+0\s\+0\s\+0/d')" - if [ "$DNSKEYS" != "$(cat "$ZoneTempFolder""OldChildKeys.""$ChildServer" 2>/dev/null)" ]; then - [ -z "$DNSKEYS" ] || echo "$DNSKEYS" > "$ZoneTempFolder""ChildKeys.""$ChildServer" - UpdateMaster=1 - elif [ -n "$DNSKEYS" ]; then - mv "$ZoneTempFolder""OldChildKeys.""$ChildServer" "$ZoneTempFolder""ChildKeys.""$ChildServer" - elif [ -f "$ZoneTempFolder""OldKeys.""$Nameserver" ]; then - UpdateMaster=1 + for ChildServer in $ChildServers; do + { + delv @"${ChildServer##*\#}" "$UpstreamIP" "${ChildServer%%\#*}" CDS 2>/dev/null | \ + sed -ne '/^;/d;s/^.*\sIN\s\+CDS\s\+\(.*\)$/'"${ChildServer%%\#*}"'.\tIN DS\t\1/p' | \ + NormalizeZoneFileFormatting | sort + } > "$ZoneTempFolder""ChildKeys.""$ChildServer" + + if [ -n "$(cat "$ZoneTempFolder""ChildKeys.""$ChildServer")" ]; then + sed -i -e '/\sIN\s\+DS\s\+0\s\+0\s\+0\s\+0/d' "$ZoneTempFolder""ChildKeys.""$ChildServer" + if ! cmp -s "$ZoneTempFolder""ChildKeys.""$ChildServer" "$ZoneTempFolder""OldChildKeys.""$ChildServer"; then + echo "1" + elif [ -z "$(cat "$ZoneTempFolder""ChildKeys.""$ChildServer")" ] && [ -f "$ZoneTempFolder""OldKeys.""$Nameserver" ]; then + echo "1" fi elif [ -f "$ZoneTempFolder""OldChildKeys.""$Nameserver" ]; then - mv "$ZoneTempFolder""OldChildKeys.""$ChildServer" "$ZoneTempFolder""ChildKeys.""$ChildServer" + mv -f "$ZoneTempFolder""OldChildKeys.""$ChildServer" "$ZoneTempFolder""ChildKeys.""$ChildServer" fi done @@ -281,7 +294,6 @@ UpdateDNSSECEntryCache () { [ "$KeyFile" = "$ZoneTempFolder""Old*" ] || \ rm -f "$KeyFile" done - echo "$UpdateMaster" } ReloadZone() { if [ -n "$2" ]; then @@ -304,6 +316,74 @@ ReloadZone() { fi } +UCharToFile () { + printf %b "\x$(printf %x "$1")" >> "$2" +} + +GetDS () { + Owner="$(echo "$1" | sed -e 's/\./ /g')" + KeyTag="$2" + Protocol="$3" + Algo="$4" + KSK="$5" + TmpFolder="$6" + + > "$TmpFolder""DSbin" + + for SubString in $Owner; do + Length=${#SubString} + UCharToFile $((Length)) "$TmpFolder""DSbin" + echo -n "$SubString" >> "$TmpFolder""DSbin" + done + + UCharToFile $((0)) "$TmpFolder""DSbin" + UCharToFile $((KeyTag / 256)) "$TmpFolder""DSbin" + UCharToFile $((KeyTag % 256)) "$TmpFolder""DSbin" + UCharToFile $((Protocol)) "$TmpFolder""DSbin" + UCharToFile $((Algo)) "$TmpFolder""DSbin" + + echo "$KSK" | openssl base64 -d >> "$TmpFolder""DSbin" + + sha256sum "$TmpFolder""DSbin" | sed -e 's/\s.*//g' | awk '{print toupper($0)}' +} +GetDSForZone () { + DNSSECKeyFolder="$1" + Domain="$2" + TmpFolder="$3" + if [ -n "$DNSSECKeyFolder" ];then + > "$TmpFolder""KSKRemoved" + > "$TmpFolder""KSK" + for OwnKeyFile in "$DNSSECKeyFolder""K""$Domain"".+"*".key"; do + if ! [ "$OwnKeyFile" = "$DNSSECKeyFolder""K""$Domain"".+*.key" ] && \ + [ -n "$(sed -e '/^;/d;/^'"$Domain"'\.\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Dd][Nn][Ss][Kk][Ee][Yy]\s\+257/!d' "$OwnKeyFile")" ]; then + Removed="$(sed -ne 's/^; Delete: \(\S\{12\}\).*/\1/p' "$OwnKeyFile")" + RemovedSeconds="$(date -u -d "$Removed" '+%s' 2>/dev/null)" + if [ -z "$RemovedSeconds" ]; then + RemovedSeconds="$( echo "$Removed" | sed -ne 's/\(.\{4\}\)\(.\{2\}\)\(.\{2\}\)\(.\{2\}\)\(.\{2\}\).*/\1-\2-\3T\4:\5/p')" + RemovedSeconds="$(date -u -d "$RemovedSeconds" '+%s' 2>/dev/null)" + fi + Previous="$(cat "$TmpFolder""KSKRemoved")" + Previous="${Previous:-0}" + if [ $((RemovedSeconds)) -ge $((Previous)) ]; then + echo "$RemovedSeconds" > "$TmpFolder""KSKRemoved" + echo -n "$(echo "$OwnKeyFile" | sed -ne 's/^.\{'"$((${#DNSSECKeyFolder}+${#Domain}+2))"'\}+[^+]\++\(.*\)\.key/\1 /p')" > "$TmpFolder""KSK" + sed -ne '/^;/d;s/^'"$Domain"'\.\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Dd][Nn][Ss][Kk][Ee][Yy]\s\+\(.*\)$/\2/p' "$OwnKeyFile" >> "$TmpFolder""KSK" + fi + fi + done + + KSK="$(cat "$TmpFolder""KSK")" + if [ -n "$KSK" ]; then + KeyID="$(echo "$KSK" | sed -e 's/ .*//g')" + KeyTag="$(echo "$KSK" | sed -e 's/^[^ ]* //g;s/ .*//g')" + Protocol="$(echo "$KSK" | sed -e 's/^[^ ]* [^ ]* //g;s/ .*//g')" + Algo="$(echo "$KSK" | sed -e 's/^[^ ]* [^ ]* [^ ]* //g;s/ .*//g')" + KSK="$(echo "$KSK" | sed -e 's/^[^ ]* [^ ]* [^ ]* [^ ]* //g;s/ //g')" + echo -e "_cdskey.""$Domain"".\tIN TXT\t\"""$KeyID"" ""$Algo"" 2 ""$(GetDS "$Domain" "$KeyTag" "$Protocol" "$Algo" "$KSK" "$TmpFolder")""\"" + fi + fi +} + TraceErrAndExit() { echo "$1" 1>&2 exit 1 diff --git a/usr/lib/ffdns/update-dns-functions.sh b/usr/lib/ffdns/update-dns-functions.sh index 2ae037a..2ca584d 100755 --- a/usr/lib/ffdns/update-dns-functions.sh +++ b/usr/lib/ffdns/update-dns-functions.sh @@ -1,7 +1,7 @@ #!/bin/sh # SPDX-License-Identifier: GPL-3.0 # -# freifunk-franken dns-scipts (c) 2021 Blackyfff +# freifunk-franken dns-scipts (c) 2021-2022 Blackyfff SetupCache() { mkdir -p "$TempFolder""cache" @@ -43,8 +43,9 @@ UpdateMasterZone() { if [ -n "$ServeMasterZone" ]; then ZoneTempFolder="$TempFolder""cache/""$MasterDomain""/" - UpdateMaster="$(UpdateDNSSECEntryCache "$MasterDomain" "$ZoneTempFolder" "$CachedMasterFile" "$DNSSECKeyFolder" "$InternalUpstreamIP")" - if [ $((PostFetchMasterSerial)) -gt $((PreFetchMasterSerial)) ] || [ $UpdateMaster -ne 0 ] || [ ! -f "$MasterFile" ]; then + UpdateMaster="$(UpdateDNSSECEntryCache "$MasterDomain" "$ZoneTempFolder" "$CachedMasterFile" "$DNSSECKeyFolder" "$InternalUpstreamIP" "$TempFolder")" + + if [ $((PostFetchMasterSerial)) -gt $((PreFetchMasterSerial)) ] || [ -n "$UpdateMaster" ] || [ ! -f "$MasterFile" ]; then cp -f "$CachedMasterFile" "$CachedMasterFile""I" for KeyFile in "$ZoneTempFolder"*; do [ "$KeyFile" = "$ZoneTempFolder""*" ] || \ @@ -59,7 +60,7 @@ UpdateMasterZone() { else LocalMasterSerial=$((PostFetchMasterSerial)) fi - mv "$CachedMasterFile""I" "$MasterFile" + awk '/^$/ || !a[$0]++' "$CachedMasterFile""I" > "$MasterFile" ReloadZone "$MasterDomain" "$InternalViews" "$ZoneFilesFolder" fi @@ -89,14 +90,18 @@ UpdateExternal() { ExtDomainFile="$ZoneFilesFolder""db.""$FirstInternalView"".""$ExternDomain" ZoneTempFolder="$TempFolder""cache/""$ExternDomain""/" cp -f "$ExternalZoneFile" "$CachedZoneFile" - [ -z "$DNSSECKeyFolder" ] || sed -i -e '/^\s*_dnsseckeys\./d' "$CachedZoneFile" + if [ -n "$DNSSECKeyFolder" ]; then + sed -i -e '/^\s*_dnsseckeys\./d' "$CachedZoneFile" + sed -i -e '/^\s*\S\+\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Dd][Nn][Ss][Kk][Ee][Yy]/d' "$CachedZoneFile" + fi + [ -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" "$InternalUpstreamIP")" - if [ $UpdateExternView -ne 0 ] || [ $UpdateExternDomain -ne 0 ]; then + UpdateExternDomain="$(UpdateDNSSECEntryCache "$ExternDomain" "$ZoneTempFolder" "$CachedZoneFile" "$DNSSECKeyFolder" "$InternalUpstreamIP" "$TempFolder")" + if [ $UpdateExternView -ne 0 ] || [ -n "$UpdateExternDomain" ]; then for KeyFile in "$ZoneTempFolder"*; do [ "$KeyFile" = "$ZoneTempFolder""*" ] || \ cat "$KeyFile" >> "$CachedZoneFile" @@ -108,7 +113,7 @@ UpdateExternal() { sed -i -e 's/^\(\s*\)'"$SerialIntern"'\(\s*;\s*[Ss]erial.*\)$/\1'"$LocalExtDomainMasterSerial"'\2/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" + awk '/^$/ || !a[$0]++' "$CachedZoneFile" > "$ExtDomainFile" ReloadZone "$ExternDomain" "$InternalViews" "$ZoneFilesFolder" ReloadZone "$ExternDomain" "$ExternalView" "$ZoneFilesFolder" fi diff --git a/usr/lib/ffdns/update-dns.sh b/usr/lib/ffdns/update-dns.sh index bb3b7ce..428e306 100755 --- a/usr/lib/ffdns/update-dns.sh +++ b/usr/lib/ffdns/update-dns.sh @@ -3,12 +3,12 @@ # # freifunk-franken dns-scipts (c) 2016 mayosemmel # (c) 2020-2021 Fabian Bläse -# (c) 2021 Blackyfff +# (c) 2021-2022 Blackyfff # exit script when command fails set -e -export DNSSCRIPT_VERSION="0.9.2" +export DNSSCRIPT_VERSION="0.9.4" . /etc/ffdns/community.conf . /etc/ffdns/local.conf diff --git a/usr/lib/ffdns/update-hoodzone.sh b/usr/lib/ffdns/update-hoodzone.sh index 48622d6..8730148 100755 --- a/usr/lib/ffdns/update-hoodzone.sh +++ b/usr/lib/ffdns/update-hoodzone.sh @@ -1,7 +1,7 @@ #!/bin/sh # SPDX-License-Identifier: GPL-3.0 # -# freifunk-franken dns-scipts (c) 2021 Blackyfff +# freifunk-franken dns-scipts (c) 2021-2022 Blackyfff . ./dns-functions.sh @@ -51,7 +51,7 @@ NewLeases="$(echo "$NewLeases" | UpdateZone="$(UpdateDNSSECEntryCache "$Domain" "$ZoneTempFolder" "$HoodZoneFile")" -if [ "$NewLeases" != "$OldLeases" ] || [ $UpdateZone -ne 0 ]; then +if [ "$NewLeases" != "$OldLeases" ] || [ -n "$UpdateZone" ]; then NewSerial="$(GetZoneFileSerial "$HoodZoneFile")" NewSerial=$((NewSerial+1)) sed -i -e 's/^\(\s*\)\(\S\+\)\(\s*;\s*Serial.*\)/\1'"$NewSerial"'\3/g' "$HoodZoneFile" @@ -65,4 +65,4 @@ if [ "$NewLeases" != "$OldLeases" ] || [ $UpdateZone -ne 0 ]; then cat "$KeyFile" >> "$HoodZoneFile" done ReloadZone "$Domain" "$View" "$ZoneFilesFolder" -fi +fi \ No newline at end of file