From: volpol Date: Sat, 16 Jun 2018 15:34:29 +0000 (+0200) Subject: /hostip - query current IP address of user host X-Git-Url: https://git.packet-gain.de/?a=commitdiff_plain;h=f582482cffbb62794cc2a5af34676a7329693816;p=ddnset.git /hostip - query current IP address of user host --- diff --git a/ddnset.go b/ddnset.go index 416a9a7..4328d78 100644 --- a/ddnset.go +++ b/ddnset.go @@ -6,6 +6,7 @@ import ( "encoding/base64" "flag" "fmt" + "github.com/miekg/dns" "io" "io/ioutil" "log" @@ -17,16 +18,18 @@ import ( ) const ( - DefaultAccFile = "/usr/local/etc/ddnset/ddnset.acc" - DefaultZoneFile = "/usr/local/etc/ddnset/ddnset.zon" - DefaultLogFile = "/var/log/ddnset/default.log" - DefaultListenPort = 1980 + DefaultAccFile = "/usr/local/etc/ddnset/ddnset.acc" + DefaultZoneFile = "/usr/local/etc/ddnset/ddnset.zon" + DefaultLogFile = "/var/log/ddnset/default.log" + DefaultListenPort = 1980 + DefaultAuthorityDNS = "localhost" ) var AccFile = flag.String("a", DefaultAccFile, "Path to account file") var ZoneFile = flag.String("z", DefaultZoneFile, "Path to zone file") var LogFile = flag.String("l", DefaultLogFile, "Path to log file") var ListenPort = flag.Uint("p", DefaultListenPort, "Port to listen on") +var AuthorityDNS = flag.String("s", DefaultAuthorityDNS, "Authoritative name server") var Help = flag.Bool("h", false, "Show usage") @@ -190,6 +193,50 @@ func knsupdate(host, ip, zone string, ver int) bool { return true } +func resolveWithAuthority(target, rectype string) string { + res := "" + c := dns.Client{} + m := dns.Msg{} + + if rectype == "A" || rectype == "" { + m.SetQuestion(target+".", dns.TypeA) + r, _, err := c.Exchange(&m, *AuthorityDNS+":53") + + if err == nil { + if len(r.Answer) == 0 { + log.Printf("%s. has no A record", target) + } + + for _, ans := range r.Answer { + record := ans.(*dns.A) + log.Printf("%s. has IP %s", target, record.A) + res = res + record.A.String() + "," + } + } else { + log.Print(err) + } + } + + if rectype == "AAAA" || rectype == "" { + m.SetQuestion(target+".", dns.TypeAAAA) + r, _, err := c.Exchange(&m, *AuthorityDNS+":53") + + if err == nil { + if len(r.Answer) == 0 { + log.Print(target, ". has no AAAA record") + } + for _, ans := range r.Answer { + record := ans.(*dns.AAAA) + log.Printf("%s. has IPv6 %s", target, record.AAAA) + res = res + record.AAAA.String() + "," + } + } else { + log.Print(err) + } + } + return strings.TrimSuffix(res, ",") +} + func myipHandle(w http.ResponseWriter, r *http.Request) { log.Print(r.RemoteAddr, " ", r.Method, " ", r.URL.String()) clientIP, _, err := net.SplitHostPort(r.RemoteAddr) @@ -215,6 +262,8 @@ func rootHandle(w http.ResponseWriter, r *http.Request) { //check auth authok := false hosts := "" + hostip := (r.URL.Path == "/hostip") + if hdr_auth, ok := r.Header["Authorization"]; ok { log.Print("Authorization header present") for _, auth := range hdr_auth { @@ -240,16 +289,31 @@ func rootHandle(w http.ResponseWriter, r *http.Request) { log.Print("User hosts: ", hosts) //check ip q := r.URL.Query() + + myip := "0.0.0.0" + ver := 4 + valid := false + myip_count := len(q["myip"]) + log.Print("myips: ", myip_count) + if !hostip { + if myip_count == 1 { + myip, ver, valid = checkIP(q["myip"][0]) //one IP to rule them all + } + log.Printf("IP: %s (valid:%v, ver:%d)", myip, valid, ver) + if !valid { + log.Print("StatusBadIP") + io.WriteString(w, StatusBadIP+"\n") + return + } + } + //update or reportip hostnames := q["hostname"] - myip, ver, valid := checkIP(q["myip"][0]) //one IP to rule them all - log.Printf("IP: %s (valid:%v, ver:%d)", myip, valid, ver) - if !valid { - log.Print("StatusBadIP") - io.WriteString(w, StatusBadIP+"\n") - return + rectype := "" + if len(q["rectype"]) == 1 { + rectype = q["rectype"][0] } - //update for _, host := range hostnames { + log.Print("Host:", host) if !isDomainName(host) { log.Print("StatusNotFQHN") io.WriteString(w, StatusNotFQHN+"\n") @@ -262,14 +326,18 @@ func rootHandle(w http.ResponseWriter, r *http.Request) { continue } if strings.Contains(hosts, host) { - log.Printf("Updating %s to IP %s", host, myip) - updated := knsupdate(host, myip, zone, ver) - if updated { - log.Print("StatusGood") - io.WriteString(w, StatusGood+"\n") + if !hostip { + log.Printf("Updating %s to IP %s", host, myip) + updated := knsupdate(host, myip, zone, ver) + if updated { + log.Print("StatusGood") + io.WriteString(w, StatusGood+"\n") + } else { + log.Print("StatusBadDay") + io.WriteString(w, StatusBadDay+"\n") + } } else { - log.Print("StatusBadDay") - io.WriteString(w, StatusBadDay+"\n") + io.WriteString(w, resolveWithAuthority(host, rectype)+"\n") } } else { log.Print("StatusBadHost") @@ -290,6 +358,7 @@ func main() { http.HandleFunc("/myip", myipHandle) http.HandleFunc("/myip.php", myipHandle) http.HandleFunc("/", rootHandle) + http.HandleFunc("/hostip", rootHandle) logf, err := os.OpenFile(*LogFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if nil == err { defer logf.Close()