Documentation ¶
Overview ¶
Package proxy implements a DNS proxy that supports all known DNS encryption protocols.
Index ¶
- Constants
- func CheckDisabledAAAARequest(ctx *DNSContext, ipv6Disabled bool) bool
- func GenEmptyMessage(request *dns.Msg, rCode int, retry uint32) *dns.Msg
- type BeforeRequestHandler
- type Config
- type DNSContext
- type Proto
- type Proxy
- func (p *Proxy) Addr(proto Proto) net.Addr
- func (p *Proxy) Addrs(proto Proto) []net.Addr
- func (p *Proxy) Init() (err error)
- func (p *Proxy) LookupIPAddr(host string) ([]net.IPAddr, error)
- func (p *Proxy) Resolve(d *DNSContext) (err error)
- func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (p *Proxy) SetNAT64Prefix(prefix []byte)
- func (p *Proxy) Start() (err error)
- func (p *Proxy) Stop() error
- type RequestHandler
- type ResponseHandler
- type UpstreamConfig
- type UpstreamModeType
Constants ¶
const NAT64PrefixLength = 12
NAT64PrefixLength is the length of a NAT64 prefix
const NextProtoDQ = "doq-i02"
NextProtoDQ is the ALPN token for DoQ. During connection establishment, DNS/QUIC support is indicated by selecting the ALPN token "dq" in the crypto handshake. Current draft version: https://datatracker.ietf.org/doc/html/draft-ietf-dprive-dnsoquic-02
const (
// UnqualifiedNames is reserved name for "unqualified names only", ie names without dots
UnqualifiedNames = "unqualified_names"
)
Variables ¶
This section is empty.
Functions ¶
func CheckDisabledAAAARequest ¶
func CheckDisabledAAAARequest(ctx *DNSContext, ipv6Disabled bool) bool
CheckDisabledAAAARequest checks if AAAA requests should be disabled or not and sets NoError empty response to given DNSContext if needed
Types ¶
type BeforeRequestHandler ¶
type BeforeRequestHandler func(p *Proxy, d *DNSContext) (bool, error)
BeforeRequestHandler is an optional custom handler called before DNS requests If it returns false, the request won't be processed at all
type Config ¶
type Config struct { UDPListenAddr []*net.UDPAddr // if nil, then it does not listen for UDP TCPListenAddr []*net.TCPAddr // if nil, then it does not listen for TCP HTTPSListenAddr []*net.TCPAddr // if nil, then it does not listen for HTTPS (DoH) TLSListenAddr []*net.TCPAddr // if nil, then it does not listen for TLS (DoT) QUICListenAddr []*net.UDPAddr // if nil, then it does not listen for QUIC (DoQ) DNSCryptUDPListenAddr []*net.UDPAddr // if nil, then it does not listen for DNSCrypt DNSCryptTCPListenAddr []*net.TCPAddr // if nil, then it does not listen for DNSCrypt TLSConfig *tls.Config // necessary for TLS, HTTPS, QUIC DNSCryptProviderName string // DNSCrypt provider name DNSCryptResolverCert *dnscrypt.Cert // DNSCrypt resolver certificate Ratelimit int // max number of requests per second from a given IP (0 to disable) RatelimitWhitelist []string // a list of whitelisted client IP addresses RefuseAny bool // if true, refuse ANY requests // TrustedProxies is the list of IP addresses and CIDR networks to // detect proxy servers addresses the DoH requests from which should be // handled. The value of nil or an empty slice for this field makes // Proxy not trust any address. TrustedProxies []string UpstreamConfig *UpstreamConfig // Upstream DNS servers configuration Fallbacks []upstream.Upstream // list of fallback resolvers (which will be used if regular upstream failed to answer) UpstreamMode UpstreamModeType // How to request the upstream servers // FastestPingTimeout is the timeout for waiting the first successful // dialing when the UpstreamMode is set to UModeFastestAddr. // Non-positive value will be replaced with the default one. FastestPingTimeout time.Duration // BogusNXDomain - transforms responses that contain at least one of the given IP addresses into NXDOMAIN // Similar to dnsmasq's "bogus-nxdomain" BogusNXDomain []*net.IPNet // Enable EDNS Client Subnet option DNS requests to the upstream server will // contain an OPT record with Client Subnet option. If the original request // already has this option set, we pass it through as is. Otherwise, we set // it ourselves using the client IP with subnet /24 (for IPv4) and /56 (for // IPv6). // // If the upstream server supports ECS, it sets subnet number in the // response. This subnet number along with the client IP and other data is // used as a cache key. Next time, if a client from the same subnet // requests this host name, we get the response from cache. If another // client from a different subnet requests this host name, we pass his // request to the upstream server. // // If the upstream server doesn't support ECS (there's no subnet number in // response), this response will be cached for all clients. // // If client IP is private (i.e. not public), we don't add EDNS record into // a request. And so there will be no EDNS record in response either. We // store these responses in general cache (without subnet) so they will // never be used for clients with public IP addresses. EnableEDNSClientSubnet bool EDNSAddr net.IP // ECS IP used in request CacheEnabled bool // cache status CacheSizeBytes int // Cache size (in bytes). Default: 64k CacheMinTTL uint32 // Minimum TTL for DNS entries (in seconds). CacheMaxTTL uint32 // Maximum TTL for DNS entries (in seconds). // CacheOptimistic defines if the optimistic cache mechanism should be // used. CacheOptimistic bool BeforeRequestHandler BeforeRequestHandler // callback that is called before each request RequestHandler RequestHandler // callback that can handle incoming DNS requests ResponseHandler ResponseHandler // response callback // MaxGoroutines is the maximum number of goroutines processing DNS // requests. Important for mobile users. // // TODO(a.garipov): Rename this to something like // “MaxDNSRequestGoroutines” in a later major version, as it doesn't // actually limit all goroutines. MaxGoroutines int // The size of the read buffer on the underlying socket. Larger read buffers can handle // larger bursts of requests before packets get dropped. UDPBufferSize int }
Config contains all the fields necessary for proxy configuration
type DNSContext ¶
type DNSContext struct { Proto Proto // Req is the request message. Req *dns.Msg // Res is the response message. Res *dns.Msg // Addr is the address of the client. Addr net.Addr // StartTime is the moment when request processing started. StartTime time.Time // Upstream is the upstream that resolved the request. In case of cached // response it's nil. Upstream upstream.Upstream // CachedUpstreamAddr is the address of the upstream which the answer was // cached with. It's empty for responses resolved by the upstream server. CachedUpstreamAddr string // CustomUpstreamConfig is only used for current request. The Resolve // method of Proxy uses it instead of the default servers if it's not nil. CustomUpstreamConfig *UpstreamConfig // Conn is the underlying client connection. It is nil if Proto is // ProtoDNSCrypt, ProtoHTTPS, or ProtoQUIC. Conn net.Conn // HTTPRequest - HTTP request (for DOH only) HTTPRequest *http.Request // HTTPResponseWriter - HTTP response writer (for DOH only) HTTPResponseWriter http.ResponseWriter // DNSCryptResponseWriter - necessary to respond to a DNSCrypt query DNSCryptResponseWriter dnscrypt.ResponseWriter // QUICStream is the QUIC stream from which we got the query. For // ProtoQUIC only. QUICStream quic.Stream // QUICSession is the QUIC session from which we got the query. For // ProtoQUIC only. QUICSession quic.Session // RequestID is an opaque numerical identifier of this request that is // guaranteed to be unique across requests processed by a single Proxy // instance. RequestID uint64 // ReqECS is the EDNS Client Subnet used in the request. ReqECS *net.IPNet // contains filtered or unexported fields }
DNSContext represents a DNS request message context
type Proto ¶
type Proto string
Proto is the DNS protocol.
const ( // ProtoUDP is the plain DNS-over-UDP protocol. ProtoUDP Proto = "udp" // ProtoTCP is the plain DNS-over-TCP protocol. ProtoTCP Proto = "tcp" // ProtoTLS is the DNS-over-TLS (DoT) protocol. ProtoTLS Proto = "tls" // ProtoHTTPS is the DNS-over-HTTPS (DoH) protocol. ProtoHTTPS Proto = "https" // ProtoQUIC is the DNS-over-QUIC (DoQ) protocol. ProtoQUIC Proto = "quic" // ProtoDNSCrypt is the DNSCrypt protocol. ProtoDNSCrypt Proto = "dnscrypt" )
Proto values.
type Proxy ¶
type Proxy struct { sync.RWMutex // protects parallel access to proxy structures Config // proxy configuration // contains filtered or unexported fields }
Proxy combines the proxy server state and configuration
func (*Proxy) Addr ¶
Addr returns the first listen address for the specified proto or null if the proxy does not listen to it proto must be "tcp", "tls", "https", "quic", or "udp"
func (*Proxy) Addrs ¶
Addrs returns all listen addresses for the specified proto or nil if the proxy does not listen to it. proto must be "tcp", "tls", "https", "quic", or "udp"
func (*Proxy) LookupIPAddr ¶
LookupIPAddr resolves the specified host IP addresses It sends two DNS queries (A and AAAA) in parallel and returns both results
func (*Proxy) Resolve ¶
func (p *Proxy) Resolve(d *DNSContext) (err error)
Resolve is the default resolving method used by the DNS proxy to query upstream servers.
func (*Proxy) ServeHTTP ¶
func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP is the http.RequestHandler implementation that handles DOH queries Here is what it returns: http.StatusBadRequest - if there is no DNS request data http.StatusUnsupportedMediaType - if request content type is not application/dns-message http.StatusMethodNotAllowed - if request method is not GET or POST
func (*Proxy) SetNAT64Prefix ¶
SetNAT64Prefix sets NAT64 prefix
type RequestHandler ¶
type RequestHandler func(p *Proxy, d *DNSContext) error
RequestHandler is an optional custom handler for DNS requests It is called instead of the default method (Proxy.Resolve()) See handler_test.go for examples
type ResponseHandler ¶
type ResponseHandler func(d *DNSContext, err error)
ResponseHandler is a callback method that is called when DNS query has been processed d -- current DNS query context (contains response if it was successful) err -- error (if any)
type UpstreamConfig ¶
type UpstreamConfig struct { Upstreams []upstream.Upstream // list of default upstreams DomainReservedUpstreams map[string][]upstream.Upstream // map of reserved domains and lists of corresponding upstreams }
UpstreamConfig is a wrapper for list of default upstreams and map of reserved domains and corresponding upstreams
func ParseUpstreamsConfig ¶
func ParseUpstreamsConfig(upstreamConfig []string, options *upstream.Options) (*UpstreamConfig, error)
ParseUpstreamsConfig returns UpstreamConfig and error if upstreams configuration is invalid default upstream syntax: <upstreamString> reserved upstream syntax: [/domain1/../domainN/]<upstreamString> More specific domains take priority over less specific domains, To exclude more specific domains from reserved upstreams querying you should use the following syntax: [/domain1/../domainN/]# So the following config: ["[/host.com/]1.2.3.4", "[/www.host.com/]2.3.4.5", "[/maps.host.com/]#", "3.4.5.6"] will send queries for *.host.com to 1.2.3.4, except for *.www.host.com, which will go to 2.3.4.5 and *.maps.host.com, which will go to default server 3.4.5.6 with all other domains
type UpstreamModeType ¶
type UpstreamModeType int
UpstreamModeType - upstream mode
const ( // UModeLoadBalance - LoadBalance UModeLoadBalance UpstreamModeType = iota // UModeParallel - parallel queries to all configured upstream servers are enabled UModeParallel // UModeFastestAddr - use Fastest Address algorithm UModeFastestAddr )