resolver

package
v0.28.0 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2025 License: Apache-2.0 Imports: 49 Imported by: 0

Documentation

Overview

This file implements DNSSEC validation for DNS resolution.

DNSSEC Validation Implementation

This file implements DNSSEC (Domain Name System Security Extensions) validation according to the following RFCs:

  • RFC 4033: DNS Security Introduction and Requirements
  • RFC 4034: Resource Records for DNS Security Extensions
  • RFC 4035: Protocol Modifications for DNS Security Extensions
  • RFC 5155: DNS Security (DNSSEC) Hashed Authenticated Denial of Existence
  • RFC 6840: Clarifications and Implementation Notes for DNSSEC
  • RFC 6781: DNSSEC Operational Practices, Version 2
  • RFC 8080: Edwards-Curve Digital Security Algorithm (EdDSA) for DNSSEC
  • RFC 8624: Algorithm Implementation Requirements and Usage Guidance for DNSSEC

Key Features:

1. Full Chain of Trust Validation

  • Validates DNSSEC signatures from trust anchors (root keys) down to zone data
  • Supports both NSEC and NSEC3 authenticated denial of existence
  • Handles wildcard expansion validation per RFC 4035 §5.3.4

2. DoS Protection

  • Configurable maximum chain depth to prevent excessive recursion
  • Maximum NSEC3 iteration limit (default 150, per RFC 5155 §10.3)
  • Maximum upstream query budget to prevent query amplification attacks
  • Request-scoped query counting to track and limit validation overhead

3. Security Best Practices

  • Algorithm downgrade attack prevention (RFC 6840 §5.11)
  • Clock skew tolerance for signature validation (RFC 6781 §4.1.2)
  • Support for modern algorithms including EdDSA (RFC 8080)
  • Comprehensive validation result caching to reduce load

4. Performance Optimizations

  • Expiring cache for validation results
  • NSEC3 hash computation caching
  • Prometheus metrics for monitoring validation performance
  • Parallel validation where applicable

The validator returns one of four results:

  • Secure: Valid DNSSEC signatures and complete chain of trust
  • Insecure: No DNSSEC (unsigned zone, valid delegation)
  • Bogus: Invalid DNSSEC (failed validation, security threat)
  • Indeterminate: Validation could not be completed (network/system errors)

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidValidationResult = fmt.Errorf("not a valid ValidationResult, try [%s]", strings.Join(_ValidationResultNames, ", "))
View Source
var NoResponse = &model.Response{} //nolint:gochecknoglobals

Functions

func ForEach

func ForEach(resolver Resolver, callback func(Resolver))

ForEach iterates over all resolvers in the chain.

If resolver is not a chain, or is unlinked, the callback is called exactly once.

func GetFromChainWithType

func GetFromChainWithType[T any](resolver ChainedResolver) (result T, err error)

func GetQueryLoggingWriter

func GetQueryLoggingWriter(ctx context.Context, cfg config.QueryLog) (querylog.Writer, error)

func LogResolverConfig

func LogResolverConfig(res Resolver, logger *logrus.Entry)

LogResolverConfig logs the resolver's type and config.

func Name

func Name(resolver Resolver) string

Name returns a user-friendly name of a resolver

func ValidationResultNames added in v0.28.0

func ValidationResultNames() []string

ValidationResultNames returns a list of possible string values of ValidationResult.

Types

type BlockingResolver

type BlockingResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

BlockingResolver checks request's question (domain name) against allow/denylists

func NewBlockingResolver

func NewBlockingResolver(ctx context.Context,
	cfg config.Blocking,
	redis *redis.Client,
	bootstrap *Bootstrap,
) (r *BlockingResolver, err error)

NewBlockingResolver returns a new configured instance of the resolver

func (*BlockingResolver) BlockingStatus

func (r *BlockingResolver) BlockingStatus() api.BlockingStatus

BlockingStatus returns the current blocking status

func (*BlockingResolver) DisableBlocking

func (r *BlockingResolver) DisableBlocking(ctx context.Context, duration time.Duration, disableGroups []string) error

DisableBlocking deactivates the blocking for a particular duration (or forever if 0).

func (*BlockingResolver) EnableBlocking

func (r *BlockingResolver) EnableBlocking(ctx context.Context)

EnableBlocking enables the blocking against the denylists

func (*BlockingResolver) IsEnabled

func (c *BlockingResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*BlockingResolver) LogConfig

func (r *BlockingResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*BlockingResolver) RefreshLists

func (r *BlockingResolver) RefreshLists(ctx context.Context) error

RefreshLists triggers the refresh of all allow/denylists in the cache

func (*BlockingResolver) Resolve

func (r *BlockingResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

Resolve checks the query against the denylist and delegates to next resolver if domain is not blocked

func (*BlockingResolver) String

func (t *BlockingResolver) String() string

String implements `fmt.Stringer`.

func (*BlockingResolver) Type

func (t *BlockingResolver) Type() string

Type implements `Resolver`.

type Bootstrap

type Bootstrap struct {
	// contains filtered or unexported fields
}

Bootstrap allows resolving hostnames using the configured bootstrap DNS.

func NewBootstrap

func NewBootstrap(ctx context.Context, cfg *config.Config) (b *Bootstrap, err error)

NewBootstrap creates and returns a new Bootstrap. Internally, it uses a CachingResolver and an UpstreamResolver.

func (*Bootstrap) IsEnabled

func (c *Bootstrap) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*Bootstrap) LogConfig

func (c *Bootstrap) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*Bootstrap) NewHTTPTransport

func (b *Bootstrap) NewHTTPTransport() *http.Transport

NewHTTPTransport returns a new http.Transport that uses b to resolve hostnames

func (*Bootstrap) Resolve

func (b *Bootstrap) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

func (*Bootstrap) String

func (t *Bootstrap) String() string

String implements `fmt.Stringer`.

func (*Bootstrap) Type

func (t *Bootstrap) Type() string

Type implements `Resolver`.

func (*Bootstrap) UpstreamIPs

func (b *Bootstrap) UpstreamIPs(ctx context.Context, r *UpstreamResolver) (*IPSet, error)

type CachingResolver

type CachingResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

CachingResolver caches answers from dns queries with their TTL time, to avoid external resolver calls for recurrent queries

func NewCachingResolver

func NewCachingResolver(ctx context.Context,
	cfg config.Caching,
	redis *redis.Client,
) (*CachingResolver, error)

NewCachingResolver creates a new resolver instance

func (*CachingResolver) FlushCaches

func (r *CachingResolver) FlushCaches(ctx context.Context)

func (*CachingResolver) IsEnabled

func (c *CachingResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*CachingResolver) LogConfig

func (r *CachingResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*CachingResolver) Resolve

func (r *CachingResolver) Resolve(ctx context.Context, request *model.Request) (response *model.Response, err error)

Resolve checks if the current query should use the cache and if the result is already in the cache and returns it or delegates to the next resolver

func (*CachingResolver) String

func (t *CachingResolver) String() string

String implements `fmt.Stringer`.

func (*CachingResolver) Type

func (t *CachingResolver) Type() string

Type implements `Resolver`.

type ChainedResolver

type ChainedResolver interface {
	Resolver

	// Next sets the next resolver
	Next(n Resolver)

	// GetNext returns the next resolver
	GetNext() Resolver
}

ChainedResolver represents a resolver, which can delegate result to the next one

func Chain

func Chain(resolvers ...Resolver) ChainedResolver

Chain creates a chain of resolvers

func NewDNSSECResolver added in v0.28.0

func NewDNSSECResolver(ctx context.Context, cfg config.DNSSEC, upstream Resolver) (ChainedResolver, error)

NewDNSSECResolver creates a new DNSSEC resolver instance

func NewECSResolver

func NewECSResolver(cfg config.ECS) ChainedResolver

NewECSResolver creates new resolver instance which adds the subnet information as EDNS0 option

type ClientNamesResolver

type ClientNamesResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

ClientNamesResolver tries to determine client name by asking responsible DNS server via rDNS (reverse lookup)

func NewClientNamesResolver

func NewClientNamesResolver(ctx context.Context,
	cfg config.ClientLookup, upstreamsCfg config.Upstreams, bootstrap *Bootstrap,
) (cr *ClientNamesResolver, err error)

NewClientNamesResolver creates new resolver instance

func (*ClientNamesResolver) FlushCache

func (r *ClientNamesResolver) FlushCache()

FlushCache reset client name cache

func (*ClientNamesResolver) IsEnabled

func (c *ClientNamesResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*ClientNamesResolver) LogConfig

func (r *ClientNamesResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*ClientNamesResolver) Resolve

func (r *ClientNamesResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

Resolve tries to resolve the client name from the ip address

func (*ClientNamesResolver) String

func (t *ClientNamesResolver) String() string

String implements `fmt.Stringer`.

func (*ClientNamesResolver) Type

func (t *ClientNamesResolver) Type() string

Type implements `Resolver`.

type ConditionalUpstreamResolver

type ConditionalUpstreamResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

ConditionalUpstreamResolver delegates DNS question to other DNS resolver dependent on domain name in question

func NewConditionalUpstreamResolver

func NewConditionalUpstreamResolver(
	ctx context.Context, cfg config.ConditionalUpstream, upstreamsCfg config.Upstreams, bootstrap *Bootstrap,
) (*ConditionalUpstreamResolver, error)

NewConditionalUpstreamResolver returns new resolver instance

func (*ConditionalUpstreamResolver) IsEnabled

func (c *ConditionalUpstreamResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*ConditionalUpstreamResolver) LogConfig

func (c *ConditionalUpstreamResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*ConditionalUpstreamResolver) Resolve

Resolve uses the conditional resolver to resolve the query

func (*ConditionalUpstreamResolver) String

func (t *ConditionalUpstreamResolver) String() string

String implements `fmt.Stringer`.

func (*ConditionalUpstreamResolver) Type

func (t *ConditionalUpstreamResolver) Type() string

Type implements `Resolver`.

type CustomDNSResolver

type CustomDNSResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

CustomDNSResolver resolves passed domain name to ip address defined in domain-IP map

func NewCustomDNSResolver

func NewCustomDNSResolver(cfg config.CustomDNS) *CustomDNSResolver

NewCustomDNSResolver creates new resolver instance

func (*CustomDNSResolver) CreateAnswerFromQuestion

func (r *CustomDNSResolver) CreateAnswerFromQuestion(newFunc createAnswerFunc)

func (*CustomDNSResolver) IsEnabled

func (c *CustomDNSResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*CustomDNSResolver) LogConfig

func (c *CustomDNSResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*CustomDNSResolver) Resolve

func (r *CustomDNSResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

Resolve uses internal mapping to resolve the query

func (*CustomDNSResolver) String

func (t *CustomDNSResolver) String() string

String implements `fmt.Stringer`.

func (*CustomDNSResolver) Type

func (t *CustomDNSResolver) Type() string

Type implements `Resolver`.

type DNSSECResolver added in v0.28.0

type DNSSECResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

DNSSECResolver is responsible for DNSSEC validation of DNS responses

func (*DNSSECResolver) IsEnabled added in v0.28.0

func (c *DNSSECResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*DNSSECResolver) LogConfig added in v0.28.0

func (c *DNSSECResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*DNSSECResolver) Resolve added in v0.28.0

func (r *DNSSECResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

Resolve validates DNSSEC signatures if validation is enabled

func (*DNSSECResolver) String added in v0.28.0

func (t *DNSSECResolver) String() string

String implements `fmt.Stringer`.

func (*DNSSECResolver) Type added in v0.28.0

func (t *DNSSECResolver) Type() string

Type implements `Resolver`.

type DNSSECValidator added in v0.28.0

type DNSSECValidator struct {
	// contains filtered or unexported fields
}

DNSSECValidator validates DNSSEC signatures and chains of trust

func NewDNSSECValidator added in v0.28.0

func NewDNSSECValidator(
	ctx context.Context,
	trustAnchors *TrustAnchorStore,
	logger *logrus.Entry,
	upstream Resolver,
	cacheExpirationHours uint,
	maxChainDepth uint,
	maxNSEC3Iterations uint,
	maxUpstreamQueries uint,
	clockSkewToleranceSec uint,
) *DNSSECValidator

NewDNSSECValidator creates a new DNSSEC validator with the given configuration.

Parameters:

  • ctx: Context for the validator lifecycle (used for cache cleanup)
  • trustAnchors: Trust anchor store containing root and/or zone-specific DNSSEC trust anchors
  • logger: Logger for validation events and debugging
  • upstream: Resolver to use for querying DNSKEY and DS records
  • cacheExpirationHours: How long to cache validation results (0 defaults to 1 hour)
  • maxChainDepth: Maximum domain label depth to validate (0 defaults to 10, prevents DoS)
  • maxNSEC3Iterations: Maximum NSEC3 iterations (0 defaults to 150, prevents DoS)
  • maxUpstreamQueries: Maximum upstream queries per validation (0 defaults to 30, prevents DoS)
  • clockSkewToleranceSec: Clock skew tolerance in seconds (0 defaults to 3600 = 1 hour)

Returns a configured DNSSECValidator ready for use.

func (*DNSSECValidator) ValidateResponse added in v0.28.0

func (v *DNSSECValidator) ValidateResponse(
	ctx context.Context,
	response *dns.Msg,
	question dns.Question,
) ValidationResult

ValidateResponse validates a DNS response's DNSSEC signatures according to RFC 4035.

This function performs the following validation steps:

  1. Checks if the response contains DNSSEC signatures (RRSIG records)
  2. If unsigned, returns ValidationResultInsecure
  3. If signed, validates all RRsets in the answer section: - Verifies RRSIG signatures match the RRset data - Validates signature time windows (inception/expiration) - Walks the chain of trust from root to the domain - Verifies DNSKEYs against DS records or trust anchors
  4. Returns ValidationResultSecure if all checks pass
  5. Returns ValidationResultBogus if validation fails

Parameters:

  • ctx: Context for the validation operation
  • response: DNS response message to validate
  • question: Original DNS question for context

Returns one of: ValidationResultSecure, ValidationResultInsecure, ValidationResultBogus, or ValidationResultIndeterminate

type ECSMask

type ECSMask interface {
	config.ECSv4Mask | config.ECSv6Mask
}

ECSMask is an interface for all ECS subnet masks as type constraint for generics

type ECSResolver

type ECSResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

ECSResolver is responsible for adding the EDNS Client Subnet information as EDNS0 option.

func (*ECSResolver) IsEnabled

func (c *ECSResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*ECSResolver) LogConfig

func (c *ECSResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*ECSResolver) Resolve

func (r *ECSResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

Resolve adds the subnet information as EDNS0 option to the request of the next resolver and sets the client IP from the EDNS0 option to the request if this option is enabled

func (*ECSResolver) String

func (t *ECSResolver) String() string

String implements `fmt.Stringer`.

func (*ECSResolver) Type

func (t *ECSResolver) Type() string

Type implements `Resolver`.

type EDEResolver

type EDEResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

A EDEResolver is responsible for adding the reason for the response as EDNS0 option

func NewEDEResolver

func NewEDEResolver(cfg config.EDE) *EDEResolver

NewEDEResolver creates new resolver instance which adds the reason for the response as EDNS0 option to the response if it is enabled in the configuration

func (*EDEResolver) IsEnabled

func (c *EDEResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*EDEResolver) LogConfig

func (c *EDEResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*EDEResolver) Resolve

func (r *EDEResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

Resolve adds the reason as EDNS0 option to the response of the next resolver if it is enabled in the configuration

func (*EDEResolver) String

func (t *EDEResolver) String() string

String implements `fmt.Stringer`.

func (*EDEResolver) Type

func (t *EDEResolver) Type() string

Type implements `Resolver`.

type FQDNOnlyResolver

type FQDNOnlyResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

func NewFQDNOnlyResolver

func NewFQDNOnlyResolver(cfg config.FQDNOnly) *FQDNOnlyResolver

func (*FQDNOnlyResolver) IsEnabled

func (c *FQDNOnlyResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*FQDNOnlyResolver) LogConfig

func (c *FQDNOnlyResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*FQDNOnlyResolver) Resolve

func (r *FQDNOnlyResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

func (*FQDNOnlyResolver) String

func (t *FQDNOnlyResolver) String() string

String implements `fmt.Stringer`.

func (*FQDNOnlyResolver) Type

func (t *FQDNOnlyResolver) Type() string

Type implements `Resolver`.

type FilteringResolver

type FilteringResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

FilteringResolver filters DNS queries (for example can drop all AAAA query) returns empty ANSWER with NOERROR

func NewFilteringResolver

func NewFilteringResolver(cfg config.Filtering) *FilteringResolver

func (*FilteringResolver) IsEnabled

func (c *FilteringResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*FilteringResolver) LogConfig

func (c *FilteringResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*FilteringResolver) Resolve

func (r *FilteringResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

func (*FilteringResolver) String

func (t *FilteringResolver) String() string

String implements `fmt.Stringer`.

func (*FilteringResolver) Type

func (t *FilteringResolver) Type() string

Type implements `Resolver`.

type HostsFileEntry

type HostsFileEntry = parsers.HostsFileEntry

type HostsFileResolver

type HostsFileResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

func NewHostsFileResolver

func NewHostsFileResolver(ctx context.Context,
	cfg config.HostsFile,
	bootstrap *Bootstrap,
) (*HostsFileResolver, error)

func (*HostsFileResolver) IsEnabled

func (c *HostsFileResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*HostsFileResolver) LogConfig

func (r *HostsFileResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*HostsFileResolver) Resolve

func (r *HostsFileResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

func (*HostsFileResolver) String

func (t *HostsFileResolver) String() string

String implements `fmt.Stringer`.

func (*HostsFileResolver) Type

func (t *HostsFileResolver) Type() string

Type implements `Resolver`.

type IPSet

type IPSet struct {
	// contains filtered or unexported fields
}

func (*IPSet) Current

func (ips *IPSet) Current() net.IP

func (*IPSet) Next

func (ips *IPSet) Next()

type MetricsResolver

type MetricsResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

MetricsResolver resolver that records metrics about requests/response

func NewMetricsResolver

func NewMetricsResolver(cfg config.Metrics) *MetricsResolver

NewMetricsResolver creates a new intance of the MetricsResolver type

func (*MetricsResolver) IsEnabled

func (c *MetricsResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*MetricsResolver) LogConfig

func (c *MetricsResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*MetricsResolver) Resolve

func (r *MetricsResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

Resolve resolves the passed request

func (*MetricsResolver) String

func (t *MetricsResolver) String() string

String implements `fmt.Stringer`.

func (*MetricsResolver) Type

func (t *MetricsResolver) Type() string

Type implements `Resolver`.

type MockUDPUpstreamServer

type MockUDPUpstreamServer struct {
	// contains filtered or unexported fields
}

func NewMockUDPUpstreamServer

func NewMockUDPUpstreamServer() *MockUDPUpstreamServer

func (*MockUDPUpstreamServer) Close

func (t *MockUDPUpstreamServer) Close()

func (*MockUDPUpstreamServer) GetCallCount

func (t *MockUDPUpstreamServer) GetCallCount() int

func (*MockUDPUpstreamServer) ResetCallCount

func (t *MockUDPUpstreamServer) ResetCallCount()

func (*MockUDPUpstreamServer) Start

func (*MockUDPUpstreamServer) WithAnswerError

func (t *MockUDPUpstreamServer) WithAnswerError(errorCode int) *MockUDPUpstreamServer

func (*MockUDPUpstreamServer) WithAnswerFn

func (t *MockUDPUpstreamServer) WithAnswerFn(fn func(request *dns.Msg) (response *dns.Msg)) *MockUDPUpstreamServer

func (*MockUDPUpstreamServer) WithAnswerMsg

func (t *MockUDPUpstreamServer) WithAnswerMsg(answer *dns.Msg) *MockUDPUpstreamServer

func (*MockUDPUpstreamServer) WithAnswerRR

func (t *MockUDPUpstreamServer) WithAnswerRR(answers ...string) *MockUDPUpstreamServer

func (*MockUDPUpstreamServer) WithDelay

type NamedResolver

type NamedResolver interface {
	// Name returns the full name of the resolver
	Name() string
}

NamedResolver is a resolver with a special name

type NextResolver

type NextResolver struct {
	// contains filtered or unexported fields
}

NextResolver is the base implementation of ChainedResolver

func (*NextResolver) GetNext

func (r *NextResolver) GetNext() Resolver

GetNext returns the next resolver

func (*NextResolver) Next

func (r *NextResolver) Next(n Resolver)

Next sets the next resolver

type NoOpResolver

type NoOpResolver struct{}

NoOpResolver is used to finish a resolver branch as created in RewriterResolver

func NewNoOpResolver

func NewNoOpResolver() *NoOpResolver

func (NoOpResolver) IsEnabled

func (NoOpResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (NoOpResolver) LogConfig

func (NoOpResolver) LogConfig(*logrus.Entry)

LogConfig implements `config.Configurable`.

func (NoOpResolver) Resolve

func (NoOpResolver) String

func (r NoOpResolver) String() string

String implements `fmt.Stringer`.

func (NoOpResolver) Type

func (NoOpResolver) Type() string

Type implements `Resolver`.

type ParallelBestResolver

type ParallelBestResolver struct {
	// contains filtered or unexported fields
}

ParallelBestResolver delegates the DNS message to 2 upstream resolvers and returns the fastest answer

func NewParallelBestResolver

func NewParallelBestResolver(
	ctx context.Context, cfg config.UpstreamGroup, bootstrap *Bootstrap,
) (*ParallelBestResolver, error)

NewParallelBestResolver creates new resolver instance

func (*ParallelBestResolver) IsEnabled

func (c *ParallelBestResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*ParallelBestResolver) LogConfig

func (c *ParallelBestResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*ParallelBestResolver) Name

func (r *ParallelBestResolver) Name() string

func (*ParallelBestResolver) Resolve

func (r *ParallelBestResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

Resolve sends the query request to multiple upstream resolvers and returns the fastest result

func (*ParallelBestResolver) String

func (r *ParallelBestResolver) String() string

func (*ParallelBestResolver) Type

func (t *ParallelBestResolver) Type() string

Type implements `Resolver`.

type QueryLoggingResolver

type QueryLoggingResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

QueryLoggingResolver writes query information (question, answer, duration, ...)

func NewQueryLoggingResolver

func NewQueryLoggingResolver(ctx context.Context, cfg config.QueryLog) (*QueryLoggingResolver, error)

NewQueryLoggingResolver returns a new resolver instance

func (*QueryLoggingResolver) IsEnabled

func (c *QueryLoggingResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*QueryLoggingResolver) LogConfig

func (c *QueryLoggingResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*QueryLoggingResolver) Resolve

func (r *QueryLoggingResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

Resolve logs the query, duration and the result

func (*QueryLoggingResolver) String

func (t *QueryLoggingResolver) String() string

String implements `fmt.Stringer`.

func (*QueryLoggingResolver) Type

func (t *QueryLoggingResolver) Type() string

Type implements `Resolver`.

type Resolver

type Resolver interface {
	config.Configurable
	fmt.Stringer

	// Type returns a short, user-friendly, name for the resolver.
	//
	// It should be the same for all instances of a specific Resolver type.
	Type() string

	// Resolve performs resolution of a DNS request
	Resolve(ctx context.Context, req *model.Request) (*model.Response, error)
}

Resolver generic interface for all resolvers

func NewUpstreamTreeResolver

func NewUpstreamTreeResolver(ctx context.Context, cfg config.Upstreams, bootstrap *Bootstrap) (Resolver, error)

type SpecialUseDomainNamesResolver

type SpecialUseDomainNamesResolver struct {
	NextResolver
	// contains filtered or unexported fields
}

func NewSpecialUseDomainNamesResolver

func NewSpecialUseDomainNamesResolver(cfg config.SUDN) *SpecialUseDomainNamesResolver

func (*SpecialUseDomainNamesResolver) IsEnabled

func (c *SpecialUseDomainNamesResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*SpecialUseDomainNamesResolver) LogConfig

func (c *SpecialUseDomainNamesResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*SpecialUseDomainNamesResolver) Resolve

func (*SpecialUseDomainNamesResolver) String

func (t *SpecialUseDomainNamesResolver) String() string

String implements `fmt.Stringer`.

func (*SpecialUseDomainNamesResolver) Type

func (t *SpecialUseDomainNamesResolver) Type() string

Type implements `Resolver`.

type StrictResolver

type StrictResolver struct {
	// contains filtered or unexported fields
}

StrictResolver delegates the DNS message strictly to the first configured upstream resolver if it can't provide the answer in time the next resolver is used

func NewStrictResolver

func NewStrictResolver(
	ctx context.Context, cfg config.UpstreamGroup, bootstrap *Bootstrap,
) (*StrictResolver, error)

NewStrictResolver creates a new strict resolver instance

func (*StrictResolver) IsEnabled

func (c *StrictResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*StrictResolver) LogConfig

func (c *StrictResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*StrictResolver) Name

func (r *StrictResolver) Name() string

func (*StrictResolver) Resolve

func (r *StrictResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

Resolve sends the query request in a strict order to the upstream resolvers

func (*StrictResolver) String

func (r *StrictResolver) String() string

func (*StrictResolver) Type

func (t *StrictResolver) Type() string

Type implements `Resolver`.

type TrustAnchor added in v0.28.0

type TrustAnchor struct {
	Key *dns.DNSKEY
}

TrustAnchor represents a DNSSEC trust anchor (DNSKEY record)

type TrustAnchorStore added in v0.28.0

type TrustAnchorStore struct {
	// contains filtered or unexported fields
}

TrustAnchorStore manages DNSSEC trust anchors

func NewTrustAnchorStore added in v0.28.0

func NewTrustAnchorStore(customAnchors []string) (*TrustAnchorStore, error)

NewTrustAnchorStore creates a new trust anchor store with the given trust anchors.

If customAnchors is empty, the default root KSK trust anchors from IANA are used. Custom anchors should be DNSKEY records in zone file format, with the SEP (KSK) flag set.

Example anchor format:

". 172800 IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvk..."

Parameters:

  • customAnchors: List of DNSKEY record strings to use as trust anchors (optional)

Returns a configured trust anchor store or an error if any anchor is invalid.

func (*TrustAnchorStore) AddTrustAnchor added in v0.28.0

func (s *TrustAnchorStore) AddTrustAnchor(anchorStr string) error

AddTrustAnchor adds a trust anchor from a DNSKEY record string

func (*TrustAnchorStore) GetRootTrustAnchors added in v0.28.0

func (s *TrustAnchorStore) GetRootTrustAnchors() []*TrustAnchor

GetRootTrustAnchors returns trust anchors for the root zone

func (*TrustAnchorStore) GetTrustAnchors added in v0.28.0

func (s *TrustAnchorStore) GetTrustAnchors(domain string) []*TrustAnchor

GetTrustAnchors returns trust anchors for a domain

func (*TrustAnchorStore) HasTrustAnchor added in v0.28.0

func (s *TrustAnchorStore) HasTrustAnchor(domain string) bool

HasTrustAnchor returns true if the store has a trust anchor for the domain

type UpstreamResolver

type UpstreamResolver struct {
	// contains filtered or unexported fields
}

UpstreamResolver sends request to external DNS server

func NewUpstreamResolver

func NewUpstreamResolver(
	ctx context.Context, cfg upstreamConfig, bootstrap *Bootstrap,
) (*UpstreamResolver, error)

NewUpstreamResolver creates new resolver instance

func (*UpstreamResolver) IsEnabled

func (c *UpstreamResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*UpstreamResolver) LogConfig

func (c *UpstreamResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*UpstreamResolver) Resolve

func (r *UpstreamResolver) Resolve(ctx context.Context, request *model.Request) (response *model.Response, err error)

Resolve calls external resolver

func (UpstreamResolver) String

func (r UpstreamResolver) String() string

func (*UpstreamResolver) Type

func (t *UpstreamResolver) Type() string

Type implements `Resolver`.

func (UpstreamResolver) Upstream

func (r UpstreamResolver) Upstream() config.Upstream

type UpstreamServerError

type UpstreamServerError struct {
	Msg *dns.Msg
}

UpstreamServerError wraps a response with RCode ServFail so no other resolver tries to use it.

func (*UpstreamServerError) Error

func (e *UpstreamServerError) Error() string

type UpstreamTreeResolver

type UpstreamTreeResolver struct {
	// contains filtered or unexported fields
}

func (*UpstreamTreeResolver) IsEnabled

func (c *UpstreamTreeResolver) IsEnabled() bool

IsEnabled implements `config.Configurable`.

func (*UpstreamTreeResolver) LogConfig

func (c *UpstreamTreeResolver) LogConfig(logger *logrus.Entry)

LogConfig implements `config.Configurable`.

func (*UpstreamTreeResolver) Name

func (r *UpstreamTreeResolver) Name() string

func (*UpstreamTreeResolver) Resolve

func (r *UpstreamTreeResolver) Resolve(ctx context.Context, request *model.Request) (*model.Response, error)

func (*UpstreamTreeResolver) String

func (r *UpstreamTreeResolver) String() string

func (*UpstreamTreeResolver) Type

func (t *UpstreamTreeResolver) Type() string

Type implements `Resolver`.

type ValidationResult added in v0.28.0

type ValidationResult int

ValidationResult represents the result of DNSSEC validation ENUM( Secure // Valid DNSSEC signatures and chain of trust Insecure // No DNSSEC (unsigned zone) Bogus // Invalid DNSSEC (failed validation) Indeterminate // Validation could not be completed )

const (
	// ValidationResultSecure is a ValidationResult of type Secure.
	// Valid DNSSEC signatures and chain of trust
	ValidationResultSecure ValidationResult = iota
	// ValidationResultInsecure is a ValidationResult of type Insecure.
	// No DNSSEC (unsigned zone)
	ValidationResultInsecure
	// ValidationResultBogus is a ValidationResult of type Bogus.
	// Invalid DNSSEC (failed validation)
	ValidationResultBogus
	// ValidationResultIndeterminate is a ValidationResult of type Indeterminate.
	// Validation could not be completed
	ValidationResultIndeterminate
)

func ParseValidationResult added in v0.28.0

func ParseValidationResult(name string) (ValidationResult, error)

ParseValidationResult attempts to convert a string to a ValidationResult.

func ValidationResultValues added in v0.28.0

func ValidationResultValues() []ValidationResult

ValidationResultValues returns a list of the values for ValidationResult

func (*ValidationResult) AppendText added in v0.28.0

func (x *ValidationResult) AppendText(b []byte) ([]byte, error)

AppendText appends the textual representation of itself to the end of b (allocating a larger slice if necessary) and returns the updated slice.

Implementations must not retain b, nor mutate any bytes within b[:len(b)].

func (ValidationResult) IsValid added in v0.28.0

func (x ValidationResult) IsValid() bool

IsValid provides a quick way to determine if the typed value is part of the allowed enumerated values

func (ValidationResult) MarshalText added in v0.28.0

func (x ValidationResult) MarshalText() ([]byte, error)

MarshalText implements the text marshaller method.

func (ValidationResult) String added in v0.28.0

func (x ValidationResult) String() string

String implements the Stringer interface.

func (*ValidationResult) UnmarshalText added in v0.28.0

func (x *ValidationResult) UnmarshalText(text []byte) error

UnmarshalText implements the text unmarshaller method.

Directories

Path Synopsis
Package dnssec implements DNSSEC validation per RFC 4033, 4034, 4035, and 5155.
Package dnssec implements DNSSEC validation per RFC 4033, 4034, 4035, and 5155.

Jump to

Keyboard shortcuts

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