From 62002841db885a918bcff1733b7b66db524436ee Mon Sep 17 00:00:00 2001 From: phga Date: Tue, 13 Apr 2021 21:28:11 +0200 Subject: [PATCH] Init: Quick and dirty --- .gitignore | 2 + README.md | 1 + build/app/Dockerfile | 7 ++++ build/docker-compose.yml | 12 ++++++ cmd/dd/config.go | 34 +++++++++++++++++ cmd/dd/dd.go | 79 ++++++++++++++++++++++++++++++++++++++++ go.mod | 3 ++ 7 files changed, 138 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 build/app/Dockerfile create mode 100644 build/docker-compose.yml create mode 100644 cmd/dd/config.go create mode 100644 cmd/dd/dd.go create mode 100644 go.mod diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..86eccc2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +configs/* +cmd/tt/tt \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..720d2c3 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +Tiny DDNS service I wrote because I needed to move VPS and did not want to use the old one written in Python. \ No newline at end of file diff --git a/build/app/Dockerfile b/build/app/Dockerfile new file mode 100644 index 0000000..8a4e356 --- /dev/null +++ b/build/app/Dockerfile @@ -0,0 +1,7 @@ +FROM golang:1.16.2 + +ENV GO111MODULE=off +RUN go get -u -d g.phga.de/phga/dd/... +WORKDIR /go/src/g.phga.de/phga/dd/cmd/dd +RUN go build +CMD ["./dd"] \ No newline at end of file diff --git a/build/docker-compose.yml b/build/docker-compose.yml new file mode 100644 index 0000000..2599f5c --- /dev/null +++ b/build/docker-compose.yml @@ -0,0 +1,12 @@ +version: '3' + +services: + dd: + build: + context: ./app + dockerfile: Dockerfile + restart: 'always' + ports: + - 8000:6969 + volumes: + - /srv/dd/configs:/go/src/g.phga.de/phga/dd/configs \ No newline at end of file diff --git a/cmd/dd/config.go b/cmd/dd/config.go new file mode 100644 index 0000000..ff9f30f --- /dev/null +++ b/cmd/dd/config.go @@ -0,0 +1,34 @@ +package main + +import ( + "encoding/json" + "log" + "os" +) + +type Config struct { + WebPort string `json:"web_port"` + WebDomain string `json:"web_domain"` + WebAdmin string `json:"web_admin"` + WebAdminPass string `json:"web_admin_pass"` + MailUser string `json:"mail_user"` + MailPass string `json:"mail_pass"` + MailSmtpServer string `json:"mail_smtp_server"` + MailSmtpPort string `json:"mail_smtp_port"` + DdUsers map[string]map[string]string `json:"dd_users"` + DnsTTL int `json:"dns_ttl"` +} + +var config Config + +func init() { + f, err := os.Open("../../configs/config.json") + if err != nil { + log.Fatalln(err, "Could not read config file") + } + defer f.Close() + err = json.NewDecoder(f).Decode(&config) + if err != nil { + log.Fatalln(err, "Could not decode config file") + } +} diff --git a/cmd/dd/dd.go b/cmd/dd/dd.go new file mode 100644 index 0000000..83a14e5 --- /dev/null +++ b/cmd/dd/dd.go @@ -0,0 +1,79 @@ +package main + +import ( + "fmt" + "io" + "log" + "net/http" + "os" + "os/exec" + "strings" +) + +// https://dd.phga.de/dd?usr=&pw= +func main() { + // cheap routing + http.HandleFunc("/dd", handleDynamicUpdate) + + log.Fatalln(http.ListenAndServe(":"+config.WebPort, nil)) +} + +func handleDynamicUpdate(w http.ResponseWriter, r *http.Request) { + up := r.URL.Query() + ip := r.Header.Get("X-FORWARDED-FOR") + + if len(ip) < 1 { + ip = strings.Split(r.RemoteAddr, ":")[0] + } + + if len(up) != 2 { + log.Println("Attempted update for:", ip) + log.Println("Not enough arguments provided:", up) + return + } + + for k, v := range config.DdUsers { + if k == up["usr"][0] { + if v["password"] == up["pwd"][0] { + log.Println("Starting update for:", ip, "(", v["domain"], ")") + // Do the update via nsupdate + err := updateDnsRecord(v["domain"], ip, v["hmac"], v["keyname"], v["secret"]) + if err != nil { + log.Println("nsupdate failed:", err) + } else { + log.Println("nsupdate succeeded!") + } + } else { + log.Println("Wrong Secret provided!") + } + } + } + +} + +func updateDnsRecord(domain string, ip string, hmac string, keyname string, secret string) error { + f, err := os.Create("/tmp/update.dns") + if err != nil { + return err + } + defer f.Close() + + update := fmt.Sprintf(`server 127.0.0.1 + key %s:%s %s + update add %s %d a %s + send`, hmac, keyname, secret, domain, config.DnsTTL, ip) + + _, err = io.WriteString(f, update) + if err != nil { + return err + } + err = f.Sync() + if err != nil { + return err + } + + nsupdate := exec.Command("nsupdate", "/tmp/update.dns") + out, err := nsupdate.Output() + log.Println(string(out)) + return err +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..31aeece --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module g.phga.de/phga/dd + +go 1.16