feat: DNS over TLS resolver

This commit is contained in:
Toby 2023-08-04 14:03:23 -07:00
parent 7c94b072ed
commit 6ad44d183e
5 changed files with 54 additions and 4 deletions

View File

@ -101,10 +101,18 @@ type serverConfigResolverUDP struct {
Timeout time.Duration `mapstructure:"timeout"`
}
type serverConfigResolverTLS struct {
Addr string `mapstructure:"addr"`
Timeout time.Duration `mapstructure:"timeout"`
SNI string `mapstructure:"sni"`
Insecure bool `mapstructure:"insecure"`
}
type serverConfigResolver struct {
Type string `mapstructure:"type"`
TCP serverConfigResolverTCP `mapstructure:"tcp"`
UDP serverConfigResolverUDP `mapstructure:"udp"`
TLS serverConfigResolverTLS `mapstructure:"tls"`
}
type serverConfigMasqueradeFile struct {
@ -254,6 +262,11 @@ func (c *serverConfig) fillOutboundConfig(hyConfig *server.Config) error {
return configError{Field: "resolver.udp.addr", Err: errors.New("empty resolver address")}
}
ob = outbounds.NewStandardResolverUDP(c.Resolver.UDP.Addr, c.Resolver.UDP.Timeout, ob)
case "tls", "tcp-tls":
if c.Resolver.TLS.Addr == "" {
return configError{Field: "resolver.tls.addr", Err: errors.New("empty resolver address")}
}
ob = outbounds.NewStandardResolverTLS(c.Resolver.TLS.Addr, c.Resolver.TLS.Timeout, c.Resolver.TLS.SNI, c.Resolver.TLS.Insecure, ob)
default:
return configError{Field: "resolver.type", Err: errors.New("unsupported resolver type")}
}

View File

@ -71,6 +71,12 @@ func TestServerConfig(t *testing.T) {
Addr: "4.6.8.0:53",
Timeout: 2 * time.Second,
},
TLS: serverConfigResolverTLS{
Addr: "dot.yolo.com:8853",
Timeout: 10 * time.Second,
SNI: "server1.yolo.net",
Insecure: true,
},
},
Masquerade: serverConfigMasquerade{
Type: "proxy",

View File

@ -49,6 +49,11 @@ resolver:
udp:
addr: 4.6.8.0:53
timeout: 2s
tls:
addr: dot.yolo.com:8853
timeout: 10s
sni: server1.yolo.net
insecure: true
masquerade:
type: proxy

View File

@ -41,10 +41,12 @@ auth:
password: some_password
# resolver:
# type: udp
# udp:
# addr: 8.8.4.4
# timeout: 2s
# type: tls
# tls:
# addr: dot.yolo.com:8853
# timeout: 10s
# sni: server1.yolo.net
# insecure: true
masquerade:
type: proxy

View File

@ -1,6 +1,7 @@
package outbounds
import (
"crypto/tls"
"net"
"time"
@ -42,6 +43,21 @@ func NewStandardResolverTCP(addr string, timeout time.Duration, next PluggableOu
}
}
func NewStandardResolverTLS(addr string, timeout time.Duration, sni string, insecure bool, next PluggableOutbound) PluggableOutbound {
return &standardResolver{
Addr: addDefaultPortTLS(addr),
Client: &dns.Client{
Net: "tcp-tls",
Timeout: timeoutOrDefault(timeout),
TLSConfig: &tls.Config{
ServerName: sni,
InsecureSkipVerify: insecure,
},
},
Next: next,
}
}
// addDefaultPort adds the default DNS port (53) to the address if not present.
func addDefaultPort(addr string) string {
if _, _, err := net.SplitHostPort(addr); err != nil {
@ -50,6 +66,14 @@ func addDefaultPort(addr string) string {
return addr
}
// addDefaultPortTLS adds the default DNS-over-TLS port (853) to the address if not present.
func addDefaultPortTLS(addr string) string {
if _, _, err := net.SplitHostPort(addr); err != nil {
return net.JoinHostPort(addr, "853")
}
return addr
}
func timeoutOrDefault(timeout time.Duration) time.Duration {
if timeout == 0 {
return standardResolverDefaultTimeout