2011-01-18 02:11:11 +11:00
|
|
|
/*
|
|
|
|
* A name server which sends back the IP address of its client, the
|
|
|
|
* recursive resolver. When queried for type TXT, it sends back the text
|
|
|
|
* form of the address. When queried for type A (resp. AAAA), it sends
|
|
|
|
* back the IPv4 (resp. v6) address.
|
2011-02-12 06:54:54 +11:00
|
|
|
*
|
2011-01-18 02:11:11 +11:00
|
|
|
* Similar services: whoami.ultradns.net, whoami.akamai.net. Also (but it
|
|
|
|
* is not their normal goal): rs.dns-oarc.net, porttest.dns-oarc.net,
|
|
|
|
* amiopen.openresolvers.org.
|
2011-02-12 06:54:54 +11:00
|
|
|
*
|
2011-12-17 05:17:04 +11:00
|
|
|
* Original version from:
|
2011-01-18 02:11:11 +11:00
|
|
|
* Stephane Bortzmeyer <stephane+grong@bortzmeyer.org>
|
|
|
|
*
|
2011-07-06 03:17:29 +10:00
|
|
|
* Adapted to Go DNS (i.e. completely rewritten)
|
2011-12-17 05:17:04 +11:00
|
|
|
* Miek Gieben <miek@miek.nl>
|
2011-01-18 02:11:11 +11:00
|
|
|
*/
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2012-01-13 08:19:42 +11:00
|
|
|
"flag"
|
2011-02-12 07:29:40 +11:00
|
|
|
"fmt"
|
2012-08-24 20:42:41 +10:00
|
|
|
"github.com/miekg/dns"
|
2011-12-17 05:17:04 +11:00
|
|
|
"log"
|
2011-12-17 03:37:21 +11:00
|
|
|
"net"
|
2012-01-13 08:19:42 +11:00
|
|
|
"os"
|
2012-02-26 08:47:26 +11:00
|
|
|
"os/signal"
|
2012-01-13 08:19:42 +11:00
|
|
|
"runtime/pprof"
|
2011-07-06 03:17:29 +10:00
|
|
|
"strconv"
|
2012-03-05 07:00:09 +11:00
|
|
|
"strings"
|
2012-08-29 05:36:25 +10:00
|
|
|
"syscall"
|
2012-03-05 07:00:09 +11:00
|
|
|
"time"
|
2011-01-18 02:11:11 +11:00
|
|
|
)
|
|
|
|
|
2012-02-27 04:23:21 +11:00
|
|
|
var (
|
2012-03-06 08:03:18 +11:00
|
|
|
printf *bool
|
2012-02-27 04:23:21 +11:00
|
|
|
compress *bool
|
2012-03-06 08:03:18 +11:00
|
|
|
tsig *string
|
2012-02-27 04:23:21 +11:00
|
|
|
)
|
2012-02-26 19:54:50 +11:00
|
|
|
|
2012-01-13 22:36:05 +11:00
|
|
|
const dom = "whoami.miek.nl."
|
2011-07-06 04:01:17 +10:00
|
|
|
|
2011-07-05 22:58:02 +10:00
|
|
|
func handleReflect(w dns.ResponseWriter, r *dns.Msg) {
|
2011-12-17 03:37:21 +11:00
|
|
|
var (
|
|
|
|
v4 bool
|
|
|
|
rr dns.RR
|
|
|
|
str string
|
|
|
|
a net.IP
|
|
|
|
)
|
2012-02-27 06:09:03 +11:00
|
|
|
// TC must be done here
|
2012-01-13 22:29:25 +11:00
|
|
|
m := new(dns.Msg)
|
|
|
|
m.SetReply(r)
|
2012-02-27 04:23:21 +11:00
|
|
|
m.Compress = *compress
|
2011-12-17 03:37:21 +11:00
|
|
|
if ip, ok := w.RemoteAddr().(*net.UDPAddr); ok {
|
|
|
|
str = "Port: " + strconv.Itoa(ip.Port) + " (udp)"
|
|
|
|
a = ip.IP
|
|
|
|
v4 = a.To4() != nil
|
|
|
|
}
|
|
|
|
if ip, ok := w.RemoteAddr().(*net.TCPAddr); ok {
|
|
|
|
str = "Port: " + strconv.Itoa(ip.Port) + " (tcp)"
|
|
|
|
a = ip.IP
|
|
|
|
v4 = a.To4() != nil
|
|
|
|
}
|
2011-07-06 03:17:29 +10:00
|
|
|
|
|
|
|
if v4 {
|
|
|
|
rr = new(dns.RR_A)
|
2011-12-17 03:37:21 +11:00
|
|
|
rr.(*dns.RR_A).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0}
|
2011-12-18 06:14:39 +11:00
|
|
|
rr.(*dns.RR_A).A = a.To4()
|
2011-07-06 03:17:29 +10:00
|
|
|
} else {
|
|
|
|
rr = new(dns.RR_AAAA)
|
2011-12-17 03:37:21 +11:00
|
|
|
rr.(*dns.RR_AAAA).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0}
|
2011-07-06 03:17:29 +10:00
|
|
|
rr.(*dns.RR_AAAA).AAAA = a
|
|
|
|
}
|
2011-01-18 02:11:11 +11:00
|
|
|
|
2011-01-28 06:16:58 +11:00
|
|
|
t := new(dns.RR_TXT)
|
2011-07-06 04:01:17 +10:00
|
|
|
t.Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0}
|
2012-02-14 01:59:40 +11:00
|
|
|
t.Txt = []string{str}
|
2011-12-18 06:14:39 +11:00
|
|
|
|
2012-02-26 19:54:50 +11:00
|
|
|
switch r.Question[0].Qtype {
|
2012-08-28 21:12:55 +10:00
|
|
|
case dns.TypeAXFR:
|
|
|
|
c := make(chan *dns.XfrToken)
|
|
|
|
var e *error
|
|
|
|
if err := dns.XfrSend(w, r, c, e); err != nil {
|
|
|
|
close(c)
|
|
|
|
return
|
|
|
|
}
|
2012-08-29 04:21:44 +10:00
|
|
|
soa, _ := dns.NewRR(`whoami.miek.nl. IN SOA elektron.atoom.net. miekg.atoom.net. (
|
2012-08-28 21:12:55 +10:00
|
|
|
2009032802
|
|
|
|
21600
|
|
|
|
7200
|
|
|
|
604800
|
|
|
|
3600)`)
|
|
|
|
c <- &dns.XfrToken{RR: []dns.RR{soa, t, rr, soa}}
|
|
|
|
close(c)
|
2012-08-29 03:53:21 +10:00
|
|
|
w.Hijack()
|
2012-08-29 04:29:06 +10:00
|
|
|
// w.Close() // Client closes
|
2012-08-28 21:12:55 +10:00
|
|
|
return
|
2012-02-26 19:54:50 +11:00
|
|
|
case dns.TypeTXT:
|
2012-01-13 22:36:05 +11:00
|
|
|
m.Answer = append(m.Answer, t)
|
|
|
|
m.Extra = append(m.Extra, rr)
|
2012-02-26 19:54:50 +11:00
|
|
|
default:
|
|
|
|
fallthrough
|
|
|
|
case dns.TypeAAAA, dns.TypeA:
|
2012-01-13 22:36:05 +11:00
|
|
|
m.Answer = append(m.Answer, rr)
|
|
|
|
m.Extra = append(m.Extra, t)
|
2012-02-26 19:54:50 +11:00
|
|
|
}
|
2012-01-15 23:53:32 +11:00
|
|
|
|
2012-08-28 19:19:03 +10:00
|
|
|
if r.IsTsig() != nil {
|
2012-03-05 07:00:09 +11:00
|
|
|
if w.TsigStatus() == nil {
|
2012-05-21 22:56:14 +10:00
|
|
|
m.SetTsig(r.Extra[len(r.Extra)-1].(*dns.RR_TSIG).Hdr.Name, dns.HmacMD5, 300, time.Now().Unix())
|
2012-03-06 08:03:18 +11:00
|
|
|
} else {
|
|
|
|
println("Status", w.TsigStatus().Error())
|
2012-03-05 07:00:09 +11:00
|
|
|
}
|
|
|
|
}
|
2012-02-26 19:54:50 +11:00
|
|
|
if *printf {
|
|
|
|
fmt.Printf("%v\n", m.String())
|
|
|
|
}
|
2012-03-05 08:32:23 +11:00
|
|
|
w.Write(m)
|
2011-01-18 02:11:11 +11:00
|
|
|
}
|
2011-01-19 07:34:22 +11:00
|
|
|
|
2012-03-05 07:00:09 +11:00
|
|
|
func serve(net, name, secret string) {
|
|
|
|
switch name {
|
|
|
|
case "":
|
|
|
|
err := dns.ListenAndServe(":8053", net, nil)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("Failed to setup the "+net+" server: %s\n", err.Error())
|
|
|
|
}
|
|
|
|
default:
|
2012-08-24 20:42:41 +10:00
|
|
|
server := &dns.Server{Addr: ":8053", Net: "net", TsigSecret: map[string]string{name: secret}}
|
2012-08-08 17:50:21 +10:00
|
|
|
err := server.ListenAndServe()
|
2012-03-05 07:00:09 +11:00
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("Failed to setup the "+net+" server: %s\n", err.Error())
|
|
|
|
}
|
2011-12-17 03:37:21 +11:00
|
|
|
}
|
2011-07-06 03:44:46 +10:00
|
|
|
}
|
|
|
|
|
2011-02-12 06:54:54 +11:00
|
|
|
func main() {
|
2012-01-13 08:19:42 +11:00
|
|
|
cpuprofile := flag.String("cpuprofile", "", "write cpu profile to file")
|
2012-01-16 01:50:19 +11:00
|
|
|
printf = flag.Bool("print", false, "print replies")
|
2012-02-27 04:23:21 +11:00
|
|
|
compress = flag.Bool("compress", false, "compress replies")
|
2012-03-05 07:00:09 +11:00
|
|
|
tsig = flag.String("tsig", "", "use MD5 hmac tsig: keyname:base64")
|
|
|
|
var name, secret string
|
2012-01-13 08:19:42 +11:00
|
|
|
flag.Usage = func() {
|
|
|
|
flag.PrintDefaults()
|
|
|
|
}
|
|
|
|
flag.Parse()
|
2012-03-05 07:00:09 +11:00
|
|
|
if *tsig != "" {
|
|
|
|
a := strings.SplitN(*tsig, ":", 2)
|
|
|
|
name, secret = a[0], a[1]
|
|
|
|
}
|
2012-01-13 08:19:42 +11:00
|
|
|
if *cpuprofile != "" {
|
|
|
|
f, err := os.Create(*cpuprofile)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
pprof.StartCPUProfile(f)
|
|
|
|
defer pprof.StopCPUProfile()
|
|
|
|
}
|
|
|
|
|
2012-09-17 02:46:40 +10:00
|
|
|
dns.HandleFunc("miek.nl.", handleReflect)
|
2012-09-03 20:54:18 +10:00
|
|
|
dns.HandleFunc("authors.bind.", dns.HandleAuthors)
|
|
|
|
dns.HandleFunc("authors.server.", dns.HandleAuthors)
|
2012-09-03 21:56:43 +10:00
|
|
|
dns.HandleFunc("version.bind.", dns.HandleVersion)
|
|
|
|
dns.HandleFunc("version.server.", dns.HandleVersion)
|
2012-03-05 07:00:09 +11:00
|
|
|
go serve("tcp", name, secret)
|
|
|
|
go serve("udp", name, secret)
|
2012-02-26 08:47:26 +11:00
|
|
|
sig := make(chan os.Signal)
|
2012-08-29 05:36:25 +10:00
|
|
|
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
|
2011-07-06 03:17:29 +10:00
|
|
|
forever:
|
2011-12-17 03:37:21 +11:00
|
|
|
for {
|
|
|
|
select {
|
2012-08-29 05:36:25 +10:00
|
|
|
case s:=<-sig:
|
|
|
|
fmt.Printf("Signal (%d) received, stopping\n", s)
|
2011-12-17 03:37:21 +11:00
|
|
|
break forever
|
|
|
|
}
|
|
|
|
}
|
2011-01-18 02:11:11 +11:00
|
|
|
}
|