adns

package module
v0.0.0-...-2a1aacf Latest Latest
Warning

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

Go to latest
Published: Mar 9, 2024 License: BSD-3-Clause Imports: 21 Imported by: 10

README

adns - copy of pure Go resolver from Go standard library, with modifications to facilitate use with DNSSEC.

Documentation: https://pkg.go.dev/github.com/mjl-/adns

License: Go's BSD license, see LICENSE.

Documentation

Overview

adns is a copy of the Go standard library, modified to provide details about the DNSSEC status of responses.

The MX, NS, SRV types from the "net" package are used to make to prevent churn when switching from net to adns.

Modifications

  • Each Lookup* also returns a Result with the "Authentic" field representing if the response had the "authentic data" bit (and is trusted), i.e. was DNSSEC-signed according to the recursive resolver.
  • Resolver are also trusted if all name servers have loopback IPs. Resolvers are still also trusted if /etc/resolv.conf has "trust-ad" in the "options".
  • New function LookupTLSA, to support DANE which uses DNS records of type TLSA.
  • Support Extended DNS Errors (EDE) for details about DNSSEC errors.
  • adns uses its own DNSError type, with an additional "Underlying error" field and Unwrap function, so callers can check for the new ExtendedError type.

Index

Constants

This section is empty.

Variables

View Source
var DefaultResolver = &Resolver{}

DefaultResolver is the resolver used by the package-level Lookup functions and by Dialers without a specified Resolver.

Functions

func JoinHostPort

func JoinHostPort(host, port string) string

JoinHostPort combines host and port into a network address of the form "host:port". If host contains a colon, as found in literal IPv6 addresses, then JoinHostPort returns "[host]:port".

See func Dial for a description of the host and port parameters.

func LookupPort

func LookupPort(network, service string) (port int, err error)

LookupPort looks up the port for the given network and service.

LookupPort uses context.Background internally; to specify the context, use Resolver.LookupPort.

func LookupTLSA

func LookupTLSA(port int, protocol, host string) ([]TLSA, Result, error)

LookupTLSA calls LookupTLSA on the DefaultResolver.

func SplitHostPort

func SplitHostPort(hostport string) (host, port string, err error)

SplitHostPort splits a network address of the form "host:port", "host%zone:port", "[host]:port" or "[host%zone]:port" into host or host%zone and port.

A literal IPv6 address in hostport must be enclosed in square brackets, as in "[::1]:80", "[::1%lo0]:80".

See func Dial for a description of the hostport parameter, and host and port results.

Types

type DNSError

type DNSError struct {
	Underlying  error  // Underlying error, could be an ExtendedError.
	Err         string // description of the error
	Name        string // name looked for
	Server      string // server used
	IsTimeout   bool   // if true, timed out; not all timeouts set this
	IsTemporary bool   // if true, error is temporary; not all errors set this

	// IsNotFound is set to true when the requested name does not
	// contain any records of the requested type (data not found),
	// or the name itself was not found (NXDOMAIN).
	IsNotFound bool
}

DNSError represents a DNS lookup error.

func (*DNSError) Error

func (e *DNSError) Error() string

func (*DNSError) Temporary

func (e *DNSError) Temporary() bool

Temporary reports whether the DNS error is known to be temporary. This is not always known; a DNS lookup may fail due to a temporary error and return a DNSError for which Temporary returns false.

func (*DNSError) Timeout

func (e *DNSError) Timeout() bool

Timeout reports whether the DNS lookup is known to have timed out. This is not always known; a DNS lookup may fail due to a timeout and return a DNSError for which Timeout returns false.

func (*DNSError) Unwrap

func (e *DNSError) Unwrap() error

Unwrap returns the underlying error, which could be an ExtendedError.

type ErrorCode

type ErrorCode uint16

ErrorCode is an InfoCode from Extended DNS Errors, RFC 8914.

const (
	ErrOtherErrorCode             ErrorCode = 0
	ErrUnsupportedDNSKEYAlgorithm ErrorCode = 1
	ErrUnsupportedDSDigestType    ErrorCode = 2
	ErrStaleAnswer                ErrorCode = 3
	ErrForgedAnswer               ErrorCode = 4
	ErrDNSSECIndeterminate        ErrorCode = 5
	ErrDNSSECBogus                ErrorCode = 6
	ErrSignatureExpired           ErrorCode = 7
	ErrSignatureNotYetValid       ErrorCode = 8
	ErrDNSKEYMissing              ErrorCode = 9
	ErrRRSIGMissing               ErrorCode = 10
	ErrNoZoneKeyBitSet            ErrorCode = 11
	ErrNSECMissing                ErrorCode = 12
	ErrCachedError                ErrorCode = 13
	ErrNotReady                   ErrorCode = 14
	ErrBlocked                    ErrorCode = 15
	ErrCensored                   ErrorCode = 16
	ErrFiltered                   ErrorCode = 17
	ErrProhibited                 ErrorCode = 18
	ErrStaleNXDOMAINAnswer        ErrorCode = 19
	ErrNotAuthoritative           ErrorCode = 20
	ErrNotSupported               ErrorCode = 21
	ErrNoReachableAuthority       ErrorCode = 22
	ErrNetworkError               ErrorCode = 23
	ErrInvalidData                ErrorCode = 24
)

func (ErrorCode) Error

func (e ErrorCode) Error() string

Error includes a human-readable short string for the info code.

func (ErrorCode) IsAuthentication

func (e ErrorCode) IsAuthentication() bool

IsAuthentication returns whether the error is related to authentication, e.g. bogus DNSSEC, missing DS/DNSKEY/RRSIG records, etc, or an other DNSSEC-related error.

func (ErrorCode) IsTemporary

func (e ErrorCode) IsTemporary() bool

IsTemporary returns whether the error is temporary and has a chance of succeeding on a retry.

func (ErrorCode) String

func (e ErrorCode) String() string

String returns a short text string for known error codes, or "unknown".

type ExtendedError

type ExtendedError struct {
	InfoCode  ErrorCode
	ExtraText string // Human-readable error message, optional.
}

ExtendedError is an RFC 8914 Extended DNS Error (EDE).

func (ExtendedError) Error

func (e ExtendedError) Error() string

Error returns a string representing the InfoCode, and either the extra text or more details for the info code.

func (ExtendedError) IsTemporary

func (e ExtendedError) IsTemporary() bool

IsTemporary indicates whether an error is a temporary server error, and retries might give a different result.

func (ExtendedError) Unwrap

func (e ExtendedError) Unwrap() error

Unwrap returns the underlying ErrorCode error.

type Resolver

type Resolver struct {
	// PreferGo controls whether Go's built-in DNS resolver is preferred
	// on platforms where it's available. It is equivalent to setting
	// GODEBUG=netdns=go, but scoped to just this resolver.
	PreferGo bool

	// StrictErrors controls the behavior of temporary errors
	// (including timeout, socket errors, and SERVFAIL) when using
	// Go's built-in resolver. For a query composed of multiple
	// sub-queries (such as an A+AAAA address lookup, or walking the
	// DNS search list), this option causes such errors to abort the
	// whole query instead of returning a partial result. This is
	// not enabled by default because it may affect compatibility
	// with resolvers that process AAAA queries incorrectly.
	StrictErrors bool

	// Dial optionally specifies an alternate dialer for use by
	// Go's built-in DNS resolver to make TCP and UDP connections
	// to DNS services. The host in the address parameter will
	// always be a literal IP address and not a host name, and the
	// port in the address parameter will be a literal port number
	// and not a service name.
	// If the Conn returned is also a PacketConn, sent and received DNS
	// messages must adhere to RFC 1035 section 4.2.1, "UDP usage".
	// Otherwise, DNS messages transmitted over Conn must adhere
	// to RFC 7766 section 5, "Transport Protocol Selection".
	// If nil, the default dialer is used.
	Dial func(ctx context.Context, network, address string) (net.Conn, error)
	// contains filtered or unexported fields
}

A Resolver looks up names and numbers.

A nil *Resolver is equivalent to a zero Resolver.

func (*Resolver) LookupAddr

func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, Result, error)

LookupAddr performs a reverse lookup for the given address, returning a list of names mapping to that address.

The returned names are validated to be properly formatted presentation-format domain names. If the response contains invalid names, those records are filtered out and an error will be returned alongside the remaining results, if any.

func (*Resolver) LookupCNAME

func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, Result, error)

LookupCNAME returns the canonical name for the given host. Callers that do not care about the canonical name can call LookupHost or LookupIP directly; both take care of resolving the canonical name as part of the lookup.

A canonical name is the final name after following zero or more CNAME records. LookupCNAME does not return an error if host does not contain DNS "CNAME" records, as long as host resolves to address records.

The returned canonical name is validated to be a properly formatted presentation-format domain name.

func (*Resolver) LookupHost

func (r *Resolver) LookupHost(ctx context.Context, host string) (addrs []string, result Result, err error)

LookupHost looks up the given host using the local resolver. It returns a slice of that host's addresses.

func (*Resolver) LookupIP

func (r *Resolver) LookupIP(ctx context.Context, network, host string) ([]net.IP, Result, error)

LookupIP looks up host for the given network using the local resolver. It returns a slice of that host's IP addresses of the type specified by network. network must be one of "ip", "ip4" or "ip6".

func (*Resolver) LookupIPAddr

func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]net.IPAddr, Result, error)

LookupIPAddr looks up host using the local resolver. It returns a slice of that host's IPv4 and IPv6 addresses.

func (*Resolver) LookupMX

func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*net.MX, Result, error)

LookupMX returns the DNS MX records for the given domain name sorted by preference.

The returned mail server names are validated to be properly formatted presentation-format domain names. If the response contains invalid names, those records are filtered out and an error will be returned alongside the remaining results, if any.

func (*Resolver) LookupNS

func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*net.NS, Result, error)

LookupNS returns the DNS NS records for the given domain name.

The returned name server names are validated to be properly formatted presentation-format domain names. If the response contains invalid names, those records are filtered out and an error will be returned alongside the remaining results, if any.

func (*Resolver) LookupNetIP

func (r *Resolver) LookupNetIP(ctx context.Context, network, host string) ([]netip.Addr, Result, error)

LookupNetIP looks up host using the local resolver. It returns a slice of that host's IP addresses of the type specified by network. The network must be one of "ip", "ip4" or "ip6".

func (*Resolver) LookupPort

func (r *Resolver) LookupPort(ctx context.Context, network, service string) (port int, err error)

LookupPort looks up the port for the given network and service.

The network must be one of "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6" or "ip".

func (*Resolver) LookupSRV

func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*net.SRV, Result, error)

LookupSRV tries to resolve an SRV query of the given service, protocol, and domain name. The proto is "tcp" or "udp". The returned records are sorted by priority and randomized by weight within a priority.

LookupSRV constructs the DNS name to look up following RFC 2782. That is, it looks up _service._proto.name. To accommodate services publishing SRV records under non-standard names, if both service and proto are empty strings, LookupSRV looks up name directly.

The returned service names are validated to be properly formatted presentation-format domain names. If the response contains invalid names, those records are filtered out and an error will be returned alongside the remaining results, if any.

func (*Resolver) LookupTLSA

func (r *Resolver) LookupTLSA(ctx context.Context, port int, protocol, host string) (records []TLSA, result Result, err error)

LookupTLSA looks up a TLSA (TLS association) record for the port (service) and protocol (e.g. tcp, udp) at the host.

LookupTLSA looks up DNS name "_<port>._<protocol>.host". Except when port is 0 and protocol the empty string, then host is directly used to look up the TLSA record.

Callers must check the Authentic field of the Result before using a TLSA record.

Callers may want to handle DNSError with NotFound set to true (i.e. "nxdomain") differently from other errors. DANE support is often optional, with protocol-specific fallback behaviour.

LookupTLSA follows CNAME records. For DANE, the secure/insecure DNSSEC response must be taken into account when following CNAMEs to determine the TLSA base domains. Callers should probably first resolve CNAMEs explicitly for their (in)secure status.

func (*Resolver) LookupTXT

func (r *Resolver) LookupTXT(ctx context.Context, name string) ([]string, Result, error)

LookupTXT returns the DNS TXT records for the given domain name.

type Result

type Result struct {
	// Authentic indicates whether the response was DNSSEC-signed and verified.
	// This package is a security-aware non-validating stub-resolver, sending requests
	// with the "authentic data" bit set to its recursive resolvers, but only if the
	// resolvers are trusted. Resolvers are trusted either if explicitly marked with
	// "options trust-ad" in /etc/resolv.conf, or if all resolver IP addresses are
	// loopback IP's. If the response from the resolver has the "authentic data" bit
	// set, the DNS name and all indirections towards the name, were signed and the
	// recursive resolver has verified them.
	Authentic bool
}

Result has additional information about a DNS lookup.

func LookupAddr

func LookupAddr(addr string) (names []string, result Result, err error)

LookupAddr performs a reverse lookup for the given address, returning a list of names mapping to that address.

The returned names are validated to be properly formatted presentation-format domain names. If the response contains invalid names, those records are filtered out and an error will be returned alongside the remaining results, if any.

When using the host C library resolver, at most one result will be returned. To bypass the host resolver, use a custom Resolver.

LookupAddr uses context.Background internally; to specify the context, use Resolver.LookupAddr.

func LookupCNAME

func LookupCNAME(host string) (cname string, result Result, err error)

LookupCNAME returns the canonical name for the given host. Callers that do not care about the canonical name can call LookupHost or LookupIP directly; both take care of resolving the canonical name as part of the lookup.

A canonical name is the final name after following zero or more CNAME records. LookupCNAME does not return an error if host does not contain DNS "CNAME" records, as long as host resolves to address records.

The returned canonical name is validated to be a properly formatted presentation-format domain name.

LookupCNAME uses context.Background internally; to specify the context, use Resolver.LookupCNAME.

func LookupHost

func LookupHost(host string) (addrs []string, result Result, err error)

LookupHost looks up the given host using the local resolver. It returns a slice of that host's addresses.

LookupHost uses context.Background internally; to specify the context, use Resolver.LookupHost.

func LookupIP

func LookupIP(host string) ([]net.IP, Result, error)

LookupIP looks up host using the local resolver. It returns a slice of that host's IPv4 and IPv6 addresses.

func LookupMX

func LookupMX(name string) ([]*net.MX, Result, error)

LookupMX returns the DNS MX records for the given domain name sorted by preference.

The returned mail server names are validated to be properly formatted presentation-format domain names. If the response contains invalid names, those records are filtered out and an error will be returned alongside the remaining results, if any.

LookupMX uses context.Background internally; to specify the context, use Resolver.LookupMX.

func LookupNS

func LookupNS(name string) ([]*net.NS, Result, error)

LookupNS returns the DNS NS records for the given domain name.

The returned name server names are validated to be properly formatted presentation-format domain names. If the response contains invalid names, those records are filtered out and an error will be returned alongside the remaining results, if any.

LookupNS uses context.Background internally; to specify the context, use Resolver.LookupNS.

func LookupSRV

func LookupSRV(service, proto, name string) (cname string, addrs []*net.SRV, result Result, err error)

LookupSRV tries to resolve an SRV query of the given service, protocol, and domain name. The proto is "tcp" or "udp". The returned records are sorted by priority and randomized by weight within a priority.

LookupSRV constructs the DNS name to look up following RFC 2782. That is, it looks up _service._proto.name. To accommodate services publishing SRV records under non-standard names, if both service and proto are empty strings, LookupSRV looks up name directly.

The returned service names are validated to be properly formatted presentation-format domain names. If the response contains invalid names, those records are filtered out and an error will be returned alongside the remaining results, if any.

func LookupTXT

func LookupTXT(name string) ([]string, Result, error)

LookupTXT returns the DNS TXT records for the given domain name.

LookupTXT uses context.Background internally; to specify the context, use Resolver.LookupTXT.

type TLSA

type TLSA struct {
	Usage     TLSAUsage     // Which validations must be performed.
	Selector  TLSASelector  // What needs to be validated (full certificate or only public key).
	MatchType TLSAMatchType // In which form the certificate/public key is stored in CertAssoc.
	CertAssoc []byte        // Certificate association data.
}

TLSA represents a TLSA DNS record.

func (TLSA) Record

func (r TLSA) Record() string

Record returns a TLSA record value for inclusion in DNS. For example:

3 1 1 133b919c9d65d8b1488157315327334ead8d83372db57465ecabf53ee5748aee

A full record in a zone file may look like this:

_25._tcp.example.com. IN TLSA 3 1 1 133b919c9d65d8b1488157315327334ead8d83372db57465ecabf53ee5748aee

This record is dane-ee (3), spki (1), sha2-256 (1), and the hexadecimal data is the sha2-256 hash.

func (TLSA) String

func (r TLSA) String() string

String is like Record but prints both the acronym and code for each field.

type TLSAMatchType

type TLSAMatchType uint8

TLSAMatchType indicates in which form the data as indicated by the selector is stored in the record as certificate association.

const (
	// Full data, e.g. a full DER-encoded SPKI or even certificate.
	TLSAMatchTypeFull TLSAMatchType = 0
	// SHA2-256-hashed data, either SPKI or certificate.
	TLSAMatchTypeSHA256 TLSAMatchType = 1
	// SHA2-512-hashed data.
	TLSAMatchTypeSHA512 TLSAMatchType = 2
)

func (TLSAMatchType) String

func (mt TLSAMatchType) String() string

String returns the lower-case acronym of a match type, or "(unknown)" for unrecognized values.

type TLSASelector

type TLSASelector uint8

TLSASelecter indicates the data the "certificate association" field is based on.

const (
	// DER-encoded x509 certificate.
	TLSASelectorCert TLSASelector = 0
	// DER-encoded subject public key info (SPKI), so only the public key and its type.
	TLSASelectorSPKI TLSASelector = 1
)

func (TLSASelector) String

func (s TLSASelector) String() string

String returns the lower-case acronym of a selector, or "(unknown)" for unrecognized values.

type TLSAUsage

type TLSAUsage uint8

TLSAUsage indicates which certificate/public key verification must be done.

const (
	// PKIX/WebPKI, certificate must be valid (name, expiry, signed by CA, etc) and
	// signed by the trusted-anchor (TA) in this record.
	TLSAUsagePKIXTA TLSAUsage = 0
	// PKIX/WebPKI, certificate must be valid (name, expiry, signed by CA, etc) and
	// match the certificate in the record.
	TLSAUsagePKIXEE TLSAUsage = 1
	// Certificate must be signed by trusted-anchor referenced in record, with matching
	// name, non-expired, etc.
	TLSAUsageDANETA TLSAUsage = 2
	// Certificate must match the record. No further requirements on name, expiration
	// or who signed it.
	TLSAUsageDANEEE TLSAUsage = 3
)

func (TLSAUsage) String

func (u TLSAUsage) String() string

String returns the lower-case acronym of a usage, or "(unknown)" for unrecognized values.

Notes

Bugs

  • On DragonFly BSD and OpenBSD, listening on the "tcp" and "udp" networks does not listen for both IPv4 and IPv6 connections. This is due to the fact that IPv4 traffic will not be routed to an IPv6 socket - two separate sockets are required if both address families are to be supported. See inet6(4) for details.

Directories

Path Synopsis
internal
singleflight
Package singleflight provides a duplicate function call suppression mechanism.
Package singleflight provides a duplicate function call suppression mechanism.
testenv
Package testenv provides information about what functionality is available in different testing environments run by the Go team.
Package testenv provides information about what functionality is available in different testing environments run by the Go team.

Jump to

Keyboard shortcuts

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