resolver

package
v0.4.17 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2020 License: AGPL-3.0 Imports: 27 Imported by: 0

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

View Source
const (
	BlockDetectionRefused     = "refused"
	BlockDetectionZeroIP      = "zeroip"
	BlockDetectionEmptyAnswer = "empty"
	BlockDetectionDisabled    = "disabled"
)

Supported upstream block detections

View Source
const (
	ServerTypeDNS = "dns"
	ServerTypeTCP = "tcp"
	ServerTypeDoT = "dot"
	ServerTypeDoH = "doh"
	ServerTypeEnv = "env"

	ServerSourceConfigured = "config"
	ServerSourceAssigned   = "dhcp"
	ServerSourceMDNS       = "mdns"
	ServerSourceEnv        = "env"
)

DNS Resolver Attributes

View Source
const (
	DNSClassMulticast = dns.ClassINET | 1<<15
)

DNS Classes

Variables

View Source
var (
	CfgOptionNameServersKey = "dns/nameservers"

	CfgOptionNoAssignedNameserversKey = "dns/noAssignedNameservers"

	CfgOptionNoMulticastDNSKey = "dns/noMulticastDNS"

	CfgOptionNoInsecureProtocolsKey = "dns/noInsecureProtocols"

	CfgOptionDontResolveSpecialDomainsKey = "dns/dontResolveSpecialDomains"

	CfgOptionDontResolveTestDomainsKey = "dns/dontResolveTestDomains"

	CfgOptionNameserverRetryRateKey = "dns/nameserverRetryRate"
)

Configuration Keys

View Source
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")

	// 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)
)
View Source
var (
	// ClearNameCacheEvent is a triggerable event that clears the name record cache.
	ClearNameCacheEvent = "clear name cache"
)
View Source
var (
	// FailThreshold is amount of errors a resolvers must experience in order to be regarded as failed.
	FailThreshold = 20
)

Functions

func DeleteNameRecord added in v0.4.13

func DeleteNameRecord(domain, question string) error

DeleteNameRecord deletes a NameRecord from the database.

func ResolveIPAndValidate

func ResolveIPAndValidate(ctx context.Context, ip string, securityLevel uint8) (domain string, err error)

ResolveIPAndValidate finds (reverse DNS), validates (forward DNS) and returns the domain name assigned to the given IP.

func SetLocalAddrFactory

func SetLocalAddrFactory(laf func(network string) net.Addr)

SetLocalAddrFactory supplies the intel package with a function to get permitted local addresses for connections.

Types

type BasicResolverConn

type BasicResolverConn struct {
	sync.Mutex // for lastFail
	// contains filtered or unexported fields
}

BasicResolverConn implements ResolverConn for standard dns clients.

func (*BasicResolverConn) IsFailing added in v0.4.4

func (brc *BasicResolverConn) IsFailing() bool

IsFailing returns if this resolver is currently failing.

func (*BasicResolverConn) ReportFailure added in v0.4.4

func (brc *BasicResolverConn) ReportFailure()

ReportFailure reports that an error occurred with this resolver.

type BlockedUpstreamError added in v0.4.1

type BlockedUpstreamError struct {
	ResolverName string
}

BlockedUpstreamError is returned when a DNS request has been blocked by the upstream server.

func (*BlockedUpstreamError) Error added in v0.4.1

func (blocked *BlockedUpstreamError) Error() string

func (*BlockedUpstreamError) Unwrap added in v0.4.1

func (blocked *BlockedUpstreamError) Unwrap() error

Unwrap implements errors.Unwrapper

type IPInfo

type IPInfo struct {
	record.Base
	sync.Mutex

	// IP holds the acutal IP address.
	IP string

	// Domains holds a list of domains that have been
	// resolved to IP. This field is deprecated and should
	// be removed.
	// DEPRECATED: remove with alpha.
	Domains []string `json:"Domains,omitempty"`

	// 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 GetIPInfo

func GetIPInfo(ip string) (*IPInfo, error)

GetIPInfo gets an IPInfo record from the database.

func (*IPInfo) AddDomain

func (ipi *IPInfo) AddDomain(resolved ResolvedDomain) bool

AddDomain adds a new resolved domain to ipi.

func (*IPInfo) Save

func (ipi *IPInfo) Save() error

Save saves the IPInfo record to the database.

func (*IPInfo) String

func (ipi *IPInfo) String() string

FmtDomains returns a string consisting of the domains that have seen to use this IP, joined by " or "

type InFlightQuery added in v0.4.9

type InFlightQuery struct {
	Query          *Query
	Msg            *dns.Msg
	Response       chan *dns.Msg
	Resolver       *Resolver
	Started        time.Time
	ConnInstanceID uint32
}

InFlightQuery represents an in flight query of a TCPResolver.

func (*InFlightQuery) MakeCacheRecord added in v0.4.9

func (ifq *InFlightQuery) MakeCacheRecord(reply *dns.Msg) *RRCache

MakeCacheRecord creates an RCache record from a reply.

type NameRecord

type NameRecord struct {
	record.Base
	sync.Mutex

	Domain   string
	Question string
	Answer   []string
	Ns       []string
	Extra    []string
	TTL      int64

	Server      string
	ServerScope int8
}

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) Save

func (rec *NameRecord) Save() error

Save saves the NameRecord to the database.

type PlainResolver added in v0.4.14

type PlainResolver struct {
	BasicResolverConn
}

PlainResolver is a resolver using plain DNS.

func NewPlainResolver added in v0.4.14

func NewPlainResolver(resolver *Resolver) *PlainResolver

NewPlainResolver returns a new TPCResolver.

func (*PlainResolver) Query added in v0.4.14

func (pr *PlainResolver) Query(ctx context.Context, q *Query) (*RRCache, error)

Query executes the given query against the resolver.

type Query

type Query struct {
	FQDN               string
	QType              dns.Type
	SecurityLevel      uint8
	NoCaching          bool
	IgnoreFailing      bool
	LocalResolversOnly bool
	// contains filtered or unexported fields
}

Query describes a dns query.

func (*Query) ID added in v0.4.13

func (q *Query) ID() string

ID returns the ID of the query consisting of the domain and question type.

type RRCache

type RRCache struct {
	sync.Mutex

	Domain   string   // constant
	Question dns.Type // constant

	Answer []dns.RR // might be mixed
	Ns     []dns.RR // constant
	Extra  []dns.RR // constant
	TTL    int64    // constant

	Server      string // constant
	ServerScope int8   // constant

	Filtered        bool     // mutable
	FilteredEntries []string // mutable
	// contains filtered or unexported fields
}

RRCache is used to cache DNS data

func GetRRCache

func GetRRCache(domain string, question dns.Type) (*RRCache, error)

GetRRCache tries to load the corresponding NameRecord from the database and convert it.

func Resolve

func Resolve(ctx context.Context, q *Query) (rrCache *RRCache, err error)

Resolve resolves the given query for a domain and type and returns a RRCache object or nil, if the query failed.

func (*RRCache) Clean

func (rrCache *RRCache) Clean(minExpires uint32)

Clean sets all TTLs to 17 and sets cache expiry with specified minimum.

func (*RRCache) Expired

func (rrCache *RRCache) Expired() bool

Expired returns whether the record has expired.

func (*RRCache) ExportAllARecords

func (rrCache *RRCache) ExportAllARecords() (ips []net.IP)

ExportAllARecords return of a list of all A and AAAA IP addresses.

func (*RRCache) Flags

func (rrCache *RRCache) Flags() string

Flags formats ServedFromCache and RequestingNew to a condensed, flag-like format.

func (*RRCache) ID added in v0.4.13

func (rrCache *RRCache) ID() string

ID returns the ID of the RRCache consisting of the domain and question type.

func (*RRCache) IsNXDomain

func (rrCache *RRCache) IsNXDomain() bool

IsNXDomain returnes whether the result is nxdomain.

func (*RRCache) MixAnswers

func (rrCache *RRCache) MixAnswers()

MixAnswers randomizes the answer records to allow dumb clients (who only look at the first record) to reliably connect.

func (*RRCache) RequestingNew

func (rrCache *RRCache) RequestingNew() bool

RequestingNew informs that it has expired and new RRs are being fetched.

func (*RRCache) Save

func (rrCache *RRCache) Save() error

Save saves the RRCache to the database as a NameRecord.

func (*RRCache) ServedFromCache

func (rrCache *RRCache) ServedFromCache() bool

ServedFromCache marks the RRCache as served from cache.

func (*RRCache) ShallowCopy

func (rrCache *RRCache) ShallowCopy() *RRCache

ShallowCopy returns a shallow copy of the cache. slices are not copied, but referenced.

func (*RRCache) ToNameRecord

func (rrCache *RRCache) ToNameRecord() *NameRecord

ToNameRecord converts the RRCache to a NameRecord for cleaner persistence.

type ResolvedDomain added in v0.4.1

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
}

ResolvedDomain holds a Domain name and a list of CNAMES that have been resolved.

func (*ResolvedDomain) String added in v0.4.1

func (resolved *ResolvedDomain) String() string

String returns a string representation of ResolvedDomain including the CNAME chain. It implements fmt.Stringer

type ResolvedDomains added in v0.4.1

type ResolvedDomains []ResolvedDomain

ResolvedDomains is a helper type for operating on a slice of ResolvedDomain

func (ResolvedDomains) MostRecentDomain added in v0.4.1

func (rds ResolvedDomains) MostRecentDomain() *ResolvedDomain

MostRecentDomain returns the most recent domain.

func (ResolvedDomains) String added in v0.4.1

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
	Server string

	// Name is the name of the resolver as passed via
	// ?name=.
	Name string

	// UpstreamBlockDetection defines the detection type
	// to identifier upstream DNS query blocking.
	// Valid values are:
	//	 - zeroip
	//	 - empty
	//   - refused (default)
	//	 - disabled
	UpstreamBlockDetection string

	// Parsed config
	ServerType    string
	ServerAddress string
	ServerIP      net.IP
	ServerIPScope int8
	ServerPort    uint16

	// Special Options
	VerifyDomain string
	Search       []string
	SkipFQDN     string

	Source string

	// logic interface
	Conn ResolverConn
}

Resolver holds information about an active resolver.

func GetResolversInScope

func GetResolversInScope(ctx context.Context, q *Query) (selected []*Resolver)

GetResolversInScope returns all resolvers that are in scope the resolve the given query and options.

func (*Resolver) GetName added in v0.4.1

func (resolver *Resolver) GetName() string

GetName returns the name of the server. If no name is configured the server address is returned.

func (*Resolver) IsBlockedUpstream added in v0.4.1

func (resolver *Resolver) IsBlockedUpstream(answer *dns.Msg) bool

IsBlockedUpstream returns true if the request has been blocked upstream.

func (*Resolver) String

func (resolver *Resolver) String() string

String returns the URL representation of the resolver.

type ResolverConn

type ResolverConn interface {
	Query(ctx context.Context, q *Query) (*RRCache, error)
	ReportFailure()
	IsFailing() bool
}

ResolverConn is an interface to implement different types of query backends.

type Scope

type Scope struct {
	Domain    string
	Resolvers []*Resolver
}

Scope defines a domain scope and which resolvers can resolve it.

type TCPResolver added in v0.4.9

type TCPResolver struct {
	BasicResolverConn
	// contains filtered or unexported fields
}

TCPResolver is a resolver using just a single tcp connection with pipelining.

func NewTCPResolver added in v0.4.9

func NewTCPResolver(resolver *Resolver) *TCPResolver

NewTCPResolver returns a new TPCResolver.

func (*TCPResolver) Query added in v0.4.9

func (tr *TCPResolver) Query(ctx context.Context, q *Query) (*RRCache, error)

Query executes the given query against the resolver.

func (*TCPResolver) UseTLS added in v0.4.9

func (tr *TCPResolver) UseTLS() *TCPResolver

UseTLS enabled TLS for the TCPResolver. TLS settings must be correctly configured in the Resolver.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL