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 ¶ added in v0.20.1
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 ¶ added in v0.14.0
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.IP
// 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 /112 (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
// contains filtered or unexported fields
}
DNSContext represents a DNS request message context
type Proto ¶ added in v0.38.0
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 ¶ added in v0.9.1
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 ¶ added in v0.32.0
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 ¶ added in v0.23.0
LookupIPAddr resolves the specified host IP addresses It sends two DNS queries (A and AAAA) in parallel and returns both results
func (*Proxy) Resolve ¶ added in v0.9.1
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 ¶ added in v0.9.11
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 ¶ added in v0.13.0
SetNAT64Prefix sets NAT64 prefix
type RequestHandler ¶ added in v0.14.0
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 ¶ added in v0.13.0
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 ¶ added in v0.12.0
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 ¶ added in v0.12.0
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 ¶ added in v0.29.0
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 )