feat(dig): Dig +https (#147)
All checks were successful
continuous-integration/drone/push Build is passing

BREAKING CHANGE: DNS-over-HTTPS requests are now dealt with differently

Using +https or -H now implies adding /dns-query (like dig)
Using the implied https:// prefix follows the old behaviour (nothing added or implied)

Reviewed-on: #147
Reviewed-by: grumbulon <grumbulon@grumbulon.xyz>
This commit is contained in:
Sam Therapy 2022-10-20 21:34:24 +00:00
parent 59212798f7
commit b1fa25a9a0
Signed by: Froth Git
GPG key ID: 5D8CD75CC6B79913
7 changed files with 54 additions and 22 deletions

View file

@ -54,7 +54,7 @@ func ParseDig(arg string, opts *util.Options) error {
opts.Display.ShowClass = isNo
// EDNS queries
case "dnssec":
case "do", "dnssec":
opts.EDNS.DNSSEC = isNo
case "expire":
opts.EDNS.Expire = isNo
@ -79,8 +79,6 @@ func ParseDig(arg string, opts *util.Options) error {
opts.TLS = isNo
case "dnscrypt":
opts.DNSCrypt = isNo
case "https":
opts.HTTPS = isNo
case "quic":
opts.QUIC = isNo
// End DNS-over-X
@ -206,6 +204,18 @@ func parseDigEq(startNo bool, arg string, opts *util.Options) error {
opts.EDNS.Version = 0
}
case "https", "https-get", "https-post":
opts.HTTPS = startNo
if isSplit && val != "" {
opts.HTTPSOptions.Endpoint = val
} else {
opts.HTTPSOptions.Endpoint = "/dns-query"
}
if strings.HasSuffix(arg, "get") {
opts.HTTPSOptions.Get = true
}
case "subnet":
if isSplit && val != "" {
err := util.ParseSubnet(val, opts)

View file

@ -25,7 +25,7 @@ func FuzzDig(f *testing.F) {
"qr", "noqr",
"ttlunits", "nottlunits",
"ttlid", "nottlid",
"dnssec", "nodnssec",
"do", "dnssec", "nodo", "nodnssec",
"edns", "edns=a", "edns=0", "noedns",
"expire", "noexpire",
"ednsflags", "ednsflags=\"", "ednsflags=1", "noednsflags",
@ -43,7 +43,7 @@ func FuzzDig(f *testing.F) {
"badcookie", "nobadcookie",
"tls", "notls",
"dnscrypt", "nodnscrypt",
"https", "nohttps",
"https", "https=/dns", "https-get", "https-get=/", "nohttps",
"quic", "noquic",
"short", "noshort",
"identify", "noidentify",

View file

@ -8,7 +8,7 @@ local -a alts args
'*+'{no,}'ignore[ignore truncation in UDP responses]'
'*+'{no,}'tls[use DNS-over-TLS for queries]'
'*+'{no,}'dnscrypt[use DNSCrypt for queries]'
'*+'{no,}'https[use DNS-over-HTTPS for queries]'
'*+'{no,}'https=[use DNS-over-HTTPS for queries]:endpoint [/dns-query]'
'*+'{no,}'quic[use DNS-over-QUIC for queries]'
'*+'{no,}'aaonly[set aa flag in the query]'
'*+'{no,}'additional[print additional section of a reply]'
@ -50,7 +50,7 @@ local -a alts args
# '*+'{no,}'rrcomments[set display of per-record comments]'
# '*+ndots=[specify number of dots to be considered absolute]:dots'
'*+bufsize=[specify UDP buffer size]:size (bytes)'
'*+'{no,}'dnssec[enable DNSSEC]'
'*+'{no,}''{dnssec,do}'[enable DNSSEC]'
'*+'{no,}'nsid[include EDNS name server ID request in query]'
'*+'{no,}'class[display the class whening printing the answer]'
'*+'{no,}'ttlid[display the TTL whening printing the record]'

View file

@ -25,13 +25,14 @@ some more recent RFCs and output options.
When no arguments are given, *awl* will perform an _NS_ query on the root ('_._').
When a nameserver is not given, *awl* will query a random system nameserver.
If one cannot be found, *awl* will query localhost.
If one cannot be found, *awl* will query the localhost.
# OPTIONS
Anything in [brackets] is optional.
Many options are inherited from *dig*(1).
*-D*, *--dnssec*, *+dnssec*
*-D*, *--dnssec*, *+dnssec*, *+do*
Enable DNSSEC. This needs to be manually enabled.
*-v*[=_int_]
@ -83,13 +84,13 @@ Anything in [brackets] is optional.
*--no-bad-cookie*, *+[no]badcookie*
\[Do not\] ignore BADCOOKIE responses
*--tcp*, *+tcp*, *+vc*
*--tcp*, *+[no]tcp*, *+[no]vc*
Use TCP for the query (see RFC 7766).
*--dnscrypt*, *+dnscrypt*
*--dnscrypt*, *+[no]dnscrypt*
Use DNSCrypt.
*-T*, *--tls*, *+tls*
*-T*, *--tls*, *+[no]tls*
Use DNS-over-TLS, implies *--tcp* (see RFC 7858)
*--tls-host* _string_
@ -99,10 +100,10 @@ Anything in [brackets] is optional.
*--tls-no-verify*
Ignore TLS validation when performing a DNS query.
*-H*. *--https*, *+https*
*-H*. *--https*, *+[no]https*
Use DNS-over-HTTPS (see RFC 8484).
*-Q*. *--quic*, *+quic*
*-Q*. *--quic*, *+[no]quic*
Use DNS-over-QUIC (see RFC 9250).
*-x*, *--reverse*
@ -204,16 +205,16 @@ All of these options except disabling EDNS imply *+edns*.
## Output Formats
*-j*, *--json*, *+json*
*-j*, *--json*, *+[no]json*
Print the query results as JSON.
*-X*, *--xml*, *+xml*
*-X*, *--xml*, *+[no]xml*
Print the query results as XML.
*-y*, *--yaml*, *+yaml*
*-y*, *--yaml*, *+[no]yaml*
Print the query results as YAML.
*-s*, *--short*, *+short*
*-s*, *--short*, *+[no]short*
Print just the address of the answer.
# EXIT STATUS
@ -254,8 +255,6 @@ Probably more, _https://www.statdns.com/rfc_
# BUGS
OPT records are only printed when using a standard output, not JSON/XML/YAML.
Full parity with *dig*(1) is not complete.
This man page is probably not complete.

View file

@ -48,7 +48,14 @@ func (resolver *HTTPSResolver) LookUp(msg *dns.Msg) (util.Response, error) {
resolver.opts.Logger.Debug("https: sending HTTPS request")
req, err := http.NewRequest("POST", resolver.opts.Request.Server, bytes.NewBuffer(buf))
var method string
if resolver.opts.HTTPSOptions.Get {
method = "GET"
} else {
method = "POST"
}
req, err := http.NewRequest(method, resolver.opts.Request.Server, bytes.NewBuffer(buf))
if err != nil {
return util.Response{}, fmt.Errorf("doh: request creation: %w", err)
}

View file

@ -31,6 +31,8 @@ func LoadResolver(opts *util.Options) (Resolver, error) {
opts.Request.Server = "https://" + opts.Request.Server
}
opts.Request.Server += opts.HTTPSOptions.Endpoint
return &HTTPSResolver{
opts: opts,
}, nil

View file

@ -18,8 +18,12 @@ type Options struct {
TLSHost string `json:"tlsHost" example:""`
// EDNS Options
EDNS
// HTTPS options :)
HTTPSOptions
// DNS request :)
Request Request
Request
// Verbosity levels, see [logawl.AllLevels]
Verbosity int `json:"-" example:"0"`
@ -65,6 +69,16 @@ type Options struct {
IPv6 bool `json:"forceIPv6" example:"false"`
}
// HTTPSOptions are options exclusively for DNS-over-HTTPS queries.
type HTTPSOptions struct {
// URL endpoint
Endpoint string `json:"endpoint" example:"/dns-query"`
// True, make GET request.
// False, make POST request.
Get bool `json:"get" example:"false"`
}
// HeaderFlags are the flags that are in DNS headers.
type HeaderFlags struct {
// Authoritative Answer DNS query flag