miekg / dns

DNS library in Go
https://miek.nl/2014/august/16/go-dns-package
BSD 3-Clause "New" or "Revised" License
7.86k stars 1.12k forks source link

Wildcard domains as per RFC-4592 #1534

Open Cottand opened 5 months ago

Cottand commented 5 months ago

Hi!

My understanding is this lib should support RFC-4592 (wildcard domains, as stated in the README). I am trying to use wildcard domains RRs with the following example:

// make a simple fake dns.ResponseWriter
type mockRw struct {
    stored *dns.Msg
}

func (m *mockRw) WriteMsg(msg *dns.Msg) error {
    m.stored = msg
    return nil
}

// returns a handler that returns TXT record
func ServerReplyTXT(txt string) dns.HandlerFunc {
    return func(w dns.ResponseWriter, req *dns.Msg) {
        m := new(dns.Msg)
        m.SetReply(req)

        m.Answer = make([]dns.RR, 1)
        m.Answer[0] = &dns.TXT{Hdr: dns.RR_Header{Name: m.Question[0].Name, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0}, Txt: []string{txt}}
        _ = w.WriteMsg(m)
    }
}

func TestWildcardInLib(t *testing.T) {
    serveMux := dns.NewServeMux()

    serveMux.HandleFunc(".", ServerReplyTXT("root"))
    serveMux.HandleFunc("example.com.", ServerReplyTXT("example"))
    serveMux.HandleFunc("*.example.com.", ServerReplyTXT("wildcard"))

    rw := mockRw{stored: nil}

    msg := new(dns.Msg)
    msg.SetQuestion("banana.example.com", dns.TypeTXT)

    serveMux.ServeDNS(&rw, msg)
    println(rw.stored.Answer[0].String()) // prints: `example`, I expected `wildcard`

}

My understandig of RFC-4592 section 2.2.1 is that the above should print wildcard (because it matches *.example.com) but it prints example instead.

Did I misunderstand the RFC or perhaps am I using the library wrong? I did not find anything else mentioning 'wildcard' in the README and these tests do not seem to be testing matching wildcard domains.

Thanks in advance

miekg commented 5 months ago

I don't think this is implemented, nor, e.g., DS handling

On Sat, 3 Feb 2024, 15:58 Cottand, @.***> wrote:

Hi!

My understanding is this lib should support RFC-4592 (wildcard domains, as stated in the README). I am trying to use wildcard domains RRs with the following example:

// make a simple fake dns.ResponseWritertype mockRw struct { stored dns.Msg } func (m mockRw) WriteMsg(msg dns.Msg) error { m.stored = msg return nil } // returns a handler that returns TXT recordfunc ServerReplyTXT(txt string) dns.HandlerFunc { return func(w dns.ResponseWriter, req dns.Msg) { m := new(dns.Msg) m.SetReply(req)

  m.Answer = make([]dns.RR, 1)
  m.Answer[0] = &dns.TXT{Hdr: dns.RR_Header{Name: m.Question[0].Name, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0}, Txt: []string{txt}}
  _ = w.WriteMsg(m)

} }

func TestWildcardInLib(t *testing.T) { serveMux := dns.NewServeMux()

serveMux.HandleFunc(".", ServerReplyTXT("root")) serveMux.HandleFunc("example.com.", ServerReplyTXT("example")) serveMux.HandleFunc("*.example.com.", ServerReplyTXT("wildcard"))

rw := mockRw{stored: nil}

msg := new(dns.Msg) msg.SetQuestion("banana.example.com", dns.TypeTXT)

serveMux.ServeDNS(&rw, msg) println(rw.stored.Answer[0].String()) // prints: example, I expected wildcard

}

My understandig of RFC-4592 section 2.2.10 https://datatracker.ietf.org/doc/html/rfc4592#section-2.2.10 is that the above should print wildcard (because it matches *.example.com) but it prints example instead.

Did I misunderstand the RFC or perhaps am I using the library wrong? I did not find anything else mentioning 'wildcard' in the README and these tests https://github.com/miekg/dns/blob/master/serve_mux_test.go do not seem to be testing matching wildcard domains.

Thanks in advance

— Reply to this email directly, view it on GitHub https://github.com/miekg/dns/issues/1534, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACWIW54UUFUVXH52BQZCB3YRZGCNAVCNFSM6AAAAABCYC2RPGVHI2DSMVQWIX3LMV43ASLTON2WKOZSGEYTMNJSGA4TENY . You are receiving this because you are subscribed to this thread.Message ID: @.***>

Cottand commented 5 months ago

Thanks for the quick reply

In that case, do you think it would be fair to either implement it, or remove RFC-4592 from the list of supported RFCs in the README?

Otherwise I would have expected it to work

miekg commented 5 months ago

No, but maybe the handlefunc docs or some other docs could be improved.

On Sat, 3 Feb 2024, 18:20 Cottand, @.***> wrote:

Thanks for the quick reply

In that case, do you think it would be fair to either implement it, or remove RFC-4592 from the list of supported RFCs in the README?

Otherwise I would have expected it to work

— Reply to this email directly, view it on GitHub https://github.com/miekg/dns/issues/1534#issuecomment-1925400252, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACWIW3OG76K2SFRVYSE7OLYRZWXDAVCNFSM6AAAAABCYC2RPGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMRVGQYDAMRVGI . You are receiving this because you commented.Message ID: @.***>

Cottand commented 5 months ago

Ok no worries, I will implement on my end, thank you.

In that case, would you mind clarifying how exactly is this library compliant with RFC-4592? Is there use of wildcards elsewhere?

miekg commented 5 months ago

ha, i see we do do DS handling, probably wildcard handling should be done as well

Cottand commented 5 months ago

that's good to hear!

miekg commented 4 months ago

[ Quoting @.***> in "Re: [miekg/dns] Wildcard domains as..." ]

that's good to hear!

should be possible to lift this out of CoreDNS' loop, but I want have any spare cycles to do this any time soon

/Miek

Cottand commented 4 months ago

If you point me to the file(s) in CoreDNS I can have a stab a it

miekg commented 4 months ago

[ Quoting @.***> in "Re: [miekg/dns] Wildcard domains as..." ]

If you point me to the file in CoreDNS I can have a stab a it

maybe here: https://github.com/coredns/coredns/blob/master/plugin/file/lookup.go

althought that is more complex. I think this checking for wildcard label if there is no match should be sufficient

/Miek

-- Miek Gieben

Cottand commented 4 months ago

See https://github.com/miekg/dns/pull/1536 as step 1. I chose not to add CoreDNS' complexity to the simple match function until I fully understood the code there