From e42cccdcdc2a40dbde4a04c07886c02829dd14fa Mon Sep 17 00:00:00 2001 From: Rudi Date: Tue, 24 May 2022 09:34:26 -0400 Subject: [PATCH] Initial commit --- go.mod | 8 ++++ go.sum | 4 ++ main.go | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..4941747 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module git.hugfreevikings.wtf/UniventionDNS2Go + +go 1.18 + +require ( + gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect + gopkg.in/ldap.v2 v2.5.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..96272d8 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM= +gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= +gopkg.in/ldap.v2 v2.5.1 h1:wiu0okdNfjlBzg6UWvd1Hn8Y+Ux17/u/4nlk4CQr6tU= +gopkg.in/ldap.v2 v2.5.1/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk= diff --git a/main.go b/main.go new file mode 100644 index 0000000..2df962b --- /dev/null +++ b/main.go @@ -0,0 +1,143 @@ +package main + +import ( + "bufio" + "crypto/tls" + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + "strings" + + "gopkg.in/ldap.v2" +) + +var ( + configFile string + domain string + host string + + ldap_uri string + ldap_default_bind_dn string + ldap_default_authtok string + ldap_search_base string +) + +type IP struct { + Query string +} + +func init() { + flag.StringVar(&configFile, "c", "/etc/sssd/sssd.conf", "Path to SSSD Config.") + flag.StringVar(&host, "h", host, "Host ID for DNS (relativeDomainName)") + flag.StringVar(&domain, "d", "", "Domain for DNS (zoneName)") + flag.Parse() +} + +func main() { + log.Printf("Using %+v as config file path", configFile) + + file, err := os.Open(configFile) + if err != nil { + log.Fatal(err) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + // optionally, resize scanner's capacity for lines over 64K, see next example + for scanner.Scan() { + line := scanner.Text() + mod := &ldap_uri + switch { + case strings.Contains(line, "ldap_uri"): + mod = &ldap_uri + case strings.Contains(line, "ldap_default_bind_dn"): + mod = &ldap_default_bind_dn + case strings.Contains(line, "ldap_default_authtok"): + mod = &ldap_default_authtok + case strings.Contains(line, "ldap_search_base"): + mod = &ldap_search_base + + default: + continue + } + *mod = strings.Split(line, "= ")[1] + + } + + if err := scanner.Err(); err != nil { + log.Fatal(err) + } + log.Printf("Connecting to %s", ldap_uri) + ldap_uri = strings.ReplaceAll(ldap_uri, "ldap://", "") + l, err := ldap.Dial("tcp", ldap_uri) + if err != nil { + log.Fatal(err) + } + defer l.Close() + log.Printf("Connected to %s, reconnecting with TLS", ldap_uri) + // Reconnect with TLS + err = l.StartTLS(&tls.Config{InsecureSkipVerify: true}) + if err != nil { + log.Fatal(err) + } + log.Printf("Binding as %s", ldap_default_bind_dn) + // First bind with a read only user + err = l.Bind(ldap_default_bind_dn, ldap_default_authtok) + if err != nil { + log.Fatal(err) + } + log.Printf("Connected as read-only user, searching for DNS Record") + // Search for the given username + searchRequest := ldap.NewSearchRequest( + fmt.Sprintf("zoneName=%s,cn=dns,%s", ldap.EscapeFilter(domain), ldap.EscapeFilter(ldap_search_base)), + ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, + fmt.Sprintf("(relativeDomainName=%s)", ldap.EscapeFilter(host)), + []string{"dn"}, + nil, + ) + + sr, err := l.Search(searchRequest) + if err != nil { + log.Fatal(err) + } + + if len(sr.Entries) != 1 { + log.Fatalf("Host does not exist or too many entries returned (%+v)", len(sr.Entries)) + } + log.Printf("Record found for %s.%s", host, domain) + newIp := getip2() + if sr.Entries[0].GetAttributeValue("aRecord") == newIp { + log.Println("New IP is same as old IP, exiting gracefully.") + return + } + req := ldap.NewModifyRequest(sr.Entries[0].DN) + + req.Replace("aRecord", []string{newIp}) + if err = l.Modify(req); err != nil { + log.Fatalf("Failed to modify DN: %s\n", err) + } + log.Printf("Updated record successfully.") + +} + +func getip2() string { + req, err := http.Get("http://ip-api.com/json/") + if err != nil { + return err.Error() + } + defer req.Body.Close() + + body, err := ioutil.ReadAll(req.Body) + if err != nil { + return err.Error() + } + + var ip IP + json.Unmarshal(body, &ip) + log.Printf("Detected IP as %s", ip.Query) + return ip.Query +}