Reworked update code, split v4/v6 updates

- collect dns updatees individually, so that we clear A and AAAA separately if and only if needed.
- made nft AddIP call more resilient against partial updates
- updated nft processing code to no longer add nil to a v4/v6 set which would end in an invalid call to AddIP when updating nft. call it individually now.
- updated samples with real world traces from an AVM Box
This commit is contained in:
Torben Nehmer 2021-09-25 11:56:50 +02:00
parent a23043ba5f
commit 45d4e45bb1
4 changed files with 38 additions and 14 deletions

View File

@ -1,3 +1,19 @@
Fritz Box kann nur IPv4 und IPv6 getrennt.
URLs werden durch spaces getrennt:
https://dyndns.nehmer.net/update?UserName=<username>&Password=<passwd>&IPv4=<ipaddr> https://dyndns.nehmer.net/update?UserName=<username>&Password=<passwd>&IPv6=<ip6addr>&IPv6Net=<ip6lanprefix>
ergibt:
79.192.127.0 - - [22/Sep/2021:18:16:17 +0200] "GET /update?UserName=atlantis&Password=xxx&IPv4=79.192.127.157 HTTP/1.1" 500 5641 "-" "Fritz!Box DDNS/1.0.2"
79.192.127.0 - - [22/Sep/2021:18:16:18 +0200] "GET /update?UserName=atlantis&Password=xxx&IPv6=2003:ef:8fff:1021:7eff:4dff:fe7e:e901&IPv6Net=2003:ef:8f0f:fc00::/64 HTTP/1.1" 500 5621 "-" "Fritz!Box DDNS/1.0.2"
/update?UserName=atlantis&Password=xxx&IPv4=79.192.127.157
/update?UserName=atlantis&Password=xx&IPv6=2003:ef:8fff:1021:7eff:4dff:fe7e:e901&IPv6Net=2003:ef:8f0f:fc00::/64
/update?UserName=example&Password=kennwort&IPv4=79.192.127.157
/update?UserName=example&Password=kennwort&IPv6=2003:ef:8fff:1021:7eff:4dff:fe7e:e901&IPv6Net=2003:ef:8f0f:fc00::/64
/update?UserName=test&Password=kennwort&Domain=atlantis.nehmer.net&IPv4=79.202.5.79&IPv6=2003:ef:8fff:905:7eff:4dff:fe7e:e901&DualStack=1&IPv6Net=2003:ef:8f08:f600::/64
Zerlegt:
@ -14,3 +30,9 @@ Zerlegt:
ispconfig.vhost
ProxyPass /hello http://127.0.0.1:8080/hello
ProxyPass /update http://127.0.0.1:8080/update
http://localhost:8080/update?UserName=example&Password=kennwort&Domain=atlantis.nehmer.net&IPv4=79.202.5.79&IPv6=2003:ef:8fff:905:7eff:4dff:fe7e:e901&DualStack=1&IPv6Net=2003:ef:8f08:f600::/64
http://localhost:8080/update?UserName=example&Password=kennwort&Domain=atlantis.nehmer.net&IPv6=2003:ef:8fff:905:7eff:4dff:fe7e:e901&DualStack=1&IPv6Net=2003:ef:8f08:f600::/64
http://localhost:8080/update?UserName=example&Password=kennwort&Domain=atlantis.nehmer.net&IPv4=79.202.5.79

View File

@ -26,18 +26,16 @@ func DNSUpdateEntry(domain string, hostname string, ip4 net.IP, ip6 net.IP) erro
zone := fmt.Sprintf("%s.", domain)
msg.SetUpdate(zone)
msg.RemoveName([]dns.RR{
&dns.RR_Header{Name: fqdn},
})
var rrs []dns.RR
if ip4 != nil {
ip4bin := ip4.To4()
if ip4bin == nil {
return fmt.Errorf("ip4 (%v) is not a valid IPv4 address", ip4)
}
rrs = append(rrs, &dns.A{
msg.RemoveRRset([]dns.RR{
&dns.RR_Header{Name: fqdn, Rrtype: dns.TypeA},
})
msg.Insert([]dns.RR{&dns.A{
Hdr: dns.RR_Header{
Name: fqdn,
Rrtype: dns.TypeA,
@ -45,7 +43,7 @@ func DNSUpdateEntry(domain string, hostname string, ip4 net.IP, ip6 net.IP) erro
Ttl: C.DNS.DefaultTTL,
},
A: ip4bin,
})
}})
}
if ip6 != nil {
@ -53,7 +51,10 @@ func DNSUpdateEntry(domain string, hostname string, ip4 net.IP, ip6 net.IP) erro
if ip6bin == nil {
return fmt.Errorf("ip6 (%v) is not a valid IPv6 address", ip4)
}
rrs = append(rrs, &dns.AAAA{
msg.RemoveRRset([]dns.RR{
&dns.RR_Header{Name: fqdn, Rrtype: dns.TypeAAAA},
})
msg.Insert([]dns.RR{&dns.AAAA{
Hdr: dns.RR_Header{
Name: fqdn,
Rrtype: dns.TypeAAAA,
@ -61,11 +62,9 @@ func DNSUpdateEntry(domain string, hostname string, ip4 net.IP, ip6 net.IP) erro
Ttl: C.DNS.DefaultTTL,
},
AAAA: ip6bin,
})
}})
}
msg.Insert(rrs)
log.Printf("Sending DNS Update for %s.%s:\n%v", hostname, domain, msg)
reply, _, err := dnsClient.Exchange(msg, C.DNS.Server)

View File

@ -65,6 +65,9 @@ func (nut *NFTUpdateTable) FindOrAddSet(SetName string, IP6 bool) (*NFTUpdateSet
}
func (nu *NFTUpdate) AddIP(TableName string, SetName string, IP net.IP) error {
if IP == nil {
return nil
}
ip6 := (IP.To4() == nil)
nut := nu.FindOrAddTable(TableName)
nus, err := nut.FindOrAddSet(SetName, ip6)

View File

@ -85,19 +85,19 @@ func (ur *UpdateRequest) Process() error {
if err := DNSUpdateEntry(ur.Config.Domain, other.Hostname, ur.IPv4, fullV6IP); err != nil {
return fmt.Errorf("failed to update DNS for host %s: %v", other.Hostname, err)
}
} else {
} else if ur.IPv6 != nil {
if err := DNSUpdateEntry(ur.Config.Domain, other.Hostname, nil, fullV6IP); err != nil {
return fmt.Errorf("failed to update DNS for host %s: %v", other.Hostname, err)
}
}
if other.NFT.Table != "" {
if other.NFT.Set6 != "" {
if other.NFT.Set6 != "" && ur.IPv6 != nil {
if err := nfu.AddIP(other.NFT.Table, other.NFT.Set6, fullV6IP); err != nil {
return fmt.Errorf("failed to update IPv6 NFT setup for host %s: %v", other.Hostname, err)
}
}
if other.RegisterV4 && other.NFT.Set4 != "" {
if other.RegisterV4 && other.NFT.Set4 != "" && ur.IPv4 != nil {
if err := nfu.AddIP(other.NFT.Table, other.NFT.Set4, ur.IPv4); err != nil {
return fmt.Errorf("failed to update IPv6 NFT setup for host %s: %v", other.Hostname, err)
}