mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-12 13:48:01 +00:00
cli: add tailscale dns query
(#13368)
Updates tailscale/tailscale#13326 Adds a CLI subcommand to perform DNS queries using the internal DNS forwarder and observe its internals (namely, which upstream resolvers are being used). Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
This commit is contained in:
@@ -38,6 +38,7 @@ import (
|
||||
"go4.org/mem"
|
||||
"go4.org/netipx"
|
||||
xmaps "golang.org/x/exp/maps"
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"tailscale.com/appc"
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
@@ -606,6 +607,50 @@ func (b *LocalBackend) GetDNSOSConfig() (dns.OSConfig, error) {
|
||||
return manager.GetBaseConfig()
|
||||
}
|
||||
|
||||
// QueryDNS performs a DNS query for name and queryType using the built-in DNS resolver, and returns
|
||||
// the raw DNS response and the resolvers that are were able to handle the query (the internal forwarder
|
||||
// may race multiple resolvers).
|
||||
func (b *LocalBackend) QueryDNS(name string, queryType dnsmessage.Type) (res []byte, resolvers []*dnstype.Resolver, err error) {
|
||||
manager, ok := b.sys.DNSManager.GetOK()
|
||||
if !ok {
|
||||
return nil, nil, errors.New("DNS manager not available")
|
||||
}
|
||||
fqdn, err := dnsname.ToFQDN(name)
|
||||
if err != nil {
|
||||
b.logf("DNSQuery: failed to parse FQDN %q: %v", name, err)
|
||||
return nil, nil, err
|
||||
}
|
||||
n, err := dnsmessage.NewName(fqdn.WithTrailingDot())
|
||||
if err != nil {
|
||||
b.logf("DNSQuery: failed to parse name %q: %v", name, err)
|
||||
return nil, nil, err
|
||||
}
|
||||
from := netip.MustParseAddrPort("127.0.0.1:0")
|
||||
db := dnsmessage.NewBuilder(nil, dnsmessage.Header{
|
||||
OpCode: 0,
|
||||
RecursionDesired: true,
|
||||
ID: 1,
|
||||
})
|
||||
db.StartQuestions()
|
||||
db.Question(dnsmessage.Question{
|
||||
Name: n,
|
||||
Type: queryType,
|
||||
Class: dnsmessage.ClassINET,
|
||||
})
|
||||
q, err := db.Finish()
|
||||
if err != nil {
|
||||
b.logf("DNSQuery: failed to build query: %v", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
res, err = manager.Query(b.ctx, q, "tcp", from)
|
||||
if err != nil {
|
||||
b.logf("DNSQuery: failed to query %q: %v", name, err)
|
||||
return nil, nil, err
|
||||
}
|
||||
rr := manager.Resolver().GetUpstreamResolvers(fqdn)
|
||||
return res, rr, nil
|
||||
}
|
||||
|
||||
// GetComponentDebugLogging gets the time that component's debug logging is
|
||||
// enabled until, or the zero time if component's time is not currently
|
||||
// enabled.
|
||||
|
Reference in New Issue
Block a user