From e17d68f25d39f609133d20b99993690569262da0 Mon Sep 17 00:00:00 2001 From: Blackyfff Date: Thu, 14 Jan 2021 20:46:10 +0100 Subject: [PATCH] parse hoods and reversezones from zonefile; new zonefile-filenames; --- README.md | 58 +++++++++++------- dns-functions.sh | 134 ++++++++++++++++++++++++++++++++++++++--- update-dns.sh | 109 ++++++++++++++++----------------- update-extzone.sh | 2 +- update-hoodzone.sh | 52 ++++++++++++++++ update-rdnszone.sh | 23 +++---- update-remotedns.sh | 9 +++ update-remoteleases.sh | 10 +++ 8 files changed, 298 insertions(+), 99 deletions(-) mode change 100644 => 100755 dns-functions.sh mode change 100644 => 100755 update-dns.sh mode change 100644 => 100755 update-extzone.sh create mode 100755 update-hoodzone.sh mode change 100644 => 100755 update-rdnszone.sh create mode 100755 update-remotedns.sh create mode 100755 update-remoteleases.sh diff --git a/README.md b/README.md index 5f79f4f..6bfe1bf 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # fff-scripts Dieses Git enthält eine Sammlung an Scripten zur Aktualisierung der Zonendatei für fff.community. -Außerdem gibt es Skripte, die aus der Forward-Zone und optional eigener Subdomain passende Reverse-Zones für unsere internen RFC 1918 und RFC 4193 Adressen erzeugen. +Außerdem gibt es Skripte, die aus der Forward-Zone und optional eigener Subdomain (durch community-Zonefile gesteuert) passende Reverse-Zones für unsere internen RFC 1918 und RFC 4193 Adressen erzeugen. ## Installation @@ -18,17 +18,19 @@ git clone https://git.freifunk-franken.de/freifunk-franken/dns-scripts.git /srv/ ``` #### konfigurieren -In der Datei update-dns.sh kann die Verwaltung einer Subdomain incl. Reversezone aktiviert werden. +In der Datei update-dns.sh die Konfigurationsparameter setzen. #### Cron anlegen Schließlich muss noch ein Cron angelegt werden, der regelmäßig das Skript aufruft, welches die Zonendatei aktualisiert und die Reverse-Skripte aufruft: ``` -1-59/5 * * * * /srv/fff-scripts/update-dns.sh +1-59/5 * * * * /usr/lib/ffdns/update-dns.sh ``` #### DNS-Server konfigurieren -Dann muss nur noch der DNS Server, z.B. `bind`, für die entsprechenden Zonen eingerichtet werden: +Dann muss nur noch der DNS Server, z.B. `bind`, für die entsprechenden Zonen eingerichtet werden, +die Zonenfiles werden durch die Scripte angelegt, für jedes Zonefile muss ein Eintrag in den entsprechenden +view: Einfachste Konfiguration: ``` @@ -37,17 +39,17 @@ $ cat named.conf.local zone "50.10.in-addr.arpa" { type master; - file "/var/lib/bind/db.50.10"; + file "/var/lib/bind/db.10.50"; allow-query { any; }; }; zone "83.10.in-addr.arpa" { type master; - file "/var/lib/bind/db.83.10"; + file "/var/lib/bind/db.10.83"; allow-query { any; }; }; zone "d.b.9.2.2.0.6.5.3.4.d.f.ip6.arpa" { type master; - file "/var/lib/bind/db.fd43-5602-29bd"; + file "/var/lib/bind/db.f.d.4.3.5.6.0.2.2.9.b.d"; allow-query { any; }; }; @@ -78,6 +80,14 @@ acl icvpnrange { }; [..] + +options { + [..] + check-names master warn; #Important for Hostnames with _ (example: HUAWEI_P30_lite ) +} + +[..] + view "icvpn-internal-view" { match-clients { icvpnrange; localhost; }; @@ -90,33 +100,35 @@ view "icvpn-internal-view" { zone ".50.10.in-addr.arpa" { type master; - file "/var/lib/bind/db..50.10"; - }; + file "/var/lib/bind/db.10.50."; + }; # Subnetz kann auch in 10.83 liegen zone ".d.b.9.2.2.0.6.5.3.4.d.f.ip6.arpa" { type master; - file "/var/lib/bind/db.fd43-5602-29bd-"; + file "/var/lib/bind/db.f.d.4.3.5.6.0.2.2.9.b.d."; }; - zone "fff.community" { - type master; - file "/var/lib/bind/db.fff.community"; - }; - zone "50.10.in-addr.arpa" { - type master; - file "/var/lib/bind/db.50.10"; + type master; + file "/var/lib/bind/db.10.50"; + allow-query { any; }; }; - zone "83.10.in-addr.arpa" { - type master; - file "/var/lib/bind/db.83.10"; + type master; + file "/var/lib/bind/db.10.83"; + allow-query { any; }; }; - zone "d.b.9.2.2.0.6.5.3.4.d.f.ip6.arpa" { - type master; - file "/var/lib/bind/db.fd43-5602-29bd"; + type master; + file "/var/lib/bind/db.f.d.4.3.5.6.0.2.2.9.b.d"; + allow-query { any; }; + }; + + zone "fff.community" { + type master; + file "/srv/fff-dns/db.fff.community"; + allow-query { any; }; }; include "/var/lib/bind/icvpn-zones.conf"; # Nicht vergessen ;) diff --git a/dns-functions.sh b/dns-functions.sh old mode 100644 new mode 100755 index 051928b..c6e36ec --- a/dns-functions.sh +++ b/dns-functions.sh @@ -1,21 +1,139 @@ #!/bin/sh GetZoneFileSerial() { - INSOASpec="^\s*\S\+\s\+\([0-9]*\s\)\?\s*IN\s\+SOA\s\+" - FirstSOALineAndFollowing="/""$INSOASpec""/,\$!d;" - RemoveComments=":a;s/;.*$//g;" - RemoveLineBreaks=":a;N;\$!ba;s/\n//g;" - SearchPrintSerial="s/""$INSOASpec""\S\+\s\+\S\+\s\+\((\s\)\?\s*\([0-9]*\).*/\3/i" - - ZoneSerial=$(sed -e "$FirstSOALineAndFollowing""$RemoveComments""$RemoveLineBreaks""$SearchPrintSerial" "$1") + if [ -f "$1" ]; then + INSOASpec="^\s*\S\+\s\+\([0-9]*\s\)\?\s*IN\s\+SOA\s\+" + FirstSOALineAndFollowing="/""$INSOASpec""/,\$!d;" + RemoveComments=":a;s/;.*$//g;" + RemoveLineBreaks=":a;N;\$!ba;s/\n//g;" + SearchPrintSerial="s/""$INSOASpec""\S\+\s\+\S\+\s\+\((\s\)\?\s*\([0-9]*\).*/\3/i" + + ZoneSerial=$(sed -e "$FirstSOALineAndFollowing""$RemoveComments""$RemoveLineBreaks""$SearchPrintSerial" "$1") + fi echo "${ZoneSerial:-0}" } +FillIPv4MissingBlocks() { + echo "$1" | sed -ne 's/^\([^.]\+\)\.\(\([^.]\+\)\.\)\?\(\([^.]\+\)\.\)\?\([^.]\+\)$/\1.\3.\5.\6/p' | sed -r 's/\.\./\.0\./g;s/\.\./\.0\./g' +} +GetReverseIPv4Domains() { + IPFilled="$(FillIPv4MissingBlocks "${1%/*}")" + Mask="${1##*/}" + Statics=$((Mask / 8)) + Filler=$((Mask % 8)) + RevDomain="$(echo "$IPFilled" | awk -F. '{for(i='"$Statics"';i>0;--i)printf "."$i}')"".in-addr.arpa." + if [ $Filler -eq 0 ]; then + echo "${RevDomain#.}" + else + Filler=$((8 - $Filler)) + Filler=$((1 << $Filler)) + Start=$(echo "$IPFilled" | awk -F. '{printf $'"$((Statics+1))"'}') + Start=$((Start - Start % Filler)) + for Sub in $(seq $Start $((Start + Filler - 1))); do + echo "$Sub""$RevDomain" + done + fi +} +FillIPv6Zeroes() { + echo "$1" | awk -F: 'BEGIN {OFS=""}{ FillCount=9-NF; for(i=1;i<=NF;i++){if(length($i) == 0){if(i==NF) {$i="0000";} else {for(j=1;j<=FillCount;j++){$i=($i "0000");}}} else {$i=substr(("0000" $i), length($i)+1);}}; print}' +} +GetReverseIPv6Domains() { + IPFilled="$(FillIPv6Zeroes "$(echo "${1%/*}" | awk '{print tolower($0)}')")" + Mask="${1##*/}" + Statics=$((Mask / 4)) + Filler=$((Mask % 4)) + RevDomain="$(echo "$IPFilled" | awk '{ for(i='"$Statics"';i>0;i--)x=x "." substr($0,i,1);}END{print x}')"".ip6.arpa." + if [ $Filler -eq 0 ]; then + echo "${RevDomain#.}" + else + Filler=$((4 - $Filler)) + Filler=$((1 << $Filler)) + Start="$(printf %d 0x"$(echo "$IPFilled" | awk 'BEGIN{FS=""}{printf $'"$((Statics+1))"'}')")" + Start=$((Start - Start % Filler)) + for Sub in $(seq $Start $((Start + Filler - 1))); do + echo "$(printf %x "$Sub")""$RevDomain" + done + fi +} +GetReverseDomains() { + Subnet="$1" + if IsValidIPv4Subnet "$Subnet"; then + GetReverseIPv4Domains "$Subnet" + elif IsValidIPv6Subnet "$Subnet"; then + GetReverseIPv6Domains "$Subnet" + fi +} +GetServernameSEDEntry() { + CommunityName="$1" + ServerName="$DNSSCRIPT_SERVER_NAME" + if [ -z "${ServerName##*$CommunityName}" ]; then + ServerName="\(""$ServerName"".\|""${ServerName%*.$CommunityName}""\)" + else + ServerName="\(""$ServerName"".\)" + fi + + echo "$ServerName" | sed -r 's/\./\\\./g' +} +GetOwnGlueRecords() { + ServerName="$DNSSCRIPT_SERVER_NAME" + if [ ! -z "${ServerName##*$1}" ]; then + ServerName="$ServerName""$1" + fi + ServerName="$ServerName""." + echo "$(sed -ne 's/^\s*'"$(GetServernameSEDEntry "$1")"'\(\s\+[Ii][Nn]\s\+\([Aa]\|[Aa]\{4\}\)\s\+.*\)$/'"$ServerName"'\2/p' "$2")" +} +GetOwnHoods() { + Entries="$(sed -ne "s/^\s*\(\S*\).*\s\+[Ii][Nn]\s\+[Nn][Ss]\s\+""$(GetServernameSEDEntry "$1")""\s*;\s*Subnets:\s*\([^;]*\)/\1 \3/p" "$2")" + Entries="$(echo "$Entries" | sed -r 's/\s+/#/g')" + + echo "$Entries" +} +IsValidIPv4Subnet() { + [ -n "$(echo "$1" | sed -e '/[^/]*\/\([12]\?[0-9]\|3[0-2]\)$/!d')" ] && IsValidIPv4 "${1%/*}" + return $? +} +IsValidIPv4() { + [ -n "$(echo "$1" | sed -e '/^\(\(25[0-5]\|\(2[0-4]\|1[0-9]\|[1-9]\)\?[0-9]\)\.\)\{0,3\}\(25[0-5]\|\(2[0-4]\|1[0-9]\|[1-9]\)\?[0-9]\)$/!d')" ] + return $? +} +IsValidIPv6Subnet() { + [ -n "$(echo "$1" | sed -e '/[^/]*\/\([1-9]\?[0-9]\|1\([01][0-9]\|2[0-8]\)\)$/!d')" ] && IsValidIPv6 "${1%/*}" + return $? +} +IsValidIPv6() { + Max8BlocksMax4Hex="/^\([0-9a-fA-F]\{0,4\}[:]\{1,2\}\)\{1,7\}[0-9a-fA-F]\{0,4\}$/!d;" + MaxOneDoubleColon="/^.*::.*::.*$/d;" + SingleColon8BlocksOrNoSingleColonBeginEnd="/^\(\([^:]\+:\)\{7\}[^:]\+\|\(\|[^:].*\)::\(\|.*[^:]\)\)$/!d" + [ -n "$(echo "$1" | sed -e "$Max8BlocksMax4Hex""$MaxOneDoubleColon""$SingleColon8BlocksOrNoSingleColonBeginEnd")" ] + return $? +} +IPv4IsInSubnet() { + IPFilled="$(FillIPv4MissingBlocks "$1")" + SubnetIPFilled="$(FillIPv4MissingBlocks "${2%/*}")" + Mask="${2##*/}" + Statics=$((Mask / 8)) + BlockMask=$((Mask % 8)) + IPStaticPart="$(echo "$IPFilled" | awk -F. '{for(i='"$Statics"';i>0;--i)printf "."$i}')" + SubnetStaticPart="$(echo "$SubnetIPFilled" | awk -F. '{for(i='"$Statics"';i>0;--i) printf "."$i}')" + AreEqual="$([ "$IPStaticPart" = "$SubnetStaticPart" ]; echo "$?")" + if [ $AreEqual -eq 0 ] && [ $BlockMask -ne 0 ]; then + BlockMask=$((8 - $BlockMask)) + BlockMask=$((-1 << $BlockMask)) + IPBlock=$(echo "$IPFilled" | awk -F. '{printf $'"$((Statics+1))"'}') + SubnetBlock=$(echo "$SubnetIPFilled" | awk -F. '{printf $'"$((Statics+1))"'}') + IPBlock=$(($IPBlock & $BlockMask)) + SubnetBlock=$(($SubnetBlock & $BlockMask)) + AreEqual="$([ $IPBlock -eq $SubnetBlock ]; echo "$?")" + fi + return $AreEqual +} ReloadZone() { if [ $DNSSCRIPT_BIND_RELOAD_VER -eq 0 ]; then systemctl reload bind9 elif [ $DNSSCRIPT_BIND_RELOAD_VER -eq 1 ]; then - rndc reload "$1" IN "$2" + for Zone in $2; do + rndc reload "$1" IN "$Zone" + done else /etc/init.d/named reload fi diff --git a/update-dns.sh b/update-dns.sh old mode 100644 new mode 100755 index f634b7a..01b2563 --- a/update-dns.sh +++ b/update-dns.sh @@ -1,94 +1,95 @@ #!/bin/sh -. ./dns-functions.sh - # exit script when command fails set -e -export DNSSCRIPT_CONTACT_EMAIL=franken.freifunk.net. -export DNSSCRIPT_SERVER_NAME=fff-gw-herpf01.fff.community. -UpdateScriptsFolder="/srv/fff-scripts/" -ZoneFilesFolder="/var/lib/bind/" +# Communityconfig CommunityDomain="fff.community" - -# Einkommentieren und für eigene Hood setzen -#HoodSubDomain="herpf" # File unter "$ZoneFilesFolder""db.""$HoodSubDomain"".""$CommunityDomain" -#HoodSubIPv4="250" # nur /24er Netze -#HoodSubIPv6="62" # nur /64er Netze - -# 0 -> Debian o.a. systemctl reload bind9 -# 1 -> rndc benutzen um nur die jeweilige Zone neu zu laden (empfohlen; rndc muss eingerichtet werden) -# 2 -> für OpenWRT /etc/init.d/named reload -# -export DNSSCRIPT_BIND_RELOAD_VER=1 - -# Wenn rndc benutzt wird den internen und externen View setzen -#InternalView="icvpn-internal-view" -#ExternalView="external-view" # ExternalView steuert auch die Erstellung der externen Zone-Files - +CommunitySubnets="10.50.0/16 10.83.0/16 fd43:5602:29bd::/48" MasterFileRemoteLocation="https://git.freifunk-franken.de/freifunk-franken/dns/raw/branch/master/db.fff.community" +# Serverconfig +export DNSSCRIPT_CONTACT_EMAIL=info.freifunk-herpf.de. +# DNSSCRIPT_SERVER_NAME must be the server given in community zone files NS entry +export DNSSCRIPT_SERVER_NAME=dns.herpf.fff.community +UpdateScriptsFolder="/usr/lib/ffdns/" +ZoneFilesFolder="/etc/bind/fff/" + +# 0 -> Debian (and like) systemctl reload bind9 +# 1 -> use rndc to reload zone (recommended; rndc needs setup first) +# 2 -> OpenWRT /etc/init.d/named reload +# +export DNSSCRIPT_BIND_RELOAD_VER=0 + +# only necessary when rndc is used; sets the internal and external views +InternalViews="icvpn-internal-view icvpn-internal-dns64-view" +ExternalView="external-view" + # TTL Refresh Retry Expire Minimum TTLReReExMi="3600 2000 6400 2419200 86400" -# ForwardZones Schema: "/" ; optional mehrfach " ""/" Keine Leerzeichen im Ordner/File erlaubt +# ForwardZones: "/" ; optionaly multiple " ""/" no spaces in full filename ForwardZones="$CommunityDomain""/""$ZoneFilesFolder""db.""$CommunityDomain" ############################################################# +cd "$UpdateScriptsFolder" +. ./dns-functions.sh MasterFile="$ZoneFilesFolder""db.""$CommunityDomain" - PreFetchMasterSerial="$(GetZoneFileSerial "$MasterFile")" curl "$MasterFileRemoteLocation" --output "$MasterFile" PostFetchMasterSerial="$(GetZoneFileSerial "$MasterFile")" if [ $((PostFetchMasterSerial)) -gt $((PreFetchMasterSerial)) ]; then - ReloadZone "$CommunityDomain" "$InternalView" + ReloadZone "$CommunityDomain" "$InternalViews" fi - -# Update für master-zones -RZone="50.10.in-addr.arpa." -RFile="$ZoneFilesFolder""db.50.10" -"$UpdateScriptsFolder"update-rdnszone.sh "$RZone" "$ForwardZones" "$RFile" "$TTLReReExMi" "$InternalView" - -RZone="83.10.in-addr.arpa." -RFile="$ZoneFilesFolder""db.83.10" -"$UpdateScriptsFolder"update-rdnszone.sh "$RZone" "$ForwardZones" "$RFile" "$TTLReReExMi" "$InternalView" - -RZone="d.b.9.2.2.0.6.5.3.4.d.f.ip6.arpa." -RFile="$ZoneFilesFolder""db.fd43-5602-29bd" -"$UpdateScriptsFolder"update-rdnszone.sh "$RZone" "$ForwardZones" "$RFile" "$TTLReReExMi" "$InternalView" +for Subnet in $CommunitySubnets; do + ReverseDomains="$(GetReverseDomains "$Subnet")" + for RDomain in $ReverseDomains; do + ./update-rdnszone.sh "$RDomain" "$ForwardZones" "$ZoneFilesFolder" "$TTLReReExMi" "$InternalViews" + done +done if [ -n "$ExternalView" ]; then # Split-View InternFile="$MasterFile" ExternFile="$ZoneFilesFolder""dbextern.""$CommunityDomain" Domain="$CommunityDomain" - "$UpdateScriptsFolder"update-extzone.sh "$InternFile" "$ExternFile" "$Domain" "$ExternalView" + ./update-extzone.sh "$InternFile" "$ExternFile" "$Domain" "$ExternalView" fi -if [ -n "$HoodSubDomain" ]; then - # Update für lokale Zone; ForwardZones wird hier um die SubDomain erweitert - ForwardZones="$ForwardZones $HoodSubDomain"".""$CommunityDomain""/""$ZoneFilesFolder""db.""$HoodSubDomain"".""$CommunityDomain" - - RZone="$HoodSubIPv4"".50.10.in-addr.arpa." - RFile="$ZoneFilesFolder""db.""$HoodSubIPv4"".50.10" - "$UpdateScriptsFolder"update-rdnszone.sh "$RZone" "$ForwardZones" "$RFile" "$TTLReReExMi" "$InternalView" - - HoodSubIPv6Reverse="$(echo "$HoodSubIPv6" | awk '{$i=substr(("0000" $i), length($i)+1); print}' | awk '{ i=length; x=substr($0,i,1); for(i--;i!=0;i--)x=x "." substr($0,i,1);}END{print x}')" - RZone="$HoodSubIPv6Reverse"".d.b.9.2.2.0.6.5.3.4.d.f.ip6.arpa." - RFile="$ZoneFilesFolder""db.fd43-5602-29bd-""$HoodSubIPv6" - "$UpdateScriptsFolder"update-rdnszone.sh "$RZone" "$ForwardZones" "$RFile" "$TTLReReExMi" "$InternalView" - +# set shorter TTL for Hoods +TTLReReExMi="420 360 180 1800 360" + +Hoods="$(GetOwnHoods "$CommunityDomain" "$MasterFile")" + +for Hood in $Hoods; do + HoodSubDomain="${Hood%%\#*}" + Subnets="$(echo "${Hood#*\#}" | sed -e 's/#/ /g')" + HoodZoneFile="$ZoneFilesFolder""db.""$HoodSubDomain"".""$CommunityDomain" + if [ ! -f "$HoodZoneFile" ]; then + echo "\$TTL ${TTLReReExMi%% *}" > "$HoodZoneFile" + echo "$HoodSubDomain"".""$CommunityDomain"". ${TTLReReExMi%% *} IN SOA $DNSSCRIPT_SERVER_NAME""."" $DNSSCRIPT_CONTACT_EMAIL 1 ${TTLReReExMi#* }" >> "$HoodZoneFile" + echo "$HoodSubDomain"".""$CommunityDomain"". ${TTLReReExMi%% *} IN NS $DNSSCRIPT_SERVER_NAME"".""" >> "$HoodZoneFile" + echo "$(GetOwnGlueRecords "$CommunityDomain" "$MasterFile")" >> "$HoodZoneFile" + fi + ./update-hoodzone.sh "$HoodZoneFile" "$HoodSubDomain"".""$CommunityDomain" "$Subnets" "$InternalViews" + HoodForwardZones="$ForwardZones $HoodSubDomain"".""$CommunityDomain""/""$ZoneFilesFolder""db.""$HoodSubDomain"".""$CommunityDomain" + for Subnet in $Subnets; do + ReverseDomains="$(GetReverseDomains "$Subnet")" + for RDomain in $ReverseDomains; do + ./update-rdnszone.sh "$RDomain" "$HoodForwardZones" "$ZoneFilesFolder" "$TTLReReExMi" "$InternalViews" + done + done if [ -n "$ExternalView" ]; then # Split-View InternFile="$ZoneFilesFolder""db.""$HoodSubDomain"".""$CommunityDomain" ExternFile="$ZoneFilesFolder""dbextern.""$HoodSubDomain"".""$CommunityDomain" Domain="$HoodSubDomain"".""$CommunityDomain" - "$UpdateScriptsFolder"update-extzone.sh "$InternFile" "$ExternFile" "$Domain" "$ExternalView" + ./update-extzone.sh "$InternFile" "$ExternFile" "$Domain" "$ExternalView" fi -fi +done \ No newline at end of file diff --git a/update-extzone.sh b/update-extzone.sh old mode 100644 new mode 100755 index ce10a3e..74c5aef --- a/update-extzone.sh +++ b/update-extzone.sh @@ -15,6 +15,6 @@ else fi if [ $SerialIntern -gt $SerialExtern ]; then - sed '/.*\s\(10.\|[fF][cdCD][0-9a-fA-F]\{2\}:\)\S*\s*\(;.*\)\?/d' "$InternalZoneFile" > "$ExternalZoneFile" + sed '/^[^;]*\s\(10.\|[fF][cdCD][0-9a-fA-F]\{2\}:\)\S*\s*\(;.*\)\?$/d' "$InternalZoneFile" > "$ExternalZoneFile" ReloadZone "$ExternalZone" "$ExternalView" fi diff --git a/update-hoodzone.sh b/update-hoodzone.sh new file mode 100755 index 0000000..fbc053f --- /dev/null +++ b/update-hoodzone.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +. ./dns-functions.sh + +HoodZoneFile="$1" +Domain="$2" +Subnets="$3" +View="$4" + + +DomainReg=".""$Domain" +DomainReg="$(echo "$DomainReg" | sed -e 's/\./\\\./g')" + +GetLeaseEntriesInSubnet() { + echo "$1" | while read -r LeaseLine; do + if IPv4IsInSubnet "${LeaseLine##* }" "$2";then + echo "$LeaseLine" + fi + done +} + +OldLeases="$(sed -e '/^;### Leases ###/,$!d' "$HoodZoneFile" | sed 1d)" + +if [ -f "/tmp/dhcp.leases" ]; then + DnsmasqLeases="$(sed -ne 's/^\s*\(\S\+\s\+\)\{2\}\(\S\+\)\s\+\([_0-9a-zA-Z-]\+\)\s\+.*/\3 IN A \2/p' "/tmp/dhcp.leases")" + for Subnet in $Subnets; do + IsValidIPv4Subnet "$Subnet" && NewLeases="$(echo "$NewLeases";echo "$(GetLeaseEntriesInSubnet "$DnsmasqLeases" "$Subnet")")" + done +fi + +for Leasefile in /tmp/hosts/*; do + if [ -n "${Leasefile##*/tmp/hosts/\*}" ]; then + NewLeases="$(echo "$NewLeases"; sed -ne 's/^\s*\([0-9.]*\)\s\+\([_0-9a-zA-Z-]\+\)'"$DomainReg"'.*/\2 IN A \1/p' "$Leasefile")" + NewLeases="$(echo "$NewLeases"; sed -ne 's/^\s*\([0-9a-fA-F:]*\)\s\+\([_0-9a-zA-Z-]\+\)'"$DomainReg"'.*/\2 IN AAAA \1/p' "$Leasefile")" + fi +done + +NewLeases="$(echo "$NewLeases" | + sed -ne 's/^\(\(\(\S\+\)'"$DomainReg"'\)\|\(\S\+\)\)\(.*\)$/\3\4\5/p' | + awk '!a[$0]++' | +# uncomment and duplicate to secure static DNS-Entries +# sed -e '/^dns\s\+.*/d' | + awk 'BEGIN{FS="\t"}{l=length($1);y=substr("\t\t\t\t\t\t", 1+length($1)/4);x=substr($0,length($1)+1); print $1 y x}' )" +if [ "$NewLeases" != "$OldLeases" ]; then + NewSerial="$(GetZoneFileSerial "$HoodZoneFile")" + NewSerial=$((NewSerial+1)) + sed -i -e 's/^\(\s*\)\(\S\+\)\(\s*;\s*Serial.*\)/\1'"$NewSerial"'\3/g' "$HoodZoneFile" + sed -i -e '/^;### Leases ###/,$d' "$HoodZoneFile" + echo ";### Leases ###" >> "$HoodZoneFile" + echo "$NewLeases" >> "$HoodZoneFile" + ReloadZone "$Domain" "$View" +fi diff --git a/update-rdnszone.sh b/update-rdnszone.sh old mode 100644 new mode 100755 index 895fe6e..180028f --- a/update-rdnszone.sh +++ b/update-rdnszone.sh @@ -5,7 +5,7 @@ ReverseDomain="$1" ReverseZone="${ReverseDomain%*.}" ForwardZones="$2" -ReverseZoneFile="$3" +ReverseZoneFile="$3""db.""$(echo "$ReverseZone" | awk -F. '{ printf $(NF-2);for(i=NF-3;i>0;--i) printf "."$i}')" TempDir="/tmp/""$ReverseZone" TTL="${4%% *}" ReReExMi="${4#* }" @@ -18,16 +18,14 @@ GetIPEntries() { IPPattern="[aA]\{4\}\s\+\([0-9a-f:]\+\)" fi - sed -ne "s/^\s*\(\S\+\)\s\+\([0-9]*\s\)\?\s*IN\s\+""$IPPattern"".*/\1\/\3/p" "$TempDir/$ForwardZoneFile" + sed -ne "s/^\s*\(\S\+\)\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+""$IPPattern"".*/\1\/\3/p" "$TempDir/$ForwardZoneFile" } ReverseEntry() { if [ -z "$RZoneIsIPv6" ]; then - echo "$(echo "$1" | awk 'BEGIN { FS = "." } ; { print $4 "." $3 "." $2 "." $1 }')"".in-addr.arpa." + echo "$(GetReverseDomains "$1""/32")" else - echo "$(echo "$1" | \ - awk -F: 'BEGIN {OFS=""}{ FillCount=9-NF; for(i=1;i<=NF;i++){if(length($i) == 0){if(i==NF) {$i="0000";} else {for(j=1;j<=FillCount;j++){$i=($i "0000");}}} else {$i=substr(("0000" $i), length($i)+1);}}; print}' | \ - awk '{ i=length; x=substr($0,i,1); for(i--;i!=0;i--)x=x "." substr($0,i,1);}END{print x}')"".ip6.arpa." + echo "$(GetReverseDomains "$1""/128")" fi } @@ -48,7 +46,7 @@ for ForwardZone in $ForwardZones; do named-checkzone -f text -i local -o "$TempDir/$ZoneName" -D "$ZoneName" "$ZoneFile" >/dev/null 2>&1 Serial="$(GetZoneFileSerial "$TempDir/$ZoneName")" NewReverseSerial=$((Serial + NewReverseSerial)) - ZoneRevNS="$(sed -ne 's/^\s*\S\+\s\+\([0-9]*\s\)\?\s*IN\s\+NS\s\+\(\S\+\)\s*.*;\s*Reverse:\s*\([^;]*\)$/\2\/\3/p' "$ZoneFile")" + ZoneRevNS="$(sed -ne 's/^\s*\S\+\s\+\([0-9]*\s\)\?\s*[Ii][Nn]\s\+[Nn][Ss]\s\+\(\S\+\)\s*.*;\s*Reverse:\s*\([^;]*\)$/\2\/\3/p' "$ZoneFile")" ZoneRevNS="$(echo "$ZoneRevNS" | sed -e 's/\(.*[^\.]\)\//\1\.'"$ZoneName"'\.\//' )" SubNSEntries="$SubNSEntries""$ZoneRevNS" done @@ -60,8 +58,8 @@ else fi if [ $NewReverseSerial -gt $OldSerial ]; then - echo "$ReverseDomain $TTL IN SOA $DNSSCRIPT_SERVER_NAME $DNSSCRIPT_CONTACT_EMAIL $NewReverseSerial $ReReExMi" > "$TempDir/$ReverseZone" - echo "$ReverseDomain $TTL IN NS $DNSSCRIPT_SERVER_NAME" >> "$TempDir/$ReverseZone" + echo "$ReverseDomain $TTL IN SOA $DNSSCRIPT_SERVER_NAME""."" $DNSSCRIPT_CONTACT_EMAIL $NewReverseSerial $ReReExMi" > "$TempDir/$ReverseZone" + echo "$ReverseDomain $TTL IN NS $DNSSCRIPT_SERVER_NAME"".""" >> "$TempDir/$ReverseZone" echo "$SubNSEntries" | while read -r SubNSEntry; do for SubReverseDomain in ${SubNSEntry#*/}; do @@ -69,16 +67,15 @@ if [ $NewReverseSerial -gt $OldSerial ]; then echo "$SubReverseDomain $TTL IN NS ${SubNSEntry%/*}" >> "$TempDir/$ReverseZone" fi done - done + done for ForwardZoneFile in $(ls $TempDir); do - IPEntries="$(GetIPEntries)" for IPEntry in $IPEntries; do IP="${IPEntry#*/}" - # Gültigkeit der IP-Adressen named-checkzone bereits geprüft - IP=$(ReverseEntry "$IP") + # IP syntax checked by named-checkzone + IP="$(ReverseEntry "$IP")" if [ -z "${IP##*$ReverseDomain}" ]; then Host="${IPEntry%/*}" echo "$IP $TTL IN PTR $Host" >> "$TempDir/$ReverseZone" diff --git a/update-remotedns.sh b/update-remotedns.sh new file mode 100755 index 0000000..e9b9561 --- /dev/null +++ b/update-remotedns.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +sed -ne 's/^\s*\(\S\+\s\+\)\{2\}\(\S\+\)\s\+\(\S\+\)\s\+.*/\2 \3/p' "/tmp/dhcp.leases" > "/tmp/upload-dns.leases" + +for Leasefile in /tmp/hosts/*; do + sed -ne 's/^\s*\([^#]\S*\)\s\+\(\S\+\).*/\1 \2/p' "$Leasefile" >> "/tmp/upload-dns.leases" +done + +curl -6 -u : --data-urlencode "@/tmp/upload-dns.leases" -X POST https:// \ No newline at end of file diff --git a/update-remoteleases.sh b/update-remoteleases.sh new file mode 100755 index 0000000..2dbb463 --- /dev/null +++ b/update-remoteleases.sh @@ -0,0 +1,10 @@ +#!/bin/sh + + +for File in /wwwup/*; do + LastFile="$File" +done + +cat "$LastFile" | sed -e 's/%\([0-9A-F][0-9A-F]\)/\\\\x\1/g' | xargs echo -e > /tmp/hosts/remote.leases + +rm /wwwup/* \ No newline at end of file