diff --git a/Makefile b/Makefile index cfe7f96..1600657 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ run: build install: go install -v go.wit.com/control-panel-dns@latest - # go install -v git.wit.com/wit/control-panel-dns@latest + # go install -v go.wit.com/control-panel-dns@latest gocui: build ./control-panel-dns -gui gocui >/tmp/witgui.log.stderr 2>&1 @@ -25,7 +25,7 @@ build-release: build: reset -mkdir -p plugins/ - -cp ~/go/src/git.wit.org/wit/gui/toolkit/*.so plugins/ + -cp ~/go/src/go.wit.com/gui/toolkit/*.so plugins/ # GO111MODULE="off" go get -v -x . GO111MODULE="off" go build -v -o control-panel-dns @@ -76,17 +76,17 @@ build-with-custom-go.mod: # replace github.com/versent/saml2aws/v2 v2.35.0 => github.com/marcottedan/saml2aws/v2 master # replace github.com/versent/saml2aws/v2 => /Users/dmarcotte/git/saml2aws/ # -check-cert: - reset - # https://crt.sh/?q=check.lab.wit.org + # https://crt.sh/?q=check.lab.wit.com # # https://letsencrypt.org/certificates/ - # openssl s_client -connect check.lab.wit.org:443 -showcerts - openssl s_client -CApath /etc/ssl/certs/ -connect check.lab.wit.org:443 -showcerts - # openssl s_client -CApath /etc/ssl/certs/ -connect check.lab.wit.org:443 -showcerts -trace -debug - # openssl s_client -CAfile isrgrootx1.pem -connect check.lab.wit.org:443 -showcerts + # openssl s_client -connect check.lab.wit.com:443 -showcerts + # openssl s_client -CApath /etc/ssl/certs/ -connect check.lab.wit.com:443 -showcerts -trace -debug + # openssl s_client -CAfile isrgrootx1.pem -connect check.lab.wit.com:443 -showcerts # cat isrgrootx1.pem lets-encrypt-r3.pem > full-chain.pem # full-chain.pem - # openssl s_client -CAfile /etc/ssl/certs/wit-full-chain.pem -connect check.lab.wit.org:443 -showcerts + # openssl s_client -CAfile /etc/ssl/certs/wit-full-chain.pem -connect check.lab.wit.com:443 -showcerts +check-cert: + reset + openssl s_client -CApath /etc/ssl/certs/ -connect go.wit.com:443 -showcerts ssl-cert-hash: openssl x509 -hash -noout -in wit-full-chain.pem @@ -98,7 +98,7 @@ sudo-cp: sudo cp -a lets-encrypt-r3.pem 8d33f237.0 /etc/ssl/certs/ go-get: - go install -v check.lab.wit.org/gui + go install -v go.wit.com/gui log: reset diff --git a/README.md b/README.md index e236dbc..e98c2b1 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,6 @@ to update the DNS server. Useful links and other external things which might be useful -* [WIT GO projects](http://go.wit.org/) -* [GOLANG GUI](https://github.com/wit-go/gui) +* [WIT GO projects](http://go.wit.com/) +* [GOLANG GUI](https://go.wit.com/gui) * [GO Style Guide](https://google.github.io/styleguide/go/index) diff --git a/args.go b/args.go index 04abc96..fed42d5 100644 --- a/args.go +++ b/args.go @@ -9,9 +9,9 @@ import ( "fmt" "time" arg "github.com/alexflint/go-arg" - "git.wit.org/wit/gui" - // log "git.wit.org/wit/gui/log" - "git.wit.org/jcarr/control-panel-dns/cloudflare" + "go.wit.com/gui" + // log "go.wit.com/gui/log" + "go.wit.com/control-panel-dns/cloudflare" ) var newRR *cloudflare.RRT diff --git a/cloudflare/cloudflare.go b/cloudflare/cloudflare.go index de08fae..f9452ce 100644 --- a/cloudflare/cloudflare.go +++ b/cloudflare/cloudflare.go @@ -8,7 +8,7 @@ import ( "io/ioutil" "net/http" - "git.wit.org/wit/gui" + "go.wit.com/gui" ) /* diff --git a/debian/Makefile b/debian/Makefile index 4f3193e..6f4f534 100644 --- a/debian/Makefile +++ b/debian/Makefile @@ -21,7 +21,7 @@ clean: extract: mkdir -p ../files/usr/bin mkdir -p ../files/usr/lib/control-panel-dns/ - -cp ~/go/src/git.wit.org/wit/gui/toolkit/*.so ../files/usr/lib/control-panel-dns/ + -cp ~/go/src/go.wit.com/gui/toolkit/*.so ../files/usr/lib/control-panel-dns/ cp ../README.md ../files/usr/lib/control-panel-dns/ cp ../control-panel-dns ../files/usr/bin/ diff --git a/dns.go b/dns.go index 8afbf26..fc9648c 100644 --- a/dns.go +++ b/dns.go @@ -9,7 +9,7 @@ import ( "net" "strings" - "git.wit.org/wit/shell" + "go.wit.com/shell" ) /* diff --git a/dnssecsocket/args.go b/dnssecsocket/args.go new file mode 100644 index 0000000..cbd9fe7 --- /dev/null +++ b/dnssecsocket/args.go @@ -0,0 +1,44 @@ +package dnssecsocket + +// +// By using the package "github.com/alexflint/go-arg", +// these can be configured from the command line +// + +import ( + // arg "github.com/alexflint/go-arg" + // "log" + // "os" +) + +type Args struct { + VerboseDnssec bool `arg:"--verbose-dnssec" help:"debug dnssec lookups"` + Foo string `arg:"env:USER"` +} + +var args struct { + Args + Verbose bool +} + +func Parse (b bool) { + args.Verbose = b + args.VerboseDnssec = b +} + +// I attempted to pass the *arg.Parser down +// to see if I could find the value somewhere but I couldn't find it +/* +var conf arg.Config + +func Parse (p *arg.Parser) { + // conf.Program = "control-panel-dns" + // conf.IgnoreEnv = false + // arg.NewParser(conf, &args) + log.Println("fuckit", p, args.VerboseDnssec) + for i, v := range p.SubcommandNames() { + log.Println("dnssec.Parse", i, v) + } + p.Jcarr() +} +*/ diff --git a/dnssecsocket/connection_handler.go b/dnssecsocket/connection_handler.go new file mode 100644 index 0000000..8ccedaa --- /dev/null +++ b/dnssecsocket/connection_handler.go @@ -0,0 +1,131 @@ +// inspired from: +// https://github.com/mactsouk/opensource.com.git +// and +// https://coderwall.com/p/wohavg/creating-a-simple-tcp-server-in-go + +package dnssecsocket + +import "os" +import "bufio" +import "math/rand" +import "net" +import "strconv" +import "strings" +// import log "github.com/sirupsen/logrus" +// import "github.com/wercker/journalhook" + +import "go.wit.com/shell" + +// will try to get this hosts FQDN +// import "github.com/Showmax/go-fqdn" + +import "github.com/miekg/dns" + +// import "github.com/davecgh/go-spew/spew" + +const MIN = 1 +const MAX = 100 + +func random() int { + return rand.Intn(MAX-MIN) + MIN +} + +func GetRemoteAddr(conn net.TCPConn) string { + clientAddr := conn.RemoteAddr().String() + parts := strings.Split(clientAddr, "]") + ipv6 := parts[0] + return ipv6[1:] +} + +// +// Handle each connection +// Each client must send it's hostname as the first line +// Then each hostname is verified with DNSSEC +// +func HandleConnection(conn *net.TCPConn) { + // Disable journalhook until it builds on Windows + // journalhook.Enable() + + // spew.Dump(conn) + // ipv6client := GetRemoteAddr(c) + ipv6client := conn.RemoteAddr() + log(args.VerboseDnssec, "Serving to %s as the IPv6 client", ipv6client) + + // setup this TCP socket as the "standard input" + // newStdin, _ := bufio.NewReader(conn.File()) + newStdin, _ := conn.File() + newreader := bufio.NewReader(newStdin) + + log(args.VerboseDnssec, "Waiting for the client to tell me its name") + netData, err := newreader.ReadString('\n') + if err != nil { + log(args.VerboseDnssec, err) + return + } + clientHostname := strings.TrimSpace(netData) + log(args.VerboseDnssec, "Recieved client hostname as:", clientHostname) + + dnsRR := Dnstrace(clientHostname, "AAAA") + if (dnsRR == nil) { + log(args.VerboseDnssec, "dnsRR IS NIL") + log(args.VerboseDnssec, "dnsRR IS NIL") + log(args.VerboseDnssec, "dnsRR IS NIL") + conn.Close() + return + } + ipaddr := dns.Field(dnsRR[1], 1) + log(args.VerboseDnssec, "Client claims to be: ", ipaddr) + log(args.VerboseDnssec, "Serving to IPv6 client:", ipv6client) + +/* TODO: figure out how to fix this check + if (ipaddr != ipv6client) { + log(args.VerboseDnssec) + log(args.VerboseDnssec, "DNSSEC ERROR: client IPv6 does not work") + log(args.VerboseDnssec, "DNSSEC ERROR: client IPv6 does not work") + log(args.VerboseDnssec, "DNSSEC ERROR: client IPv6 does not work") + log(args.VerboseDnssec) + conn.Close() + return + } +*/ + + f, _ := conn.File() +// shell.SetStdout(f) +// shell.SpewOn() // turn this on if you want to look at the process exit states + + // send all log() output to systemd journalctl +// shell.UseJournalctl() + + for { + defer shell.SetStdout(os.Stdout) + defer conn.Close() + netData, err := newreader.ReadString('\n') + if err != nil { + log(args.VerboseDnssec, err) + return + } + + temp := strings.TrimSpace(string(netData)) + if temp == "STOP" { + break + } + log(args.VerboseDnssec, "Recieved: ", temp) + + if (temp == "list") { + log(args.VerboseDnssec, "Should run list here") + shell.SetStdout(f) + shell.Run("/root/bin/list.testing.com") + shell.SetStdout(os.Stdout) + } + + if (temp == "cpuinfo") { + log(args.VerboseDnssec, "Should cat /proc/cpuinfo") + shell.SetStdout(f) + shell.Run("cat /proc/cpuinfo") + shell.SetStdout(os.Stdout) + } + + result := strconv.Itoa(random()) + "\n" + conn.Write([]byte(string(result))) + } +} diff --git a/dnssecsocket/dnstrace.go b/dnssecsocket/dnstrace.go new file mode 100644 index 0000000..d8fca38 --- /dev/null +++ b/dnssecsocket/dnstrace.go @@ -0,0 +1,168 @@ +package dnssecsocket + +// inspired from github.com/rs/dnstrace/main.go + +import "fmt" +import "net" +// import "os" +import "strings" +import "time" + +import "github.com/miekg/dns" +import "github.com/rs/dnstrace/client" + +// import log "github.com/sirupsen/logrus" + +// this is cool, but breaks the Windows build +// import "github.com/wercker/journalhook" + +// import "github.com/davecgh/go-spew/spew" + +const ( + cReset = 0 + cBold = 1 + cRed = 31 + cGreen = 32 + cYellow = 33 + cBlue = 34 + cMagenta = 35 + cCyan = 36 + cGray = 37 + cDarkGray = 90 +) + +func colorize(s interface{}, color int, enabled bool) string { + if !enabled { + return fmt.Sprintf("%v", s) + } + return fmt.Sprintf("\x1b[%dm%v\x1b[0m", color, s) +} + +func Dnstrace(hostname string, qtypestr string) []dns.RR { + // color := flag.Bool("color", true, "Enable/disable colors") + color := true + + qname := dns.Fqdn(hostname) + // qtype := dns.TypeA + qtype := dns.StringToType[qtypestr] + + col := func(s interface{}, c int) string { + return colorize(s, c, color) + } + + m := &dns.Msg{} + m.SetQuestion(qname, qtype) + // Set DNSSEC opt to better emulate the default queries from a nameserver. + o := &dns.OPT{ + Hdr: dns.RR_Header{ + Name: ".", + Rrtype: dns.TypeOPT, + }, + } + o.SetDo() + o.SetUDPSize(dns.DefaultMsgSize) + m.Extra = append(m.Extra, o) + + c := client.New(1) + c.Client.Timeout = 500 * time.Millisecond + t := client.Tracer{ + GotIntermediaryResponse: func(i int, m *dns.Msg, rs client.Responses, rtype client.ResponseType) { + fr := rs.Fastest() + var r *dns.Msg + if fr != nil { + r = fr.Msg + } + qname := m.Question[0].Name + qtype := dns.TypeToString[m.Question[0].Qtype] + if i > 1 { + log(args.VerboseDnssec) + } + log(args.VerboseDnssec, "%d - query %s %s", i, qtype, qname) + if r != nil { + log(args.VerboseDnssec, ": %s", strings.Replace(strings.Replace(r.MsgHdr.String(), ";; ", "", -1), "\n", ", ", -1)) + } + log(args.VerboseDnssec) + for _, pr := range rs { + ln := 0 + if pr.Msg != nil { + ln = pr.Msg.Len() + } + rtt := float64(pr.RTT) / float64(time.Millisecond) + lrtt := "0ms (from cache)" + if pr.Server.HasGlue { + lrtt = "0ms (from glue)" + } else if pr.Server.LookupRTT > 0 { + lrtt = fmt.Sprintf("%.2fms", float64(pr.Server.LookupRTT)/float64(time.Millisecond)) + } + log(args.VerboseDnssec, col(" - %d bytes in %.2fms + %s lookup on %s(%s)", cDarkGray), ln, rtt, lrtt, pr.Server.Name, pr.Addr) + if pr.Err != nil { + err := pr.Err + if oerr, ok := err.(*net.OpError); ok { + err = oerr.Err + } + log(args.VerboseDnssec, ": %v", col(err, cRed)) + } + log(args.VerboseDnssec, "\n") + } + + switch rtype { + case client.ResponseTypeDelegation: + var label string + for _, rr := range r.Ns { + if ns, ok := rr.(*dns.NS); ok { + label = ns.Header().Name + break + } + } + _, ns := c.DCache.Get(label) + for _, s := range ns { + var glue string + if s.HasGlue { + glue = col("glue: "+strings.Join(s.Addrs, ","), cDarkGray) + } else { + glue = col("no glue", cYellow) + } + log(args.VerboseDnssec, "%s %d NS %s (%s)\n", label, s.TTL, s.Name, glue) + } + case client.ResponseTypeCNAME: + for _, rr := range r.Answer { + log(args.VerboseDnssec, rr) + } + } + }, + FollowingCNAME: func(domain, target string) { + log(args.VerboseDnssec, col("\n~ following CNAME %s -> %s\n", cBlue), domain, target) + }, + } + r, rtt, err := c.RecursiveQuery(m, t) + if err != nil { + log(args.VerboseDnssec, col("*** error: %v\n", cRed), err) + return nil + } + + log(args.VerboseDnssec) + log(args.VerboseDnssec, col(";; Cold best path time: %s\n\n", cGray), rtt) + for i, rr := range r.Answer { + log(args.VerboseDnssec, "r.Answer =", i, rr, args.VerboseDnssec) + } + return r.Answer + // for _, rr := range r.Answer { + // return rr + // } + // return nil +} + +func ResolveIPv6hostname(hostname string) *net.TCPAddr { + dnsRR := Dnstrace(hostname, "AAAA") + if (dnsRR == nil) { + return nil + } + aaaa := dns.Field(dnsRR[1], 1) + localTCPAddr, _ := net.ResolveTCPAddr("tcp", aaaa) + return localTCPAddr +} + +func UseJournalctl() { + log(args.VerboseDnssec, "journalhook is disabled because it breaks the Windows build right now") + // journalhook.Enable() +} diff --git a/dnssecsocket/log.go b/dnssecsocket/log.go new file mode 100644 index 0000000..6381899 --- /dev/null +++ b/dnssecsocket/log.go @@ -0,0 +1,30 @@ +package dnssecsocket + +import ( + witlog "go.wit.com/gui/log" +) + +// various debugging flags +var logNow bool = true // useful for active development +var logError bool = true +var logWarn bool = false +var logInfo bool = false +var logVerbose bool = false + +var SPEW witlog.Spewt + +// var log interface{} + +func log(a ...any) { + witlog.Where = "wit/gui" + witlog.Log(a...) +} + +func sleep(a ...any) { + witlog.Sleep(a...) +} + +func exit(a ...any) { + log(logError, "got to log() exit") + witlog.Exit(a...) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..f21c131 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module go.wit.com/control-panel-dns + +go 1.21.4 diff --git a/gui.go b/gui.go index 3eb8582..0ba5d54 100644 --- a/gui.go +++ b/gui.go @@ -10,8 +10,8 @@ import ( "net" "strings" - "git.wit.org/wit/gui" - "git.wit.org/wit/shell" + "go.wit.com/gui" + "go.wit.com/shell" "github.com/davecgh/go-spew/spew" ) diff --git a/hostname.go b/hostname.go index 06e2ce7..a0da280 100644 --- a/hostname.go +++ b/hostname.go @@ -6,12 +6,10 @@ package main import ( - "git.wit.org/wit/shell" + "go.wit.com/shell" - // dnssec IPv6 socket library - "git.wit.org/jcarr/dnssecsocket" - - "git.wit.org/jcarr/control-panel-dns/cloudflare" + "go.wit.com/control-panel-dns/cloudflare" + "go.wit.com/control-panel-dns/dnssecsocket" ) // will try to get this hosts FQDN diff --git a/log.go b/log.go index 252f4da..12ee261 100644 --- a/log.go +++ b/log.go @@ -3,7 +3,7 @@ package main import ( "log" "reflect" - witlog "git.wit.org/wit/gui/log" + witlog "go.wit.com/gui/log" ) var LogPrefix = "ipv6cp" // ipv6 control panel debugging line diff --git a/main.go b/main.go index 657d989..13ab381 100644 --- a/main.go +++ b/main.go @@ -13,7 +13,7 @@ import ( "time" "embed" - "git.wit.org/wit/gui" + "go.wit.com/gui" "github.com/miekg/dns" ) diff --git a/nsupdate.go b/nsupdate.go index db33018..6aef147 100644 --- a/nsupdate.go +++ b/nsupdate.go @@ -12,7 +12,7 @@ import ( // ./go-nsupdate \ // --tsig-algorithm=hmac-sha512 \ // --tsig-secret="OWh5/ZHIyaz7B8J9m9ZDqZ8448Pke0PTpkYbZmFcOf5a6rEzgmcwrG91u1BHi1/4us+mKKEobDPLw1x6sD+ZJw==" \ -// -i eno2 farm001.lab.wit.org +// -i eno2 farm001.lab.wit.com func nsupdate() { var tsigSecret string diff --git a/structs.go b/structs.go index 9671078..7424e9c 100644 --- a/structs.go +++ b/structs.go @@ -4,7 +4,7 @@ package main import ( "net" "time" - "git.wit.org/wit/gui" + "go.wit.com/gui" "github.com/miekg/dns" ) diff --git a/unix.go b/unix.go index e9776ae..722ec82 100644 --- a/unix.go +++ b/unix.go @@ -13,7 +13,7 @@ import ( "fmt" "strings" - "git.wit.org/wit/shell" + "go.wit.com/shell" ) func CheckSuperuser() bool { @@ -35,8 +35,8 @@ func Escalate() { } // You need permission to do a zone transfer. Otherwise: -// dig +noall +answer +multiline lab.wit.org any -// dig +all +multiline fire.lab.wit.org # gives the zonefile header (ttl vals) +// dig +noall +answer +multiline lab.wit.com any +// dig +all +multiline fire.lab.wit.com # gives the zonefile header (ttl vals) func DumpPublicDNSZone(zone string) { entries, err := net.LookupHost(zone) if err != nil {