Skip to content

Commit

Permalink
Support SOCKS5 for DoT
Browse files Browse the repository at this point in the history
  • Loading branch information
folbricht committed Jun 25, 2023
1 parent 283bb71 commit f824287
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 14 deletions.
13 changes: 13 additions & 0 deletions cmd/routedns/example-config/socks5-dot.toml
Original file line number Diff line number Diff line change
@@ -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"
4 changes: 3 additions & 1 deletion cmd/routedns/example-config/socks5-udp.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Simple DNS queries routed through a SOCKS5 proxy.

[resolvers.cloudflare-udp]
address = "1.1.1.1:53"
protocol = "udp"
Expand All @@ -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"
17 changes: 11 additions & 6 deletions cmd/routedns/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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
}
13 changes: 6 additions & 7 deletions dotclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ type DoTClientOptions struct {
TLSConfig *tls.Config

QueryTimeout time.Duration

// Optional dialer, e.g. proxy
Dialer Dialer
}

var _ Resolver = &DoTClient{}
Expand All @@ -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
Expand Down

0 comments on commit f824287

Please sign in to comment.