From 967faec56c4b893d33944c0b667cce5d2f5a00de Mon Sep 17 00:00:00 2001 From: Alex Chauvin Date: Tue, 24 Nov 2020 13:35:23 +0100 Subject: [PATCH] add options for ECS full subnet mask in server & TLS verification bypass in client (#92) * add ECS full size & limit filtering * add tls certification bypass in configuration * flush log lines * changes following pull request comments * with fmt and reorg of libs in client.go --- doh-client/client.go | 15 ++++++++------- doh-client/config/config.go | 19 ++++++++++--------- doh-client/doh-client.conf | 6 ++++++ doh-server/config.go | 2 ++ doh-server/doh-server.conf | 18 ++++++++++++++++++ doh-server/google.go | 2 +- doh-server/ietf.go | 15 +++++++++++++-- doh-server/server.go | 7 ++++++- 8 files changed, 64 insertions(+), 20 deletions(-) diff --git a/doh-client/client.go b/doh-client/client.go index fdc8da1..91e5c9e 100644 --- a/doh-client/client.go +++ b/doh-client/client.go @@ -25,7 +25,14 @@ package main import ( "context" + "crypto/tls" "fmt" + "github.com/m13253/dns-over-https/doh-client/config" + "github.com/m13253/dns-over-https/doh-client/selector" + jsondns "github.com/m13253/dns-over-https/json-dns" + "github.com/miekg/dns" + "golang.org/x/net/http2" + "golang.org/x/net/idna" "log" "math/rand" "net" @@ -36,13 +43,6 @@ import ( "strings" "sync" "time" - - "github.com/m13253/dns-over-https/doh-client/config" - "github.com/m13253/dns-over-https/doh-client/selector" - jsondns "github.com/m13253/dns-over-https/json-dns" - "github.com/miekg/dns" - "golang.org/x/net/http2" - "golang.org/x/net/idna" ) type Client struct { @@ -247,6 +247,7 @@ func (c *Client) newHTTPClient() error { MaxIdleConnsPerHost: 10, Proxy: http.ProxyFromEnvironment, TLSHandshakeTimeout: time.Duration(c.conf.Other.Timeout) * time.Second, + TLSClientConfig: &tls.Config{InsecureSkipVerify: c.conf.Other.TLSInsecureSkipVerify}, } if c.conf.Other.NoIPv6 { c.httpTransport.DialContext = func(ctx context.Context, network, address string) (net.Conn, error) { diff --git a/doh-client/config/config.go b/doh-client/config/config.go index 01dbe31..e57e22b 100644 --- a/doh-client/config/config.go +++ b/doh-client/config/config.go @@ -47,15 +47,16 @@ type upstream struct { } type others struct { - Bootstrap []string `toml:"bootstrap"` - Passthrough []string `toml:"passthrough"` - Timeout uint `toml:"timeout"` - NoCookies bool `toml:"no_cookies"` - NoECS bool `toml:"no_ecs"` - NoIPv6 bool `toml:"no_ipv6"` - NoUserAgent bool `toml:"no_user_agent"` - Verbose bool `toml:"verbose"` - DebugHTTPHeaders []string `toml:"debug_http_headers"` + Bootstrap []string `toml:"bootstrap"` + Passthrough []string `toml:"passthrough"` + Timeout uint `toml:"timeout"` + NoCookies bool `toml:"no_cookies"` + NoECS bool `toml:"no_ecs"` + NoIPv6 bool `toml:"no_ipv6"` + NoUserAgent bool `toml:"no_user_agent"` + Verbose bool `toml:"verbose"` + DebugHTTPHeaders []string `toml:"debug_http_headers"` + TLSInsecureSkipVerify bool `toml:"insecure_tls_skip_verify"` } type Config struct { diff --git a/doh-client/doh-client.conf b/doh-client/doh-client.conf index c5bd0c9..db2cc88 100644 --- a/doh-client/doh-client.conf +++ b/doh-client/doh-client.conf @@ -132,3 +132,9 @@ no_user_agent = false # Enable logging verbose = false + +# insecure_tls_skip_verification will disable necessary TLS security verification. +# This option is designed for testing or development purposes, +# turning on this option on public Internet may cause your connection +# vulnerable to MITM attack. +insecure_tls_skip_verify = false diff --git a/doh-server/config.go b/doh-server/config.go index edb9f64..796f300 100644 --- a/doh-server/config.go +++ b/doh-server/config.go @@ -42,6 +42,8 @@ type config struct { Verbose bool `toml:"verbose"` DebugHTTPHeaders []string `toml:"debug_http_headers"` LogGuessedIP bool `toml:"log_guessed_client_ip"` + LocalIPFilter bool `toml:"ecs_allow_non_global_ip"` + ECSFullSubnet bool `toml:"ecs_use_precise_ip"` } func loadConfig(path string) (*config, error) { diff --git a/doh-server/doh-server.conf b/doh-server/doh-server.conf index 72e06ad..c6c7955 100644 --- a/doh-server/doh-server.conf +++ b/doh-server/doh-server.conf @@ -51,3 +51,21 @@ verbose = false # Enable log IP from HTTPS-reverse proxy header: X-Forwarded-For or X-Real-IP # Note: http uri/useragent log cannot be controlled by this config log_guessed_client_ip = false + +# By default, non global IP addresses are never forwarded to upstream servers. +# This is to prevent two things from happening: +# 1. the upstream server knowing your private LAN addresses; +# 2. the upstream server unable to provide geographically near results, +# or even fail to provide any result. +# However, if you are deploying a split tunnel corporation network environment, +# or for any other reason you want to inhibit this behavior, change the following +# option to "true". +ecs_allow_non_global_ip = false + +# If ECS is added to the request, let the full IP address or +# cap it to 24 or 128 mask. This option is to be used only on private +# networks where knwoledge of the terminal endpoint may be required for +# security purposes (eg. DNS Firewalling). Not a good option on the +# internet where IP address may be used to identify the user and +# not only the approximate location. +ecs_use_precise_ip = false diff --git a/doh-server/google.go b/doh-server/google.go index 71ab0aa..4231c72 100644 --- a/doh-server/google.go +++ b/doh-server/google.go @@ -34,7 +34,7 @@ import ( "strings" "time" - "github.com/m13253/dns-over-https/json-dns" + jsondns "github.com/m13253/dns-over-https/json-dns" "github.com/miekg/dns" "golang.org/x/net/idna" ) diff --git a/doh-server/ietf.go b/doh-server/ietf.go index 239d9f3..497ff27 100644 --- a/doh-server/ietf.go +++ b/doh-server/ietf.go @@ -125,6 +125,7 @@ func (s *Server) parseRequestIETF(ctx context.Context, w http.ResponseWriter, r } } isTailored := edns0Subnet == nil + if edns0Subnet == nil { ednsClientFamily := uint16(0) ednsClientAddress := s.findClientIP(r) @@ -133,10 +134,20 @@ func (s *Server) parseRequestIETF(ctx context.Context, w http.ResponseWriter, r if ipv4 := ednsClientAddress.To4(); ipv4 != nil { ednsClientFamily = 1 ednsClientAddress = ipv4 - ednsClientNetmask = 24 + if s.conf.ECSFullSubnet { + ednsClientNetmask = 32 + } else { + ednsClientNetmask = 24 + ednsClientAddress = ednsClientAddress.Mask(net.CIDRMask(24, 32)) + } } else { ednsClientFamily = 2 - ednsClientNetmask = 56 + if s.conf.ECSFullSubnet { + ednsClientNetmask = 128 + } else { + ednsClientNetmask = 56 + ednsClientAddress = ednsClientAddress.Mask(net.CIDRMask(56, 128)) + } } edns0Subnet = new(dns.EDNS0_SUBNET) edns0Subnet.Code = dns.EDNS0SUBNET diff --git a/doh-server/server.go b/doh-server/server.go index e263954..ecf01b9 100644 --- a/doh-server/server.go +++ b/doh-server/server.go @@ -265,17 +265,22 @@ func (s *Server) findClientIP(r *http.Request) net.IP { if XRealIP != "" { addr := strings.TrimSpace(XRealIP) ip := net.ParseIP(addr) - if jsondns.IsGlobalIP(ip) { + if !s.conf.LocalIPFilter || jsondns.IsGlobalIP(ip) { return ip } } + remoteAddr, err := net.ResolveTCPAddr("tcp", r.RemoteAddr) if err != nil { return nil } + if !s.conf.LocalIPFilter { + return remoteAddr.IP + } if ip := remoteAddr.IP; jsondns.IsGlobalIP(ip) { return ip } + return nil }