feat: add tls config for dot lookups
Ref https://github.com/mr-karan/doggo/issues/29pull/41/head v0.5.2
parent
0ce04d0c13
commit
53f7b70af4
14
README.md
14
README.md
|
@ -210,12 +210,14 @@ URL scheme of the server is used to identify which resolver to use for lookups.
|
||||||
### Resolver Options
|
### Resolver Options
|
||||||
|
|
||||||
```
|
```
|
||||||
--strategy=STRATEGY Specify strategy to query nameserver listed in etc/resolv.conf. Defaults to `all` (`random`, `first`, `all`).
|
--strategy=STRATEGY Specify strategy to query nameserver listed in etc/resolv.conf. Defaults to `all` (`random`, `first`, `all`).
|
||||||
--ndots=INT Specify ndots parameter. Takes value from /etc/resolv.conf if using the system nameserver or 1 otherwise.
|
--ndots=INT Specify ndots parameter. Takes value from /etc/resolv.conf if using the system nameserver or 1 otherwise.
|
||||||
--search Use the search list defined in resolv.conf. Defaults to true. Set --search=false to disable search list.
|
--search Use the search list defined in resolv.conf. Defaults to true. Set --search=false to disable search list.
|
||||||
--timeout Specify timeout (in seconds) for the resolver to return a response.
|
--timeout Specify timeout (in seconds) for the resolver to return a response.
|
||||||
-4 --ipv4 Use IPv4 only.
|
-4 --ipv4 Use IPv4 only.
|
||||||
-6 --ipv6 Use IPv6 only.
|
-6 --ipv6 Use IPv6 only.
|
||||||
|
--tls-hostname=HOSTNAME Provide a hostname for doing verification of the certificate if the provided DoT nameserver is an IP.
|
||||||
|
--skip-hostname-verification Skip TLS Hostname Verification in case of DOT Lookups.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,8 @@ func main() {
|
||||||
f.BoolP("ipv4", "4", false, "Use IPv4 only")
|
f.BoolP("ipv4", "4", false, "Use IPv4 only")
|
||||||
f.BoolP("ipv6", "6", false, "Use IPv6 only")
|
f.BoolP("ipv6", "6", false, "Use IPv6 only")
|
||||||
f.String("strategy", "all", "Strategy to query nameservers in resolv.conf file (`all`, `random`, `first`)")
|
f.String("strategy", "all", "Strategy to query nameservers in resolv.conf file (`all`, `random`, `first`)")
|
||||||
|
f.String("tls-hostname", "", "Provide a hostname for doing verification of the certificate if the provided DoT nameserver is an IP")
|
||||||
|
f.Bool("skip-hostname-verification", false, "Skip TLS Hostname Verification")
|
||||||
|
|
||||||
// Output Options
|
// Output Options
|
||||||
f.BoolP("json", "J", false, "Set the output format as JSON")
|
f.BoolP("json", "J", false, "Set the output format as JSON")
|
||||||
|
@ -121,14 +123,16 @@ func main() {
|
||||||
|
|
||||||
// Load Resolvers.
|
// Load Resolvers.
|
||||||
rslvrs, err := resolvers.LoadResolvers(resolvers.Options{
|
rslvrs, err := resolvers.LoadResolvers(resolvers.Options{
|
||||||
Nameservers: app.Nameservers,
|
Nameservers: app.Nameservers,
|
||||||
UseIPv4: app.QueryFlags.UseIPv4,
|
UseIPv4: app.QueryFlags.UseIPv4,
|
||||||
UseIPv6: app.QueryFlags.UseIPv6,
|
UseIPv6: app.QueryFlags.UseIPv6,
|
||||||
SearchList: app.ResolverOpts.SearchList,
|
SearchList: app.ResolverOpts.SearchList,
|
||||||
Ndots: app.ResolverOpts.Ndots,
|
Ndots: app.ResolverOpts.Ndots,
|
||||||
Timeout: app.QueryFlags.Timeout * time.Second,
|
Timeout: app.QueryFlags.Timeout * time.Second,
|
||||||
Logger: app.Logger,
|
Logger: app.Logger,
|
||||||
Strategy: app.QueryFlags.Strategy,
|
Strategy: app.QueryFlags.Strategy,
|
||||||
|
InsecureSkipVerify: app.QueryFlags.InsecureSkipVerify,
|
||||||
|
TLSHostname: app.QueryFlags.TLSHostname,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.Logger.WithError(err).Error("error loading resolver")
|
app.Logger.WithError(err).Error("error loading resolver")
|
||||||
|
|
|
@ -47,12 +47,15 @@ var appHelpTextTemplate = `{{ "NAME" | color "" "heading" }}:
|
||||||
{{"-x, --reverse" | color "yellow" ""}} Performs a DNS Lookup for an IPv4 or IPv6 address. Sets the query type and class to PTR and IN respectively.
|
{{"-x, --reverse" | color "yellow" ""}} Performs a DNS Lookup for an IPv4 or IPv6 address. Sets the query type and class to PTR and IN respectively.
|
||||||
|
|
||||||
{{ "Resolver Options" | color "" "heading" }}:
|
{{ "Resolver Options" | color "" "heading" }}:
|
||||||
{{"--strategy=STRATEGY" | color "yellow" ""}} Specify strategy to query nameserver listed in etc/resolv.conf. ({{"all, random, first" | color "cyan" ""}}).
|
{{"--strategy=STRATEGY" | color "yellow" ""}} Specify strategy to query nameserver listed in etc/resolv.conf. ({{"all, random, first" | color "cyan" ""}}).
|
||||||
{{"--ndots=INT" | color "yellow" ""}} Specify ndots parameter. Takes value from /etc/resolv.conf if using the system namesever or 1 otherwise.
|
{{"--ndots=INT" | color "yellow" ""}} Specify ndots parameter. Takes value from /etc/resolv.conf if using the system namesever or 1 otherwise.
|
||||||
{{"--search" | color "yellow" ""}} Use the search list defined in resolv.conf. Defaults to true. Set --search=false to disable search list.
|
{{"--search" | color "yellow" ""}} Use the search list defined in resolv.conf. Defaults to true. Set --search=false to disable search list.
|
||||||
{{"--timeout" | color "yellow" ""}} Specify timeout (in seconds) for the resolver to return a response.
|
{{"--timeout" | color "yellow" ""}} Specify timeout (in seconds) for the resolver to return a response.
|
||||||
{{"-4 --ipv4" | color "yellow" ""}} Use IPv4 only.
|
{{"-4 --ipv4" | color "yellow" ""}} Use IPv4 only.
|
||||||
{{"-6 --ipv6" | color "yellow" ""}} Use IPv6 only.
|
{{"-6 --ipv6" | color "yellow" ""}} Use IPv6 only.
|
||||||
|
{{"--ndots=INT" | color "yellow" ""}} Specify ndots parameter. Takes value from /etc/resolv.conf if using the system namesever or 1 otherwise.
|
||||||
|
{{"--tls-hostname=HOSTNAME" | color "yellow" ""}} Provide a hostname for doing verification of the certificate if the provided DoT nameserver is an IP.
|
||||||
|
{{"--skip-hostname-verification" | color "yellow" ""}} Skip TLS Hostname Verification in case of DOT Lookups.
|
||||||
|
|
||||||
{{ "Output Options" | color "" "heading" }}:
|
{{ "Output Options" | color "" "heading" }}:
|
||||||
{{"-J, --json " | color "yellow" ""}} Format the output as JSON.
|
{{"-J, --json " | color "yellow" ""}} Format the output as JSON.
|
||||||
|
|
|
@ -22,21 +22,23 @@ const (
|
||||||
// QueryFlags is used store the query params
|
// QueryFlags is used store the query params
|
||||||
// supplied by the user.
|
// supplied by the user.
|
||||||
type QueryFlags struct {
|
type QueryFlags struct {
|
||||||
QNames []string `koanf:"query" json:"query"`
|
QNames []string `koanf:"query" json:"query"`
|
||||||
QTypes []string `koanf:"type" json:"type"`
|
QTypes []string `koanf:"type" json:"type"`
|
||||||
QClasses []string `koanf:"class" json:"class"`
|
QClasses []string `koanf:"class" json:"class"`
|
||||||
Nameservers []string `koanf:"nameservers" json:"nameservers"`
|
Nameservers []string `koanf:"nameservers" json:"nameservers"`
|
||||||
UseIPv4 bool `koanf:"ipv4" json:"ipv4"`
|
UseIPv4 bool `koanf:"ipv4" json:"ipv4"`
|
||||||
UseIPv6 bool `koanf:"ipv6" json:"ipv6"`
|
UseIPv6 bool `koanf:"ipv6" json:"ipv6"`
|
||||||
Ndots int `koanf:"ndots" json:"ndots"`
|
Ndots int `koanf:"ndots" json:"ndots"`
|
||||||
Timeout time.Duration `koanf:"timeout" json:"timeout"`
|
Timeout time.Duration `koanf:"timeout" json:"timeout"`
|
||||||
Color bool `koanf:"color" json:"-"`
|
Color bool `koanf:"color" json:"-"`
|
||||||
DisplayTimeTaken bool `koanf:"time" json:"-"`
|
DisplayTimeTaken bool `koanf:"time" json:"-"`
|
||||||
ShowJSON bool `koanf:"json" json:"-"`
|
ShowJSON bool `koanf:"json" json:"-"`
|
||||||
ShortOutput bool `koanf:"short" short:"-"`
|
ShortOutput bool `koanf:"short" short:"-"`
|
||||||
UseSearchList bool `koanf:"search" json:"-"`
|
UseSearchList bool `koanf:"search" json:"-"`
|
||||||
ReverseLookup bool `koanf:"reverse" reverse:"-"`
|
ReverseLookup bool `koanf:"reverse" reverse:"-"`
|
||||||
Strategy string `koanf:"strategy" strategy:"-"`
|
Strategy string `koanf:"strategy" strategy:"-"`
|
||||||
|
InsecureSkipVerify bool `koanf:"skip-hostname-verification" skip-hostname-verification:"-"`
|
||||||
|
TLSHostname string `koanf:"tls-hostname" tls-hostname:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nameserver represents the type of Nameserver
|
// Nameserver represents the type of Nameserver
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package resolvers
|
package resolvers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
|
@ -16,10 +17,8 @@ type ClassicResolver struct {
|
||||||
|
|
||||||
// ClassicResolverOpts holds options for setting up a Classic resolver.
|
// ClassicResolverOpts holds options for setting up a Classic resolver.
|
||||||
type ClassicResolverOpts struct {
|
type ClassicResolverOpts struct {
|
||||||
IPv4Only bool
|
UseTLS bool
|
||||||
IPv6Only bool
|
UseTCP bool
|
||||||
UseTLS bool
|
|
||||||
UseTCP bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClassicResolver accepts a list of nameservers and configures a DNS resolver.
|
// NewClassicResolver accepts a list of nameservers and configures a DNS resolver.
|
||||||
|
@ -34,15 +33,20 @@ func NewClassicResolver(server string, classicOpts ClassicResolverOpts, resolver
|
||||||
net = "tcp"
|
net = "tcp"
|
||||||
}
|
}
|
||||||
|
|
||||||
if classicOpts.IPv4Only {
|
if resolverOpts.UseIPv4 {
|
||||||
net = net + "4"
|
net = net + "4"
|
||||||
}
|
}
|
||||||
if classicOpts.IPv6Only {
|
if resolverOpts.UseIPv6 {
|
||||||
net = net + "6"
|
net = net + "6"
|
||||||
}
|
}
|
||||||
|
|
||||||
if classicOpts.UseTLS {
|
if classicOpts.UseTLS {
|
||||||
net = net + "-tls"
|
net = net + "-tls"
|
||||||
|
// Provide extra TLS config for doing/skipping hostname verification.
|
||||||
|
client.TLSConfig = &tls.Config{
|
||||||
|
ServerName: resolverOpts.TLSHostname,
|
||||||
|
InsecureSkipVerify: resolverOpts.InsecureSkipVerify,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Net = net
|
client.Net = net
|
||||||
|
|
|
@ -18,10 +18,7 @@ type DNSCryptResolver struct {
|
||||||
|
|
||||||
// DNSCryptResolverOpts holds options for setting up a DNSCrypt resolver.
|
// DNSCryptResolverOpts holds options for setting up a DNSCrypt resolver.
|
||||||
type DNSCryptResolverOpts struct {
|
type DNSCryptResolverOpts struct {
|
||||||
IPv4Only bool
|
UseTCP bool
|
||||||
IPv6Only bool
|
|
||||||
UseTLS bool
|
|
||||||
UseTCP bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSCryptResolver accepts a list of nameservers and configures a DNS resolver.
|
// NewDNSCryptResolver accepts a list of nameservers and configures a DNS resolver.
|
||||||
|
@ -30,6 +27,7 @@ func NewDNSCryptResolver(server string, dnscryptOpts DNSCryptResolverOpts, resol
|
||||||
if dnscryptOpts.UseTCP {
|
if dnscryptOpts.UseTCP {
|
||||||
net = "tcp"
|
net = "tcp"
|
||||||
}
|
}
|
||||||
|
|
||||||
client := &dnscrypt.Client{Net: net, Timeout: resolverOpts.Timeout, UDPSize: 4096}
|
client := &dnscrypt.Client{Net: net, Timeout: resolverOpts.Timeout, UDPSize: 4096}
|
||||||
resolverInfo, err := client.Dial(server)
|
resolverInfo, err := client.Dial(server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -11,14 +11,17 @@ import (
|
||||||
// Options represent a set of common options
|
// Options represent a set of common options
|
||||||
// to configure a Resolver.
|
// to configure a Resolver.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Nameservers []models.Nameserver
|
Logger *logrus.Logger
|
||||||
UseIPv4 bool
|
|
||||||
UseIPv6 bool
|
Nameservers []models.Nameserver
|
||||||
SearchList []string
|
UseIPv4 bool
|
||||||
Ndots int
|
UseIPv6 bool
|
||||||
Timeout time.Duration
|
SearchList []string
|
||||||
Logger *logrus.Logger
|
Ndots int
|
||||||
Strategy string
|
Timeout time.Duration
|
||||||
|
Strategy string
|
||||||
|
InsecureSkipVerify bool
|
||||||
|
TLSHostname string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolver implements the configuration for a DNS
|
// Resolver implements the configuration for a DNS
|
||||||
|
@ -68,18 +71,13 @@ type Authority struct {
|
||||||
// LoadResolvers loads differently configured
|
// LoadResolvers loads differently configured
|
||||||
// resolvers based on a list of nameserver.
|
// resolvers based on a list of nameserver.
|
||||||
func LoadResolvers(opts Options) ([]Resolver, error) {
|
func LoadResolvers(opts Options) ([]Resolver, error) {
|
||||||
var resolverOpts = Options{
|
// For each nameserver, initialise the correct resolver.
|
||||||
Timeout: opts.Timeout,
|
|
||||||
Ndots: opts.Ndots,
|
|
||||||
SearchList: opts.SearchList,
|
|
||||||
Logger: opts.Logger,
|
|
||||||
}
|
|
||||||
// for each nameserver, initialise the correct resolver
|
|
||||||
rslvrs := make([]Resolver, 0, len(opts.Nameservers))
|
rslvrs := make([]Resolver, 0, len(opts.Nameservers))
|
||||||
|
|
||||||
for _, ns := range opts.Nameservers {
|
for _, ns := range opts.Nameservers {
|
||||||
if ns.Type == models.DOHResolver {
|
if ns.Type == models.DOHResolver {
|
||||||
opts.Logger.Debug("initiating DOH resolver")
|
opts.Logger.Debug("initiating DOH resolver")
|
||||||
rslvr, err := NewDOHResolver(ns.Address, resolverOpts)
|
rslvr, err := NewDOHResolver(ns.Address, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rslvrs, err
|
return rslvrs, err
|
||||||
}
|
}
|
||||||
|
@ -89,11 +87,9 @@ func LoadResolvers(opts Options) ([]Resolver, error) {
|
||||||
opts.Logger.Debug("initiating DOT resolver")
|
opts.Logger.Debug("initiating DOT resolver")
|
||||||
rslvr, err := NewClassicResolver(ns.Address,
|
rslvr, err := NewClassicResolver(ns.Address,
|
||||||
ClassicResolverOpts{
|
ClassicResolverOpts{
|
||||||
IPv4Only: opts.UseIPv4,
|
UseTLS: true,
|
||||||
IPv6Only: opts.UseIPv6,
|
UseTCP: true,
|
||||||
UseTLS: true,
|
}, opts)
|
||||||
UseTCP: true,
|
|
||||||
}, resolverOpts)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rslvrs, err
|
return rslvrs, err
|
||||||
|
@ -104,11 +100,9 @@ func LoadResolvers(opts Options) ([]Resolver, error) {
|
||||||
opts.Logger.Debug("initiating TCP resolver")
|
opts.Logger.Debug("initiating TCP resolver")
|
||||||
rslvr, err := NewClassicResolver(ns.Address,
|
rslvr, err := NewClassicResolver(ns.Address,
|
||||||
ClassicResolverOpts{
|
ClassicResolverOpts{
|
||||||
IPv4Only: opts.UseIPv4,
|
UseTLS: false,
|
||||||
IPv6Only: opts.UseIPv6,
|
UseTCP: true,
|
||||||
UseTLS: false,
|
}, opts)
|
||||||
UseTCP: true,
|
|
||||||
}, resolverOpts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rslvrs, err
|
return rslvrs, err
|
||||||
}
|
}
|
||||||
|
@ -118,11 +112,9 @@ func LoadResolvers(opts Options) ([]Resolver, error) {
|
||||||
opts.Logger.Debug("initiating UDP resolver")
|
opts.Logger.Debug("initiating UDP resolver")
|
||||||
rslvr, err := NewClassicResolver(ns.Address,
|
rslvr, err := NewClassicResolver(ns.Address,
|
||||||
ClassicResolverOpts{
|
ClassicResolverOpts{
|
||||||
IPv4Only: opts.UseIPv4,
|
UseTLS: false,
|
||||||
IPv6Only: opts.UseIPv6,
|
UseTCP: false,
|
||||||
UseTLS: false,
|
}, opts)
|
||||||
UseTCP: false,
|
|
||||||
}, resolverOpts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rslvrs, err
|
return rslvrs, err
|
||||||
}
|
}
|
||||||
|
@ -133,7 +125,7 @@ func LoadResolvers(opts Options) ([]Resolver, error) {
|
||||||
rslvr, err := NewDNSCryptResolver(ns.Address,
|
rslvr, err := NewDNSCryptResolver(ns.Address,
|
||||||
DNSCryptResolverOpts{
|
DNSCryptResolverOpts{
|
||||||
UseTCP: false,
|
UseTCP: false,
|
||||||
}, resolverOpts)
|
}, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rslvrs, err
|
return rslvrs, err
|
||||||
}
|
}
|
||||||
|
@ -141,7 +133,7 @@ func LoadResolvers(opts Options) ([]Resolver, error) {
|
||||||
}
|
}
|
||||||
if ns.Type == models.DOQResolver {
|
if ns.Type == models.DOQResolver {
|
||||||
opts.Logger.Debug("initiating DOQ resolver")
|
opts.Logger.Debug("initiating DOQ resolver")
|
||||||
rslvr, err := NewDOQResolver(ns.Address, resolverOpts)
|
rslvr, err := NewDOQResolver(ns.Address, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rslvrs, err
|
return rslvrs, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue