Documentation ¶
Overview ¶
Package resolver is responsible for querying DNS.
DNS Servers ¶
Internal lists of resolvers to use are built on start and rebuilt on every config or network change. Configured DNS servers are prioritized over servers assigned by dhcp. Domain and search options (here referred to as "search scopes") are being considered.
Security ¶
Usage of DNS Servers can be regulated using the configuration:
DoNotUseAssignedDNS // Do not use DNS servers assigned by DHCP DoNotUseMDNS // Do not use mDNS DoNotForwardSpecialDomains // Do not forward special domains to local resolvers, except if they have a search scope for it
Note: The DHCP options "domain" and "search" are ignored for servers assigned by DHCP that do not reside within local address space.
Resolving DNS ¶
Various different queries require the resolver to behave in different manner:
Queries for "localhost." are immediately responded with 127.0.0.1 and ::1, for A and AAAA queries and NXDomain for others. Reverse lookups on local address ranges (10/8, 172.16/12, 192.168/16, fe80::/7) will be tried against every local resolver and finally mDNS until a successful, non-NXDomain answer is received. Special domains ("example.", "example.com.", "example.net.", "example.org.", "invalid.", "test.", "onion.") are resolved using search scopes and local resolvers. All other domains are resolved using search scopes and all available resolvers.
Index ¶
- Constants
- Variables
- func AddToDebugInfo(di *debug.Info)
- func ForceResolverReconnect(ctx context.Context)
- func IsResolverAddress(ip net.IP, port uint16) bool
- func ResetCachedRecord(domain, question string) error
- func ResolveIPAndValidate(ctx context.Context, ip string) (domain string, err error)
- func SetLocalAddrFactory(laf func(network string) net.Addr)
- type BasicResolverConn
- type BlockedUpstreamError
- type DNSRequestContext
- type HTTPSQuery
- type HTTPSResolver
- type IPInfo
- type NameRecord
- type PlainResolver
- type Query
- type RRCache
- func (rrCache *RRCache) Cacheable() bool
- func (rrCache *RRCache) Clean(minExpires uint32)
- func (rrCache *RRCache) Expired() bool
- func (rrCache *RRCache) ExpiresSoon() bool
- func (rrCache *RRCache) ExportAllARecords() (ips []net.IP)
- func (rrCache *RRCache) Flags() string
- func (rrCache *RRCache) GetExtraRRs(ctx context.Context, query *dns.Msg) (extra []dns.RR)
- func (rrCache *RRCache) ID() string
- func (rrCache *RRCache) ReplaceAnswerNames(fqdn string)
- func (rrCache *RRCache) ReplyWithDNS(ctx context.Context, request *dns.Msg) *dns.Msg
- func (rrCache *RRCache) Save() error
- func (rrCache *RRCache) ShallowCopy() *RRCache
- func (rrCache *RRCache) ToDNSRequestContext() *DNSRequestContext
- func (rrCache *RRCache) ToNameRecord() *NameRecord
- type ResolvedDomain
- type ResolvedDomains
- type Resolver
- type ResolverConn
- type ResolverInfo
- type ResolverModule
- type Scope
- type TCPResolver
Constants ¶
const ( BlockDetectionRefused = "refused" BlockDetectionZeroIP = "zeroip" BlockDetectionEmptyAnswer = "empty" BlockDetectionDisabled = "disabled" )
Supported upstream block detections.
const ( ServerTypeDNS = "dns" ServerTypeTCP = "tcp" ServerTypeDoT = "dot" ServerTypeDoH = "doh" ServerTypeMDNS = "mdns" ServerTypeEnv = "env" ServerTypeMonitor = "monitor" ServerTypeFirewall = "firewall" ServerSourceConfigured = "config" ServerSourceOperatingSystem = "system" ServerSourceMDNS = "mdns" ServerSourceEnv = "env" ServerSourceETW = "etw" ServerSourceSystemd = "systemd" ServerSourceFirewall = "firewall" )
DNS Resolver Attributes.
const ( HTTPSProtocol = "https" TLSProtocol = "tls" )
DNS resolver scheme aliases.
const (
DNSClassMulticast = dns.ClassINET | 1<<15
)
DNS Classes.
const (
// IPInfoProfileScopeGlobal is the profile scope used for unscoped IPInfo entries.
IPInfoProfileScopeGlobal = "global"
)
const (
// InternalSpecialUseDomain is the domain scope used for internal services.
InternalSpecialUseDomain = "portmaster.home.arpa."
)
Variables ¶
var ( CompatDNSCheckInternalDomainScope string CompatSelfCheckIsFailing func() bool CompatSubmitDNSCheckDomain func(subdomain string) (respondWith net.IP) )
This is a workaround for enabling the resolver to work with the compat module without importing it. Long-term, the network module should not import the resolver package, as this breaks the SPN hub.
var ( CfgOptionNameServersKey = "dns/nameservers" CfgOptionNoAssignedNameserversKey = "dns/noAssignedNameservers" CfgOptionUseStaleCacheKey = "dns/useStaleCache" CfgOptionNoMulticastDNSKey = "dns/noMulticastDNS" CfgOptionNoInsecureProtocolsKey = "dns/noInsecureProtocols" CfgOptionDontResolveSpecialDomainsKey = "dns/dontResolveSpecialDomains" CfgOptionNameserverRetryRateKey = "dns/nameserverRetryRate" )
Configuration Keys.
var ( // FailThreshold is amount of errors a resolvers must experience in order to be regarded as failed. FailThreshold = 5 // FailObserveDuration is the duration in which failures are counted in order to mark a resolver as failed. FailObserveDuration = time.Duration(FailThreshold) * 10 * time.Second )
var ( // ErrNotFound is a basic error that will match all "not found" errors. ErrNotFound = errors.New("record could not be found") // ErrBlocked is basic error that will match all "blocked" errors. ErrBlocked = errors.New("query was blocked") // ErrLocalhost is returned to *.localhost queries. ErrLocalhost = errors.New("query for localhost") // ErrTimeout is returned when a query times out. ErrTimeout = errors.New("query timed out") // ErrOffline is returned when no network connection is detected. ErrOffline = errors.New("device is offine") // ErrFailure is returned when the type of failure is unclear. ErrFailure = errors.New("query failed") // ErrContinue is returned when the resolver has no answer, and the next resolver should be asked. ErrContinue = errors.New("resolver has no answer") // ErrShuttingDown is returned when the resolver is shutting down. ErrShuttingDown = errors.New("resolver is shutting down") // ErrTestDomainsDisabled wraps ErrBlocked. ErrTestDomainsDisabled = fmt.Errorf("%w: test domains disabled", ErrBlocked) // ErrSpecialDomainsDisabled wraps ErrBlocked. ErrSpecialDomainsDisabled = fmt.Errorf("%w: special domains disabled", ErrBlocked) // ErrInvalid wraps ErrNotFound. ErrInvalid = fmt.Errorf("%w: invalid request", ErrNotFound) // ErrNoCompliance wraps ErrBlocked and is returned when no resolvers were able to comply with the current settings. ErrNoCompliance = fmt.Errorf("%w: no compliant resolvers for this query", ErrBlocked) )
Errors.
Functions ¶
func AddToDebugInfo ¶
AddToDebugInfo adds the system status to the given debug.Info.
func ForceResolverReconnect ¶
ForceResolverReconnect forces all resolvers to reconnect.
func IsResolverAddress ¶
IsResolverAddress returns whether the given ip and port match a configured resolver.
func ResetCachedRecord ¶
ResetCachedRecord deletes a NameRecord from the cache database.
func ResolveIPAndValidate ¶
ResolveIPAndValidate finds (reverse DNS), validates (forward DNS) and returns the domain name assigned to the given IP.
func SetLocalAddrFactory ¶
SetLocalAddrFactory supplies the intel package with a function to get permitted local addresses for connections.
Types ¶
type BasicResolverConn ¶
type BasicResolverConn struct { sync.Mutex // Also used by inheriting structs. // contains filtered or unexported fields }
BasicResolverConn implements ResolverConn for standard dns clients.
func (*BasicResolverConn) IsFailing ¶
func (brc *BasicResolverConn) IsFailing() bool
IsFailing returns if this resolver is currently failing.
func (*BasicResolverConn) ReportFailure ¶
func (brc *BasicResolverConn) ReportFailure()
ReportFailure reports that an error occurred with this resolver.
func (*BasicResolverConn) ResetFailure ¶
func (brc *BasicResolverConn) ResetFailure()
ResetFailure resets the failure status.
type BlockedUpstreamError ¶
type BlockedUpstreamError struct {
ResolverName string
}
BlockedUpstreamError is returned when a DNS request has been blocked by the upstream server.
func (*BlockedUpstreamError) Error ¶
func (blocked *BlockedUpstreamError) Error() string
func (*BlockedUpstreamError) Unwrap ¶
func (blocked *BlockedUpstreamError) Unwrap() error
Unwrap implements errors.Unwrapper.
type DNSRequestContext ¶
type DNSRequestContext struct { Domain string Question string RCode string ServedFromCache bool RequestingNew bool IsBackup bool Filtered bool Modified time.Time Expires time.Time }
DNSRequestContext is a static structure to add information to DNS request connections.
type HTTPSQuery ¶
HTTPSQuery holds the query information for a hTTPSResolverConn.
func (*HTTPSQuery) MakeCacheRecord ¶
func (tq *HTTPSQuery) MakeCacheRecord(reply *dns.Msg, resolverInfo *ResolverInfo) *RRCache
MakeCacheRecord creates an RRCache record from a reply.
type HTTPSResolver ¶
type HTTPSResolver struct { BasicResolverConn // contains filtered or unexported fields }
HTTPSResolver is a resolver using just a single tcp connection with pipelining.
func NewHTTPSResolver ¶
func NewHTTPSResolver(resolver *Resolver) *HTTPSResolver
NewHTTPSResolver returns a new HTTPSResolver.
func (*HTTPSResolver) ForceReconnect ¶
func (hr *HTTPSResolver) ForceReconnect(ctx context.Context)
ForceReconnect forces the resolver to re-establish the connection to the server.
type IPInfo ¶
type IPInfo struct { record.Base sync.Mutex // IP holds the actual IP address. IP string // ProfileID is used to scope this entry to a process group. ProfileID string // ResolvedDomain is a slice of domains that // have been requested by various applications // and have been resolved to IP. ResolvedDomains ResolvedDomains }
IPInfo represents various information about an IP.
func (*IPInfo) AddDomain ¶
func (info *IPInfo) AddDomain(resolved ResolvedDomain)
AddDomain adds a new resolved domain to IPInfo.
func (*IPInfo) MostRecentDomain ¶
func (info *IPInfo) MostRecentDomain() *ResolvedDomain
MostRecentDomain returns the most recent domain.
type NameRecord ¶
type NameRecord struct { record.Base sync.Mutex Domain string Question string RCode int Answer []string Ns []string Extra []string Expires int64 Resolver *ResolverInfo }
NameRecord is helper struct to RRCache to better save data to the database.
func GetNameRecord ¶
func GetNameRecord(domain, question string) (*NameRecord, error)
GetNameRecord gets a NameRecord from the database.
func (*NameRecord) IsValid ¶
func (nameRecord *NameRecord) IsValid() bool
IsValid returns whether the NameRecord is valid and may be used. Otherwise, it should be disregarded.
func (*NameRecord) Save ¶
func (nameRecord *NameRecord) Save() error
Save saves the NameRecord to the database.
type PlainResolver ¶
type PlainResolver struct {
BasicResolverConn
}
PlainResolver is a resolver using plain DNS.
func NewPlainResolver ¶
func NewPlainResolver(resolver *Resolver) *PlainResolver
NewPlainResolver returns a new TPCResolver.
func (*PlainResolver) ForceReconnect ¶
func (pr *PlainResolver) ForceReconnect(_ context.Context)
ForceReconnect forces the resolver to re-establish the connection to the server. Does nothing for PlainResolver, as every request uses its own connection.
type Query ¶
type Query struct { FQDN string QType dns.Type NoCaching bool IgnoreFailing bool LocalResolversOnly bool // ICANNSpace signifies if the domain is within ICANN managed domain space. ICANNSpace bool // Domain root is the effective TLD +1. DomainRoot string // contains filtered or unexported fields }
Query describes a dns query.
func (*Query) InitPublicSuffixData ¶
func (q *Query) InitPublicSuffixData()
InitPublicSuffixData initializes the public suffix data.
type RRCache ¶
type RRCache struct { // Respnse Header Domain string Question dns.Type RCode int // Response Content Answer []dns.RR `json:"-"` Ns []dns.RR `json:"-"` Extra []dns.RR `json:"-"` Expires int64 // Resolver Information Resolver *ResolverInfo `json:"-"` // Metadata about the request and handling ServedFromCache bool RequestingNew bool IsBackup bool Filtered bool FilteredEntries []string // Modified holds when this entry was last changed, ie. saved to database. // This field is only populated when the entry comes from the cache. Modified int64 }
RRCache is a single-use structure to hold a DNS response. Persistence is handled through NameRecords because of a limitation of the underlying dns library.
func GetRRCache ¶
GetRRCache tries to load the corresponding NameRecord from the database and convert it.
func QueryPortmasterEnv ¶
QueryPortmasterEnv queries the environment resolver directly.
func Resolve ¶
Resolve resolves the given query for a domain and type and returns a RRCache object or nil, if the query failed.
func (*RRCache) ExpiresSoon ¶
ExpiresSoon returns whether the record will expire soon (or already has) and should already be refreshed.
func (*RRCache) ExportAllARecords ¶
ExportAllARecords return of a list of all A and AAAA IP addresses.
func (*RRCache) Flags ¶
Flags formats ServedFromCache and RequestingNew to a condensed, flag-like format.
func (*RRCache) GetExtraRRs ¶
GetExtraRRs returns a slice of RRs with additional informational records.
func (*RRCache) ReplaceAnswerNames ¶
ReplaceAnswerNames is a helper function that replaces all answer names, that match the query domain, with another value. This is used to support handling non-standard query names, which are resolved normalized, but have to be reverted back for the origin non-standard query name in order for the clients to recognize the response.
func (*RRCache) ReplyWithDNS ¶
ReplyWithDNS creates a new reply to the given query with the data from the RRCache, and additional informational records.
func (*RRCache) ShallowCopy ¶
ShallowCopy returns a shallow copy of the cache. slices are not copied, but referenced.
func (*RRCache) ToDNSRequestContext ¶
func (rrCache *RRCache) ToDNSRequestContext() *DNSRequestContext
ToDNSRequestContext returns a new DNSRequestContext of the RRCache.
func (*RRCache) ToNameRecord ¶
func (rrCache *RRCache) ToNameRecord() *NameRecord
ToNameRecord converts the RRCache to a NameRecord for cleaner persistence.
type ResolvedDomain ¶
type ResolvedDomain struct { // Domain is the domain as requested by the application. Domain string // CNAMEs is a list of CNAMEs that have been resolved for // Domain. CNAMEs []string // Resolver holds basic information about the resolver that provided this // information. Resolver *ResolverInfo // DNSRequestContext holds the DNS request context. DNSRequestContext *DNSRequestContext // Expires holds the timestamp when this entry expires. // This does not mean that the entry may not be used anymore afterwards, // but that this is used to calcuate the TTL of the database record. Expires int64 }
ResolvedDomain holds a Domain name and a list of CNAMES that have been resolved.
func (*ResolvedDomain) AddCNAMEs ¶ added in v1.6.27
func (resolved *ResolvedDomain) AddCNAMEs(cnames map[string]string)
AddCNAMEs adds all cnames from the map related to its set Domain.
func (*ResolvedDomain) String ¶
func (resolved *ResolvedDomain) String() string
String returns a string representation of ResolvedDomain including the CNAME chain. It implements fmt.Stringer.
type ResolvedDomains ¶
type ResolvedDomains []ResolvedDomain
ResolvedDomains is a helper type for operating on a slice of ResolvedDomain.
func (ResolvedDomains) String ¶
func (rds ResolvedDomains) String() string
String returns a string representation of all domains joined to a single string.
type Resolver ¶
type Resolver struct { // Server config url (and ID) // Supported parameters: // - `verify=domain`: verify domain (dot only) // - `name=name`: human readable name for resolver // - `blockedif=empty`: how to detect if the dns service blocked something // - `empty`: NXDomain result, but without any other record in any section // - `refused`: Request was refused // - `zeroip`: Answer only contains zeroip ConfigURL string // Info holds the parsed configuration. Info *ResolverInfo // ServerAddress holds the resolver address for easier use. ServerAddress string // UpstreamBlockDetection defines the detection type // to identifier upstream DNS query blocking. // Valid values are: // - zeroip // - empty // - refused (default) // - disabled UpstreamBlockDetection string // Special Options Search []string SearchOnly bool Path string LinkLocalUnavailable bool // logic interface Conn ResolverConn `json:"-"` }
Resolver holds information about an active resolver.
func GetResolversInScope ¶
func GetResolversInScope(ctx context.Context, q *Query) (selected []*Resolver, primarySource string, tryAll bool)
GetResolversInScope returns all resolvers that are in scope the resolve the given query and options.
func (*Resolver) IsBlockedUpstream ¶
IsBlockedUpstream returns true if the request has been blocked upstream.
type ResolverConn ¶
type ResolverConn interface { Query(ctx context.Context, q *Query) (*RRCache, error) ReportFailure() IsFailing() bool ResetFailure() ForceReconnect(ctx context.Context) }
ResolverConn is an interface to implement different types of query backends.
type ResolverInfo ¶
type ResolverInfo struct { // Name describes the name given to the resolver. The name is configured in the config URL using the name parameter. Name string // Type describes the type of the resolver. // Possible values include dns, tcp, dot, doh, mdns, env, monitor, firewall. Type string // Source describes where the resolver configuration came from. // Possible values include config, system, mdns, env, etw, systemd, firewall. Source string // IP is the IP address of the resolver IP net.IP // Domain of the dns server if it has one Domain string // IPScope is the network scope of the IP address. IPScope netutils.IPScope // Port is the udp/tcp port of the resolver. Port uint16 // contains filtered or unexported fields }
ResolverInfo is a subset of resolver attributes that is attached to answers from that server in order to use it later for decision making. It must not be changed by anyone after creation and initialization is complete.
func (*ResolverInfo) Copy ¶
func (info *ResolverInfo) Copy() *ResolverInfo
Copy returns a full copy of the ResolverInfo.
func (*ResolverInfo) DescriptiveName ¶
func (info *ResolverInfo) DescriptiveName() string
DescriptiveName returns a human readable, but also detailed representation of the resolver.
func (*ResolverInfo) ID ¶
func (info *ResolverInfo) ID() string
ID returns the unique ID of the resolver.
type ResolverModule ¶ added in v1.6.19
type ResolverModule struct {
// contains filtered or unexported fields
}
ResolverModule is the DNS resolver module.
func New ¶ added in v1.6.19
func New(instance instance) (*ResolverModule, error)
New returns a new Resolver module.
func (*ResolverModule) IsDisabled ¶ added in v1.6.27
func (rm *ResolverModule) IsDisabled() bool
func (*ResolverModule) Manager ¶ added in v1.6.19
func (rm *ResolverModule) Manager() *mgr.Manager
Manager returns the module manager.
func (*ResolverModule) Start ¶ added in v1.6.19
func (rm *ResolverModule) Start() error
Start starts the module.
func (*ResolverModule) States ¶ added in v1.6.19
func (rm *ResolverModule) States() *mgr.StateMgr
States returns the module state manager.
func (*ResolverModule) Stop ¶ added in v1.6.19
func (rm *ResolverModule) Stop() error
Stop stops the module.
type TCPResolver ¶
type TCPResolver struct { BasicResolverConn // contains filtered or unexported fields }
TCPResolver is a resolver using just a single tcp connection with pipelining.
func NewTCPResolver ¶
func NewTCPResolver(resolver *Resolver) *TCPResolver
NewTCPResolver returns a new TPCResolver.
func (*TCPResolver) ForceReconnect ¶
func (tr *TCPResolver) ForceReconnect(ctx context.Context)
ForceReconnect forces the resolver to re-establish the connection to the server.
func (*TCPResolver) UseTLS ¶
func (tr *TCPResolver) UseTLS() *TCPResolver
UseTLS enabled TLS for the TCPResolver. TLS settings must be correctly configured in the Resolver.