diff --git a/cmd/routedns/example-config/socks5-dot.toml b/cmd/routedns/example-config/socks5-dot.toml new file mode 100644 index 00000000..17e75a4a --- /dev/null +++ b/cmd/routedns/example-config/socks5-dot.toml @@ -0,0 +1,13 @@ +# DoT coonfiguration that connects to the upstream server via SOCKS5 proxy. + +[resolvers.cloudflare-dot] +address = "1.1.1.1:853" +protocol = "dot" +socks5-address = "127.0.0.1:1080" +socks5-username = "test" +socks5-password = "test" + +[listeners.local-udp] +address = "127.0.0.1:53" +protocol = "udp" +resolver = "cloudflare-dot" diff --git a/cmd/routedns/example-config/socks5-udp.toml b/cmd/routedns/example-config/socks5-udp.toml index 749b17d0..5fb5c302 100644 --- a/cmd/routedns/example-config/socks5-udp.toml +++ b/cmd/routedns/example-config/socks5-udp.toml @@ -1,3 +1,5 @@ +# Simple DNS queries routed through a SOCKS5 proxy. + [resolvers.cloudflare-udp] address = "1.1.1.1:53" protocol = "udp" @@ -6,6 +8,6 @@ socks5-username = "test" socks5-password = "test" [listeners.local-udp] -address = "127.0.0.1:1153" +address = "127.0.0.1:53" protocol = "udp" resolver = "cloudflare-udp" diff --git a/cmd/routedns/resolver.go b/cmd/routedns/resolver.go index 8f1d4560..5ec00279 100644 --- a/cmd/routedns/resolver.go +++ b/cmd/routedns/resolver.go @@ -43,6 +43,7 @@ func instantiateResolver(id string, r resolver, resolvers map[string]rdns.Resolv LocalAddr: net.ParseIP(r.LocalAddr), TLSConfig: tlsConfig, QueryTimeout: time.Duration(r.QueryTimeout) * time.Second, + Dialer: socks5DialerFromConfig(r), } resolvers[id], err = rdns.NewDoTClient(id, r.Address, opt) if err != nil { @@ -92,12 +93,7 @@ func instantiateResolver(id string, r resolver, resolvers map[string]rdns.Resolv LocalAddr: net.ParseIP(r.LocalAddr), UDPSize: r.EDNS0UDPSize, QueryTimeout: time.Duration(r.QueryTimeout) * time.Second, - } - if r.Socks5Address != "" { - opt.Dialer, err = socks5.NewClient(r.Socks5Address, r.Socks5Username, r.Socks5Password, 0, 5) - if err != nil { - return err - } + Dialer: socks5DialerFromConfig(r), } resolvers[id], err = rdns.NewDNSClient(id, r.Address, r.Protocol, opt) if err != nil { @@ -108,3 +104,12 @@ func instantiateResolver(id string, r resolver, resolvers map[string]rdns.Resolv } return nil } + +// Returns a dialer if a socks5 proxy is configured, nil otherwise +func socks5DialerFromConfig(cfg resolver) *socks5.Client { + if cfg.Socks5Address == "" { + return nil + } + client, _ := socks5.NewClient(cfg.Socks5Address, cfg.Socks5Username, cfg.Socks5Password, 0, 5) + return client +} diff --git a/dotclient.go b/dotclient.go index 22df8814..02f5acc5 100644 --- a/dotclient.go +++ b/dotclient.go @@ -30,6 +30,9 @@ type DoTClientOptions struct { TLSConfig *tls.Config QueryTimeout time.Duration + + // Optional dialer, e.g. proxy + Dialer Dialer } var _ Resolver = &DoTClient{} @@ -40,15 +43,11 @@ func NewDoTClient(id, endpoint string, opt DoTClientOptions) (*DoTClient, error) return nil, err } - // Use a custom dialer if a local address was provided - var dialer *net.Dialer - if opt.LocalAddr != nil { - dialer = &net.Dialer{LocalAddr: &net.TCPAddr{IP: opt.LocalAddr}} - } - client := &dns.Client{ + client := GenericDNSClient{ Net: "tcp-tls", TLSConfig: opt.TLSConfig, - Dialer: dialer, + Dialer: opt.Dialer, + LocalAddr: opt.LocalAddr, } // If a bootstrap address was provided, we need to use the IP for the connection but the // hostname in the TLS handshake. The DNS library doesn't support custom dialers, so