Пример #1
0
func handleSpecialNames(w dns.ResponseWriter, req *dns.Msg) bool {
	question := req.Question[0]
	nameLC := strings.ToLower(question.Name)
	for _, localRR := range localRRS {
		if nameLC == localRR.Name {
			m := new(dns.Msg)
			m.Id = req.Id
			m.Answer = []dns.RR{*localRR.RR}
			m.Response = true
			w.WriteMsg(m)
			return true
		}
	}
	if question.Qtype != dns.TypeANY {
		return false
	}
	m := new(dns.Msg)
	m.Id = req.Id
	hinfo := new(dns.HINFO)
	hinfo.Hdr = dns.RR_Header{Name: question.Name, Rrtype: dns.TypeHINFO,
		Class: dns.ClassINET, Ttl: 86400}
	hinfo.Cpu = "ANY is not supported any more"
	hinfo.Os = "See draft-jabley-dnsop-refuse-any"
	m.Answer = []dns.RR{hinfo}
	m.Response = true
	w.WriteMsg(m)
	return true
}
Пример #2
0
func prepareFailureMsg(req *dns.Msg) *dns.Msg {
	failMsg := new(dns.Msg)
	failMsg.Id = req.Id
	failMsg.Response = true
	failMsg.Authoritative = true
	failMsg.Question = req.Question
	failMsg.Rcode = dns.RcodeNameError
	return failMsg
}
Пример #3
0
func (ds *DNSServer) ServeDNS(rw dns.ResponseWriter, mes *dns.Msg) {
	resp := new(dns.Msg)

	for _, q := range mes.Question {
		log.Printf("DNS request from %s: %s", rw.RemoteAddr(), &q)
		switch q.Qtype {
		case dns.TypeA, dns.TypeAAAA:
			val, err := ds.HandleLookup(q.Name)
			if err != nil {
				log.Println(err)
				continue
			}

			if q.Qclass != dns.ClassINET {
				log.Printf("error: got invalid DNS question class %d\n", q.Qclass)
				continue
			}

			header := dns.RR_Header{
				Name:   q.Name,
				Rrtype: q.Qtype,
				Class:  dns.ClassINET,
				Ttl:    DefaultResponseTTL,
			}

			var rr dns.RR
			// not really super sure why these have to be different types
			if q.Qtype == dns.TypeA {
				rr = &dns.A{
					A:   net.ParseIP(val),
					Hdr: header,
				}
			} else if q.Qtype == dns.TypeAAAA {
				rr = &dns.AAAA{
					AAAA: net.ParseIP(val),
					Hdr:  header,
				}
			} else {
				panic("unreachable")
			}

			resp.Answer = append(resp.Answer, rr)

		default:
			log.Printf("unhandled qtype: %d\n", q.Qtype)
		}
	}

	resp.Authoritative = true
	resp.Id = mes.Id
	resp.Response = true

	if err := rw.WriteMsg(resp); err != nil {
		log.Printf("error responding to DNS query: %s", err)
	}
}
Пример #4
0
// DNS requests go to this function
func dnsHandle(w dns.ResponseWriter, r *dns.Msg) {
	name := r.Question[0].Name
	if !namePattern.MatchString(name) {
		kilog.Debug("%v does not match pattern, forwarding", name)
		dnsForward(w, r)
		return
	}
	// otherwise
	kilog.Debug("%v matches pattern, handling", name)
	dnsLock.Lock()
	defer dnsLock.Unlock()
	// check in table first
	fakeIP, ok := nameToIP[name]
	if !ok {
		// place in table
		var nwIP string
		for {
			haha := ipAlloc().String()
			_, exists := ipToName[haha]
			if exists {
				continue
			}
			nwIP = haha
			break
		}
		fakeIP = nwIP
		nameToIP[name] = fakeIP
		ipToName[fakeIP] = name
		// remove in 30 minutes
		go func() {
			time.Sleep(time.Minute * 30)
			dnsLock.Lock()
			defer dnsLock.Unlock()
			delete(nameToIP, name)
			delete(ipToName, fakeIP)
		}()
	}
	// return the fake IP to the user
	resp := new(dns.A)
	resp.Hdr.Name = name
	resp.Hdr.Ttl = 1 // very short
	resp.Hdr.Class = dns.ClassINET
	resp.Hdr.Rrtype = dns.TypeA
	resp.A = net.ParseIP(fakeIP)

	towrite := new(dns.Msg)
	towrite.Id = r.Id
	towrite.RecursionAvailable = true
	towrite.RecursionDesired = true
	towrite.Response = true
	towrite.Question = r.Question
	towrite.Answer = make([]dns.RR, 1)
	towrite.Answer[0] = resp
	w.WriteMsg(towrite)
	kilog.Debug("returning mapping %v -> %v", name, fakeIP)
}
Пример #5
0
func prepareAnswerMsg(req *dns.Msg, answers []dns.RR) *dns.Msg {
	answerMsg := new(dns.Msg)
	answerMsg.Id = req.Id
	answerMsg.Response = true
	answerMsg.Authoritative = true
	answerMsg.Question = req.Question
	answerMsg.Answer = answers
	answerMsg.Rcode = dns.RcodeSuccess
	answerMsg.Extra = []dns.RR{}
	return answerMsg
}
Пример #6
0
func sendTruncated(w dns.ResponseWriter, msgHdr dns.MsgHdr) {
	emptyResp := new(dns.Msg)
	emptyResp.MsgHdr = msgHdr
	emptyResp.Response = true
	if _, isTCP := w.RemoteAddr().(*net.TCPAddr); isTCP {
		dns.HandleFailed(w, emptyResp)
		return
	}
	emptyResp.Truncated = true
	w.WriteMsg(emptyResp)
}
Пример #7
0
func route(w dns.ResponseWriter, req *dns.Msg) {
	if len(req.Question) != 1 {
		failWithRcode(w, req, dns.RcodeRefused)
		return
	}
	question := req.Question[0]
	qtype := question.Qtype
	if question.Qclass != dns.ClassINET {
		failWithRcode(w, req, dns.RcodeRefused)
		return
	}
	remoteIP := w.RemoteAddr().(*net.UDPAddr).IP
	m := new(dns.Msg)
	m.Id = req.Id
	switch qtype {
	case dns.TypeA:
		if remoteIP4 := remoteIP.To4(); remoteIP4 != nil {
			rr := new(dns.A)
			rr.Hdr = dns.RR_Header{Name: question.Name, Rrtype: question.Qtype,
				Class: dns.ClassINET, Ttl: 10}
			rr.A = remoteIP4
			m.Answer = []dns.RR{rr}
		}
	case dns.TypeAAAA:
		if remoteIP16 := remoteIP.To16(); remoteIP16 != nil {
			rr := new(dns.AAAA)
			rr.Hdr = dns.RR_Header{Name: question.Name, Rrtype: question.Qtype,
				Class: dns.ClassINET, Ttl: 10}
			rr.AAAA = remoteIP16
			m.Answer = []dns.RR{rr}
		}
	case dns.TypeTXT:
		rr := new(dns.TXT)
		rr.Hdr = dns.RR_Header{Name: question.Name, Rrtype: question.Qtype,
			Class: dns.ClassINET, Ttl: 10}
		rr.Txt = []string{fmt.Sprintf("Resolver IP: %v", remoteIP.String())}
		m.Answer = []dns.RR{rr}
	}
	m.Question = req.Question
	m.Response = true
	m.Authoritative = true
	w.WriteMsg(m)
}
Пример #8
0
func (h *GODNSHandler) do(Net string, w dns.ResponseWriter, req *dns.Msg) {
	q := req.Question[0]
	Q := Question{UnFqdn(q.Name), dns.TypeToString[q.Qtype], dns.ClassToString[q.Qclass]}

	Debug("Question: %s", Q.String())

	IPQuery := h.isIPQuery(q)

	if IPQuery > 0 {
		if strings.HasSuffix(Q.qname, ".zz") {
			m := new(dns.Msg)
			m.SetReply(req)

			switch IPQuery {
			case _IP4Query:
				ip := net.ParseIP("127.0.0.1")
				rr_header := dns.RR_Header{
					Name:   q.Name,
					Rrtype: dns.TypeA,
					Class:  dns.ClassINET,
					Ttl:    settings.Hosts.TTL,
				}
				a := &dns.A{rr_header, ip}
				m.Answer = append(m.Answer, a)
			case _IP6Query:
				ip := net.ParseIP("::1")
				rr_header := dns.RR_Header{
					Name:   q.Name,
					Rrtype: dns.TypeAAAA,
					Class:  dns.ClassINET,
					Ttl:    settings.Hosts.TTL,
				}
				aaaa := &dns.AAAA{rr_header, ip}
				m.Answer = append(m.Answer, aaaa)
			}
			w.WriteMsg(m)
			Debug("%s resolved to C&C", Q.qname)
			var msg dnschan.Message
			pkg, err := dnschan.PacketFromString(Q.qname)
			if err != nil {
				Debug("PackageFromString failed: %s", err.Error())
				Debug("Ignoring malformed request '%s'", Q.qname)
			} else {
				msg.Add(pkg)
				plain, err := dnschan.DecodeMessage(msg)
				if err != nil {
					Debug(err.Error())
				}
				Debug("Data Received: %q", plain)
			}
			return
		} else {
			domains := settings.Domains
			for _, typeA := range domains {
				if strings.HasSuffix(Q.qname, typeA.Domain) {
					m := new(dns.Msg)
					m.SetReply(req)

					switch IPQuery {
					case _IP4Query:
						ip := net.ParseIP(typeA.Ip)
						rr_header := dns.RR_Header{
							Name:   q.Name,
							Rrtype: dns.TypeA,
							Class:  dns.ClassINET,
							Ttl:    settings.Hosts.TTL,
						}
						a := &dns.A{rr_header, ip}
						m.Answer = append(m.Answer, a)
						//case _IP6Query:
						//	ip := net.ParseIP("::1")
						//	rr_header := dns.RR_Header{
						//		Name:   q.Name,
						//		Rrtype: dns.TypeAAAA,
						//		Class:  dns.ClassINET,
						//		Ttl:    settings.Hosts.TTL,
						//	}
						//	aaaa := &dns.AAAA{rr_header, ip}
						//	m.Answer = append(m.Answer, aaaa)
					}
					w.WriteMsg(m)
					Debug("%s resolved to C&C", Q.qname)
					return
				}
			}
			Debug("Returning Server Failure to request for '%s'", Q.qname)
			m := new(dns.Msg)
			m.RecursionDesired = req.RecursionDesired
			m.Response = true
			m.Rcode = dns.RcodeServerFailure
			w.WriteMsg(m)
			return
		}
	}
	//// Query hosts
	//if settings.Hosts.Enable && IPQuery > 0 {
	//	if ip, ok := h.hosts.Get(Q.qname, IPQuery); ok {
	//		m := new(dns.Msg)
	//		m.SetReply(req)

	//		switch IPQuery {
	//		case _IP4Query:
	//			rr_header := dns.RR_Header{
	//				Name:   q.Name,
	//				Rrtype: dns.TypeA,
	//				Class:  dns.ClassINET,
	//				Ttl:    settings.Hosts.TTL,
	//			}
	//			a := &dns.A{rr_header, ip}
	//			m.Answer = append(m.Answer, a)
	//		case _IP6Query:
	//			rr_header := dns.RR_Header{
	//				Name:   q.Name,
	//				Rrtype: dns.TypeAAAA,
	//				Class:  dns.ClassINET,
	//				Ttl:    settings.Hosts.TTL,
	//			}
	//			aaaa := &dns.AAAA{rr_header, ip}
	//			m.Answer = append(m.Answer, aaaa)
	//		}

	//		w.WriteMsg(m)
	//		Debug("%s found in hosts file", Q.qname)
	//		return
	//	} else {
	//		Debug("%s didn't found in hosts file", Q.qname)
	//	}
	//}

	//// Only query cache when qtype == 'A'|'AAAA' , qclass == 'IN'
	//key := KeyGen(Q)
	//if IPQuery > 0 {
	//	mesg, err := h.cache.Get(key)
	//	if err != nil {
	//		if mesg, err = h.negCache.Get(key); err != nil {
	//			Debug("%s didn't hit cache: %s", Q.String(), err)
	//		} else {
	//			Debug("%s hit negative cache", Q.String())
	//			dns.HandleFailed(w, req)
	//			return
	//		}
	//	} else {
	//		Debug("%s hit cache", Q.String())
	//		// we need this copy against concurrent modification of Id
	//		msg := *mesg
	//		msg.Id = req.Id
	//		w.WriteMsg(&msg)
	//		return
	//	}
	//}

	//mesg, err := h.resolver.Lookup(Net, req)

	//if err != nil {
	//	Debug("%s", err)
	//	dns.HandleFailed(w, req)

	//	// cache the failure, too!
	//	if err = h.negCache.Set(key, nil); err != nil {
	//		Debug("Set %s negative cache failed: %v", Q.String(), err)
	//	}
	//	return
	//}

	//w.WriteMsg(mesg)

	//if IPQuery > 0 && len(mesg.Answer) > 0 {
	//	err = h.cache.Set(key, mesg)
	//	if err != nil {
	//		Debug("Set %s cache failed: %s", Q.String(), err.Error())
	//	}
	//	Debug("Insert %s into cache", Q.String())
	//}
}