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
This commit is contained in:
Alex Chauvin
2020-11-24 13:35:23 +01:00
committed by GitHub
parent 2aa7370aaf
commit 967faec56c
8 changed files with 64 additions and 20 deletions

View File

@@ -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) {

View File

@@ -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

View File

@@ -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"
)

View File

@@ -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

View File

@@ -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
}