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:
parent
a23043ba5f
commit
45d4e45bb1
22
samples.txt
22
samples.txt
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user