Skip to content

Commit

Permalink
fix local dns proxy. (#487)
Browse files Browse the repository at this point in the history
Signed-off-by: Cybwan <[email protected]>
  • Loading branch information
cybwan authored Nov 30, 2024
1 parent 25451af commit a2a08b2
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 27 deletions.
82 changes: 60 additions & 22 deletions pkg/dns/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ func NewHandler(config *Config) *DNSHandler {
return handler
}

func (h *DNSHandler) getSuffixDomains(trustDomain string) []string {
suffixes := []string{fmt.Sprintf(`.svc.%s.`, trustDomain)}
sections := strings.Split(trustDomain, `.`)
for index := range sections {
suffixes = append(suffixes, fmt.Sprintf(`.%s.`, strings.Join(sections[index:], `.`)))
}
return suffixes
}

func (h *DNSHandler) getTrustDomainSearches(trustDomain, namespace string) []string {
searches := []string{fmt.Sprintf(`.svc.%s`, namespace)}
sections := strings.Split(trustDomain, `.`)
Expand All @@ -83,29 +92,32 @@ func (h *DNSHandler) getTrustDomainSearches(trustDomain, namespace string) []str
return searches
}

func (h *DNSHandler) getRawQName(qname string, suffixDomain string, trustDomain string) (string, string) {
func (h *DNSHandler) getRawQName(qname, trustDomain string) (string, string) {
fromNamespace := `default`
if strings.HasSuffix(qname, suffixDomain) {
qname = strings.TrimSuffix(qname, suffixDomain)
sections := strings.Split(qname, `.`)
ndots := len(sections)
if ndots > 2 {
fromNamespace = sections[len(sections)-1]
searches := h.getTrustDomainSearches(trustDomain, fromNamespace)
for _, search := range searches {
if strings.HasSuffix(qname, search) {
qname = strings.TrimSuffix(qname, search)
break
suffixDomains := h.getSuffixDomains(trustDomain)
for _, suffixDomain := range suffixDomains {
if strings.HasSuffix(qname, suffixDomain) {
qname = strings.TrimSuffix(qname, suffixDomain)
sections := strings.Split(qname, `.`)
ndots := len(sections)
if ndots > 1 {
fromNamespace = sections[len(sections)-1]
searches := h.getTrustDomainSearches(trustDomain, fromNamespace)
for _, search := range searches {
if strings.HasSuffix(qname, search) {
qname = strings.TrimSuffix(qname, search)
break
}
}
}
break
}
}
return qname, fromNamespace
return strings.TrimSuffix(qname, `.`), fromNamespace
}

func (h *DNSHandler) do(cfg *Config) {
trustDomain := service.GetTrustDomain()
suffixDomain := fmt.Sprintf(".svc.%s.", trustDomain)
for {
data, ok := <-h.requestChannel
if !ok {
Expand All @@ -116,8 +128,20 @@ func (h *DNSHandler) do(cfg *Config) {
_ = w.Close()
}(w)

var remote net.IP
if Net == "tcp" {
remote = w.RemoteAddr().(*net.TCPAddr).IP
} else {
remote = w.RemoteAddr().(*net.UDPAddr).IP
}

var origQuestions []dns.Question

for index, q := range req.Question {
qname, fromNamespace := h.getRawQName(q.Name, suffixDomain, trustDomain)
origQuestions = append(origQuestions, q)
qname, fromNamespace := h.getRawQName(q.Name, trustDomain)
log.Debug().Msgf("%s lookup q.Name:%s qname:%s namespace:%s trustDomain:%s", remote, q.Name, qname, fromNamespace, trustDomain)

segs := strings.Split(qname, `.`)
sections := len(segs)
if sections == 1 { //internal domain name
Expand All @@ -135,30 +159,27 @@ func (h *DNSHandler) do(cfg *Config) {

q := req.Question[0]
Q := Question{UnFqdn(q.Name), dns.TypeToString[q.Qtype], dns.ClassToString[q.Qclass]}
var remote net.IP
if Net == "tcp" {
remote = w.RemoteAddr().(*net.TCPAddr).IP
} else {
remote = w.RemoteAddr().(*net.UDPAddr).IP
}

log.Info().Msgf("%s lookup %s\n", remote, Q.String())
log.Debug().Msgf("%s lookup %s", remote, Q.String())

ipQuery := h.isIPQuery(q)
if ipQuery == 0 {
m := new(dns.Msg)
m.SetReply(req)
m.SetRcode(req, dns.RcodeNameError)
m.Question = origQuestions
h.WriteReplyMsg(w, m)
return
}

resp, err := h.resolver.Lookup(Net, req, cfg.GetTimeout(), cfg.GetInterval(), cfg.GetNameservers())
if err != nil {
log.Error().Msgf("resolve query error %s\n", err)
req.Question = origQuestions
h.HandleFailed(w, req)
return
}
resp.Question = origQuestions

if resp.Truncated && Net == "udp" {
resp, err = h.resolver.Lookup("tcp", req, cfg.GetTimeout(), cfg.GetInterval(), cfg.GetNameservers())
Expand All @@ -169,7 +190,10 @@ func (h *DNSHandler) do(cfg *Config) {
}
}

log.Debug().Msgf("%s lookup %s rcode:%d", remote, Q.String(), resp.Rcode)

if resp.Rcode == dns.RcodeNameError && cfg.IsWildcard() {
req.Question = origQuestions
h.HandleWildcard(req, cfg, ipQuery, &q, w)
return
}
Expand All @@ -194,6 +218,20 @@ func (h *DNSHandler) do(cfg *Config) {
break
}
}
case dns.TypeAAAA:
resp.Answer = nil
//aaaa := rr.(*dns.AAAA)
//ip := aaaa.AAAA
//if ip.IsUnspecified() || ip.IsLoopback() {
// for _, db := range dbs {
// if len(db.IPv6) > 0 {
// aaaa.AAAA = net.ParseIP(db.IPv6)
// resp.Answer[idx] = aaaa
// break
// }
// }
// break
//}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/dns/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ func (r *Resolver) Lookup(net string, req *dns.Msg, timeout int, interval int, n
return
}
if r != nil && r.Rcode != dns.RcodeSuccess {
log.Warn().Msgf("%s failed to get an valid answer on %s", qname, nameserver)
log.Debug().Msgf("%s failed to get a valid answer on %s", qname, nameserver)
if r.Rcode == dns.RcodeServerFailure {
return
}
} else {
log.Debug().Msgf("%s resolv on %s (%s)\n", UnFqdn(qname), nameserver, net)
log.Debug().Msgf("%s resolv on %s (%s)", UnFqdn(qname), nameserver, net)
}
select {
case res <- r:
Expand Down
4 changes: 2 additions & 2 deletions pkg/dns/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ func (s *Server) run(config *Config) {
}

func (s *Server) start(ds *dns.Server) {
log.Info().Msgf("start %s listener on %s\n", ds.Net, s.host)
log.Info().Msgf("start %s listener on %s", ds.Net, s.host)

if err := ds.ListenAndServe(); err != nil {
log.Error().Msgf("start %s listener on %s failed: %s\n", ds.Net, s.host, err.Error())
log.Error().Msgf("start %s listener on %s failed: %s", ds.Net, s.host, err.Error())
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/sidecar/providers/pipy/driver/pipy_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func getPipySidecarContainerSpec(injCtx *driver.InjectorContext, pod *corev1.Pod

pod.Spec.DNSPolicy = "None"
trustDomain := injCtx.CertManager.GetTrustDomain()
dots := "4"
dots := fmt.Sprintf("%d", len(strings.Split(trustDomain, `.`))+3)
searches := make([]string, 0)
if len(pod.Namespace) > 0 {
searches = append(searches, fmt.Sprintf("%s.svc.%s", pod.Namespace, trustDomain))
Expand Down

0 comments on commit a2a08b2

Please sign in to comment.