From 8c7457fb727fa138f07943ccd84c9068a8662a55 Mon Sep 17 00:00:00 2001 From: jlusiardi Date: Mon, 24 Feb 2025 18:44:01 +0100 Subject: [PATCH] =?UTF-8?q?main.go=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 main.go diff --git a/main.go b/main.go new file mode 100644 index 0000000..2a8849e --- /dev/null +++ b/main.go @@ -0,0 +1,94 @@ +package main + +/* + * https://github.com/joeig/go-powerdns + * https://github.com/xlzd/gotp + */ +import ( + "context" + "fmt" + "github.com/dspinhirne/netaddr-go" + "github.com/joeig/go-powerdns/v3" + "github.com/xlzd/gotp" + "gopkg.in/yaml.v2" + "log" + "net" + "net/http" + "os" + "strings" +) + +type conf struct { + TotpToken string `yaml:"totp_secret"` + PdnsApiToken string `yaml:"pdns_api_token"` + Zone string `yaml:"zone"` + Records []string `yaml:"records"` +} + +func (c *conf) getConf() *conf { + yamlFile, err := os.ReadFile("config.yaml") + if err != nil { + log.Printf("yamlFile.Get err #%v ", err) + } + err = yaml.Unmarshal(yamlFile, c) + if err != nil { + log.Fatalf("Unmarshal: %v", err) + } + return c +} + +func main() { + var c conf + c.getConf() + + ctx := context.Background() + pdns := powerdns.New("http://localhost:8081", "localhost", powerdns.WithAPIKey(c.PdnsApiToken)) + + http.HandleFunc("/update", func(w http.ResponseWriter, r *http.Request) { + token := r.URL.Query().Get("token") + if token == gotp.NewDefaultTOTP(c.TotpToken).Now() { + ip, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + log.Fatalf("Err %v ", err) + } + userIP := net.ParseIP(ip) + if userIP == nil { + log.Fatalf("Err %v ", err) + } + fmt.Fprintf(w, "IP: %q \n", ip) + log.Println(fmt.Sprintf("TOTP : %q", gotp.NewDefaultTOTP(c.TotpToken).Now())) + log.Println(fmt.Sprintf("Token: %q", token)) + + ipv6, _ := netaddr.ParseIPv6(ip) + new_prefix := ipv6.NetId() + + for _, record_to_update := range c.Records { + records, err := pdns.Records.Get(ctx, c.Zone, record_to_update, powerdns.RRTypePtr(powerdns.RRTypeAAAA)) + if err != nil { + log.Fatalf("%v", err) + } + for _, r := range records { + if strings.Index(*r.Name, record_to_update) == 0 { + ipv6, err := netaddr.ParseIPv6(*r.Records[0].Content) + if err != nil { + log.Fatalf("IPv6 parse err %v ", err) + } + hostId := ipv6.HostId() + new_ipv6 := netaddr.NewIPv6(new_prefix, hostId) + log.Println(fmt.Sprintf("Host: %q -> %q", ipv6, new_ipv6)) + err = pdns.Records.Change(ctx, c.Zone, record_to_update+"."+c.Zone, powerdns.RRTypeAAAA, 30, []string{new_ipv6.Long()}) + if err != nil { + log.Fatalf("Update err %v ", err) + } + } + } + } + + pdns.Zones.Notify(ctx, c.Zone) + log.Println("Updated...") + } + }) + + log.Println("Started...") + http.ListenAndServe(":8080", nil) +}