Documentation ¶
Overview ¶
Package dnsforward contains a DNS forwarding server.
Index ¶
- Constants
- func IsCommentOrEmpty(s string) (ok bool)
- func UpstreamHTTPVersions(http3 bool) (v []upstream.HTTPVersion)
- func ValidateClientID(id string) (err error)
- type ClientsContainer
- type Config
- type DHCP
- type DNSCreateParams
- type DNSCryptConfig
- type EDNSClientSubnet
- type PrivateRDNSError
- type Server
- func (s *Server) AddrProcConfig() (c *client.DefaultAddrProcConfig)
- func (s *Server) Close()
- func (s *Server) DialContext(ctx context.Context, network, addr string) (conn net.Conn, err error)
- func (s *Server) Exchange(ip netip.Addr) (host string, ttl time.Duration, err error)
- func (s *Server) HandleBefore(_ *proxy.Proxy, pctx *proxy.DNSContext) (err error)
- func (s *Server) IsBlockedClient(ip netip.Addr, clientID string) (blocked bool, rule string)
- func (s *Server) IsRunning() bool
- func (s *Server) LocalPTRResolvers() (localPTRResolvers []string)
- func (s *Server) NewMsgNODATA(req *dns.Msg) (resp *dns.Msg)
- func (s *Server) NewMsgNOTIMPLEMENTED(req *dns.Msg) (resp *dns.Msg)
- func (s *Server) NewMsgNXDOMAIN(req *dns.Msg) (resp *dns.Msg)
- func (s *Server) NewMsgSERVFAIL(req *dns.Msg) (resp *dns.Msg)
- func (s *Server) Prepare(conf *ServerConfig) (err error)
- func (s *Server) Reconfigure(conf *ServerConfig) error
- func (s *Server) Resolve(ctx context.Context, net, host string) (addr []netip.Addr, err error)
- func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (s *Server) Start() error
- func (s *Server) Stop() error
- func (s *Server) UpdatedProtectionStatus() (enabled bool, disabledUntil *time.Time)
- func (s *Server) WriteDiskConfig(c *Config)
- type ServerConfig
- type SystemResolvers
- type TLSConfig
- type UpstreamMode
Constants ¶
const ( // ErrRDNSNoData is returned by [RDNSExchanger.Exchange] when the answer // section of response is either NODATA or has no PTR records. ErrRDNSNoData errors.Error = "no ptr data in response" // ErrRDNSFailed is returned by [RDNSExchanger.Exchange] if the received // response is not a NOERROR or NXDOMAIN. ErrRDNSFailed errors.Error = "failed to resolve ptr" )
const DefaultTimeout = 10 * time.Second
DefaultTimeout is the default upstream timeout
Variables ¶
This section is empty.
Functions ¶
func IsCommentOrEmpty ¶
IsCommentOrEmpty returns true if s starts with a "#" character or is empty. This function is useful for filtering out non-upstream lines from upstream configs.
func UpstreamHTTPVersions ¶
func UpstreamHTTPVersions(http3 bool) (v []upstream.HTTPVersion)
UpstreamHTTPVersions returns the HTTP versions for upstream configuration depending on configuration.
func ValidateClientID ¶
ValidateClientID returns an error if id is not a valid ClientID.
Keep in sync with client.ValidateClientID.
Types ¶
type ClientsContainer ¶
type ClientsContainer interface { // UpstreamConfigByID returns the custom upstream configuration for the // client having id, using boot to initialize the one if necessary. It // returns nil if there is no custom upstream configuration for the client. // The id is expected to be either a string representation of an IP address // or the ClientID. UpstreamConfigByID( id string, boot upstream.Resolver, ) (conf *proxy.CustomUpstreamConfig, err error) }
ClientsContainer provides information about preconfigured DNS clients.
type Config ¶
type Config struct { // FilterHandler is an optional additional filtering callback. FilterHandler func(cliAddr netip.Addr, clientID string, settings *filtering.Settings) `yaml:"-"` // ClientsContainer stores the information about special handling of some // DNS clients. ClientsContainer ClientsContainer `yaml:"-"` // Ratelimit is the maximum number of requests per second from a given IP // (0 to disable). Ratelimit uint32 `yaml:"ratelimit"` // RatelimitSubnetLenIPv4 is a subnet length for IPv4 addresses used for // rate limiting requests. RatelimitSubnetLenIPv4 int `yaml:"ratelimit_subnet_len_ipv4"` // RatelimitSubnetLenIPv6 is a subnet length for IPv6 addresses used for // rate limiting requests. RatelimitSubnetLenIPv6 int `yaml:"ratelimit_subnet_len_ipv6"` // RatelimitWhitelist is the list of whitelisted client IP addresses. RatelimitWhitelist []netip.Addr `yaml:"ratelimit_whitelist"` // RefuseAny, if true, refuse ANY requests. RefuseAny bool `yaml:"refuse_any"` // UpstreamDNS is the list of upstream DNS servers. UpstreamDNS []string `yaml:"upstream_dns"` // UpstreamDNSFileName, if set, points to the file which contains upstream // DNS servers. UpstreamDNSFileName string `yaml:"upstream_dns_file"` // BootstrapDNS is the list of bootstrap DNS servers for DoH and DoT // resolvers (plain DNS only). BootstrapDNS []string `yaml:"bootstrap_dns"` // FallbackDNS is the list of fallback DNS servers used when upstream DNS // servers are not responding. FallbackDNS []string `yaml:"fallback_dns"` // UpstreamMode determines the logic through which upstreams will be used. UpstreamMode UpstreamMode `yaml:"upstream_mode"` // FastestTimeout replaces the default timeout for dialing IP addresses // when FastestAddr is true. FastestTimeout timeutil.Duration `yaml:"fastest_timeout"` // AllowedClients is the slice of IP addresses, CIDR networks, and // ClientIDs of allowed clients. If not empty, only these clients are // allowed, and [Config.DisallowedClients] are ignored. AllowedClients []string `yaml:"allowed_clients"` // DisallowedClients is the slice of IP addresses, CIDR networks, and // ClientIDs of disallowed clients. DisallowedClients []string `yaml:"disallowed_clients"` // BlockedHosts is the list of hosts that should be blocked. BlockedHosts []string `yaml:"blocked_hosts"` // TrustedProxies is the list of CIDR networks with proxy servers addresses // from which the DoH requests should be handled. The value of nil or an // empty slice for this field makes Proxy not trust any address. TrustedProxies []netutil.Prefix `yaml:"trusted_proxies"` // CacheSize is the DNS cache size (in bytes). CacheSize uint32 `yaml:"cache_size"` // CacheMinTTL is the override TTL value (minimum) received from upstream // server. CacheMinTTL uint32 `yaml:"cache_ttl_min"` // CacheMaxTTL is the override TTL value (maximum) received from upstream // server. CacheMaxTTL uint32 `yaml:"cache_ttl_max"` // CacheOptimistic defines if optimistic cache mechanism should be used. CacheOptimistic bool `yaml:"cache_optimistic"` // BogusNXDomain is the list of IP addresses, responses with them will be // transformed to NXDOMAIN. BogusNXDomain []string `yaml:"bogus_nxdomain"` // AAAADisabled, if true, respond with an empty answer to all AAAA // requests. AAAADisabled bool `yaml:"aaaa_disabled"` // EnableDNSSEC, if true, set AD flag in outcoming DNS request. EnableDNSSEC bool `yaml:"enable_dnssec"` // EDNSClientSubnet is the settings list for EDNS Client Subnet. EDNSClientSubnet *EDNSClientSubnet `yaml:"edns_client_subnet"` // MaxGoroutines is the max number of parallel goroutines for processing // incoming requests. MaxGoroutines uint `yaml:"max_goroutines"` // HandleDDR, if true, handle DDR requests HandleDDR bool `yaml:"handle_ddr"` // IpsetList is the ipset configuration that allows AdGuard Home to add IP // addresses of the specified domain names to an ipset list. Syntax: // // DOMAIN[,DOMAIN].../IPSET_NAME[,IPSET_NAME]... // // This field is ignored if [IpsetListFileName] is set. IpsetList []string `yaml:"ipset"` // IpsetListFileName, if set, points to the file with ipset configuration. // The format is the same as in [IpsetList]. IpsetListFileName string `yaml:"ipset_file"` // BootstrapPreferIPv6, if true, instructs the bootstrapper to prefer IPv6 // addresses to IPv4 ones for DoH, DoQ, and DoT. BootstrapPreferIPv6 bool `yaml:"bootstrap_prefer_ipv6"` }
Config represents the DNS filtering configuration of AdGuard Home. The zero Config is empty and ready for use.
type DHCP ¶
type DHCP interface { // HostByIP returns the hostname of the DHCP client with the given IP // address. The address will be netip.Addr{} if there is no such client, // due to an assumption that a DHCP client must always have an IP address. HostByIP(ip netip.Addr) (host string) // IPByHost returns the IP address of the DHCP client with the given // hostname. The hostname will be an empty string if there is no such // client, due to an assumption that a DHCP client must always have a // hostname, either set by the client or assigned automatically. IPByHost(host string) (ip netip.Addr) // Enabled returns true if DHCP provides information about clients. Enabled() (ok bool) }
DHCP is an interface for accessing DHCP lease data needed in this package.
type DNSCreateParams ¶
type DNSCreateParams struct { DNSFilter *filtering.DNSFilter Stats stats.Interface QueryLog querylog.QueryLog DHCPServer DHCP PrivateNets netutil.SubnetSet Anonymizer *aghnet.IPMut EtcHosts *aghnet.HostsContainer // Logger is used as a base logger. It must not be nil. Logger *slog.Logger LocalDomain string }
DNSCreateParams are parameters to create a new server.
type DNSCryptConfig ¶
type DNSCryptConfig struct { ResolverCert *dnscrypt.Cert ProviderName string UDPListenAddrs []*net.UDPAddr TCPListenAddrs []*net.TCPAddr Enabled bool }
DNSCryptConfig is the DNSCrypt server configuration struct.
type EDNSClientSubnet ¶
type EDNSClientSubnet struct { // CustomIP for EDNS Client Subnet. CustomIP netip.Addr `yaml:"custom_ip"` // Enabled defines if EDNS Client Subnet is enabled. Enabled bool `yaml:"enabled"` // UseCustom defines if CustomIP should be used. UseCustom bool `yaml:"use_custom"` }
EDNSClientSubnet is the settings list for EDNS Client Subnet.
type PrivateRDNSError ¶
type PrivateRDNSError struct {
// contains filtered or unexported fields
}
PrivateRDNSError is returned when the private rDNS upstreams are invalid but enabled.
TODO(e.burkov): Consider allowing to use incomplete private rDNS upstreams configuration in proxy when the private rDNS function is enabled. In theory, proxy supports the case when no upstreams provided to resolve the private request, since it already supports this for DNS64-prefixed PTR requests.
func (*PrivateRDNSError) Error ¶
func (e *PrivateRDNSError) Error() (s string)
Error implements the errors.Error interface.
func (*PrivateRDNSError) Unwrap ¶
func (e *PrivateRDNSError) Unwrap() (err error)
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is the main way to start a DNS server.
Example:
s := dnsforward.Server{} err := s.Start(nil) // will start a DNS server listening on default port 53, in a goroutine err := s.Reconfigure(ServerConfig{UDPListenAddr: &net.UDPAddr{Port: 53535}}) // will reconfigure running DNS server to listen on UDP port 53535 err := s.Stop() // will stop listening on port 53535 and cancel all goroutines err := s.Start(nil) // will start listening again, on port 53535, in a goroutine
The zero Server is empty and ready for use.
func NewServer ¶
func NewServer(p DNSCreateParams) (s *Server, err error)
NewServer creates a new instance of the dnsforward.Server Note: this function must be called only once
TODO(a.garipov): How many constructors and initializers does this thing have? Refactor!
func (*Server) AddrProcConfig ¶
func (s *Server) AddrProcConfig() (c *client.DefaultAddrProcConfig)
AddrProcConfig returns the current address processing configuration. Only fields c.UsePrivateRDNS, c.UseRDNS, and c.UseWHOIS are filled.
func (*Server) Close ¶
func (s *Server) Close()
Close gracefully closes the server. It is safe for concurrent use.
TODO(e.burkov): A better approach would be making Stop method waiting for all its workers finished. But it would require the upstream.Upstream to have the Close method to prevent from hanging while waiting for unresponsive server to respond.
func (*Server) DialContext ¶
DialContext is an aghnet.DialContextFunc that uses s to resolve hostnames. addr should be a valid host:port address, where host could be a domain name or an IP address.
func (*Server) Exchange ¶
Exchange implements the rdns.Exchanger interface for *Server.
func (*Server) HandleBefore ¶
HandleBefore is the handler that is called before any other processing, including logs. It performs access checks and puts the client ID, if there is one, into the server's cache.
TODO(d.kolyshev): Extract to separate package.
func (*Server) IsBlockedClient ¶
IsBlockedClient returns true if the client is blocked by the current access settings.
func (*Server) LocalPTRResolvers ¶
LocalPTRResolvers returns the current local PTR resolver configuration.
func (*Server) NewMsgNODATA ¶
NewMsgNODATA implements the proxy.MessageConstructor interface for *Server.
func (*Server) NewMsgNOTIMPLEMENTED ¶
NewMsgNOTIMPLEMENTED implements the proxy.MessageConstructor interface for *Server.
func (*Server) NewMsgNXDOMAIN ¶
NewMsgNXDOMAIN implements the proxy.MessageConstructor interface for *Server.
func (*Server) NewMsgSERVFAIL ¶
NewMsgSERVFAIL implements the proxy.MessageConstructor interface for *Server.
func (*Server) Prepare ¶
func (s *Server) Prepare(conf *ServerConfig) (err error)
Prepare initializes parameters of s using data from conf. conf must not be nil.
func (*Server) Reconfigure ¶
func (s *Server) Reconfigure(conf *ServerConfig) error
Reconfigure applies the new configuration to the DNS server.
func (*Server) Resolve ¶
Resolve gets IP addresses by host name from an upstream server. No request/response filtering is performed. Query log and Stats are not updated. This method may be called before Server.Start.
func (*Server) ServeHTTP ¶
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP is a HTTP handler method we use to provide DNS-over-HTTPS.
func (*Server) Start ¶
Start starts the DNS server. It must only be called after Server.Prepare.
func (*Server) UpdatedProtectionStatus ¶
UpdatedProtectionStatus updates protection state, if the protection was disabled temporarily. Returns the updated state of protection.
func (*Server) WriteDiskConfig ¶
WriteDiskConfig - write configuration
type ServerConfig ¶
type ServerConfig struct { // UDPListenAddrs is the list of addresses to listen for DNS-over-UDP. UDPListenAddrs []*net.UDPAddr // TCPListenAddrs is the list of addresses to listen for DNS-over-TCP. TCPListenAddrs []*net.TCPAddr // UpstreamConfig is the general configuration of upstream DNS servers. UpstreamConfig *proxy.UpstreamConfig // PrivateRDNSUpstreamConfig is the configuration of upstream DNS servers // for private reverse DNS. PrivateRDNSUpstreamConfig *proxy.UpstreamConfig // AddrProcConf defines the configuration for the client IP processor. // If nil, [client.EmptyAddrProc] is used. // // TODO(a.garipov): The use of [client.EmptyAddrProc] is a crutch for tests. // Remove that. AddrProcConf *client.DefaultAddrProcConfig Config TLSConfig DNSCryptConfig TLSAllowUnencryptedDoH bool // UpstreamTimeout is the timeout for querying upstream servers. UpstreamTimeout time.Duration TLSv12Roots *x509.CertPool // list of root CAs for TLSv1.2 // TLSCiphers are the IDs of TLS cipher suites to use. TLSCiphers []uint16 // Called when the configuration is changed by HTTP request ConfigModified func() // Register an HTTP handler HTTPRegister aghhttp.RegisterFunc // LocalPTRResolvers is a slice of addresses to be used as upstreams for // resolving PTR queries for local addresses. LocalPTRResolvers []string // DNS64Prefixes is a slice of NAT64 prefixes to be used for DNS64. DNS64Prefixes []netip.Prefix // UsePrivateRDNS defines if the PTR requests for unknown addresses from // locally-served networks should be resolved via private PTR resolvers. UsePrivateRDNS bool // UseDNS64 defines if DNS64 is enabled for incoming requests. UseDNS64 bool // ServeHTTP3 defines if HTTP/3 is be allowed for incoming requests. ServeHTTP3 bool // UseHTTP3Upstreams defines if HTTP/3 is be allowed for DNS-over-HTTPS // upstreams. UseHTTP3Upstreams bool // ServePlainDNS defines if plain DNS is allowed for incoming requests. ServePlainDNS bool }
ServerConfig represents server configuration. The zero ServerConfig is empty and ready for use.
type SystemResolvers ¶
type SystemResolvers interface { // Addrs returns the list of system resolvers' addresses. Callers must // clone the returned slice before modifying it. Implementations of Addrs // must be safe for concurrent use. Addrs() (addrs []netip.AddrPort) }
SystemResolvers is an interface for accessing the OS-provided resolvers.
type TLSConfig ¶
type TLSConfig struct { TLSListenAddrs []*net.TCPAddr `yaml:"-" json:"-"` QUICListenAddrs []*net.UDPAddr `yaml:"-" json:"-"` HTTPSListenAddrs []*net.TCPAddr `yaml:"-" json:"-"` // PEM-encoded certificates chain CertificateChain string `yaml:"certificate_chain" json:"certificate_chain"` // PEM-encoded private key PrivateKey string `yaml:"private_key" json:"private_key"` CertificatePath string `yaml:"certificate_path" json:"certificate_path"` PrivateKeyPath string `yaml:"private_key_path" json:"private_key_path"` CertificateChainData []byte `yaml:"-" json:"-"` PrivateKeyData []byte `yaml:"-" json:"-"` // ServerName is the hostname of the server. Currently, it is only being // used for ClientID checking and Discovery of Designated Resolvers (DDR). ServerName string `yaml:"-" json:"-"` // OverrideTLSCiphers, when set, contains the names of the cipher suites to // use. If the slice is empty, the default safe suites are used. OverrideTLSCiphers []string `yaml:"override_tls_ciphers,omitempty" json:"-"` // StrictSNICheck controls if the connections with SNI mismatching the // certificate's ones should be rejected. StrictSNICheck bool `yaml:"strict_sni_check" json:"-"` // contains filtered or unexported fields }
TLSConfig is the TLS configuration for HTTPS, DNS-over-HTTPS, and DNS-over-TLS
type UpstreamMode ¶
type UpstreamMode string
UpstreamMode is a enumeration of upstream mode representations. See proxy.UpstreamModeType.
TODO(d.kolyshev): Consider using proxy.UpstreamMode.
const ( UpstreamModeLoadBalance UpstreamMode = "load_balance" UpstreamModeParallel UpstreamMode = "parallel" UpstreamModeFastestAddr UpstreamMode = "fastest_addr" )