commit
62002841db
@ -0,0 +1,2 @@
|
||||
configs/*
|
||||
cmd/tt/tt
|
@ -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.
|
@ -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"]
|
@ -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
|
@ -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")
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// https://dd.phga.de/dd?usr=<username>&pw=<passwd>
|
||||
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
|
||||
}
|
Loading…
Reference in new issue