mirror of
https://github.com/coredns/coredns.git
synced 2026-08-27 15:17:06 -04:00
Keep miekg/dns's default request policy unless a plugin explicitly registers an additional opcode. Aggregate the policy at the listener, then enforce it again after zone routing so mixed server blocks on one socket remain isolated. Apply the same policy to UDP, TCP, and DNS-over-TLS while preserving TSIG verification and the one-question requirement. Signed-off-by: houyuwushang <liuluoqianqiu@outlook.com>
202 lines
7.4 KiB
Go
202 lines
7.4 KiB
Go
package dnsserver
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/coredns/caddy"
|
|
"github.com/coredns/coredns/plugin"
|
|
"github.com/coredns/coredns/request"
|
|
|
|
"github.com/miekg/dns"
|
|
"github.com/pires/go-proxyproto"
|
|
)
|
|
|
|
// Config configuration for a single server.
|
|
type Config struct {
|
|
// The zone of the site.
|
|
Zone string
|
|
|
|
// one or several hostnames to bind the server to.
|
|
// defaults to a single empty string that denote the wildcard address
|
|
ListenHosts []string
|
|
|
|
// The port to listen on.
|
|
Port string
|
|
|
|
// The number of servers that will listen on one port.
|
|
// By default, one server will be running.
|
|
NumSockets int
|
|
|
|
// Root points to a base directory we find user defined "things".
|
|
// First consumer is the file plugin to looks for zone files in this place.
|
|
Root string
|
|
|
|
// Debug controls the panic/recover mechanism that is enabled by default.
|
|
Debug bool
|
|
|
|
// Stacktrace controls including stacktrace as part of log from recover mechanism, it is disabled by default.
|
|
Stacktrace bool
|
|
|
|
// The transport we implement, normally just "dns" over TCP/UDP, but could be
|
|
// DNS-over-TLS or DNS-over-gRPC.
|
|
Transport string
|
|
|
|
// If this function is not nil it will be used to inspect and validate
|
|
// HTTP requests. Although this isn't referenced in-tree, external plugins
|
|
// may depend on it.
|
|
HTTPRequestValidateFunc func(*http.Request) bool
|
|
|
|
// If this function is not nil it is called once per Server in ServePacket
|
|
// (so each UDP listening socket gets its own decorator under multisocket)
|
|
// and its result is installed as the underlying dns.Server's
|
|
// DecorateWriter. Plain dns:// UDP listeners only. When several server
|
|
// blocks sharing a listener set it, the last one in config order wins.
|
|
// Although this isn't referenced in-tree, external plugins may depend
|
|
// on it.
|
|
UDPDecorateWriterFunc func(*Server) dns.DecorateWriter
|
|
|
|
// FilterFuncs is used to further filter access
|
|
// to this handler. E.g. to limit access to a reverse zone
|
|
// on a non-octet boundary, i.e. /17
|
|
FilterFuncs []FilterFunc
|
|
|
|
// ViewName is the name of the Viewer PLugin defined in the Config
|
|
ViewName string
|
|
|
|
// TLSConfig when listening for encrypted connections (gRPC, DNS-over-TLS).
|
|
TLSConfig *tls.Config
|
|
|
|
// MaxQUICStreams defines the maximum number of concurrent QUIC streams for a QUIC server.
|
|
// This is nil if not specified, allowing for a default to be used.
|
|
MaxQUICStreams *int
|
|
|
|
// MaxQUICConnections is the maximum number of concurrent connections.
|
|
MaxQUICConnections *int
|
|
|
|
// MaxQUICWorkerPoolSize defines the size of the worker pool for processing QUIC streams.
|
|
// This is nil if not specified, allowing for a default to be used.
|
|
MaxQUICWorkerPoolSize *int
|
|
|
|
// ProxyProtoConnPolicy is the function that will be used to
|
|
// configure the PROXY protocol settings on listeners.
|
|
// If nil, PROXY protocol is disabled.
|
|
ProxyProtoConnPolicy proxyproto.ConnPolicyFunc
|
|
|
|
// ProxyProtoUDPSessionTrackingTTL enables per-UDP-session source address
|
|
// caching on the PacketConn listener when set to a positive duration.
|
|
// The first datagram of a Cloudflare Spectrum PPv2 session (which contains
|
|
// only the PROXY Protocol header and no DNS payload) is used to populate a
|
|
// short-lived cache keyed by the Spectrum-side remote address. Subsequent
|
|
// datagrams from the same remote address that carry no PROXY Protocol header
|
|
// are associated with the cached real client address for up to this duration
|
|
// (refreshed on each matching packet). A zero or negative value disables
|
|
// session tracking. Has no effect unless ProxyProtoConnPolicy is also set.
|
|
ProxyProtoUDPSessionTrackingTTL time.Duration
|
|
|
|
// ProxyProtoUDPSessionTrackingMaxSessions is the maximum number of concurrent
|
|
// UDP sessions held in the LRU cache. Zero means use the default (udpSessionMaxEntries).
|
|
// Has no effect unless ProxyProtoUDPSessionTrackingTTL is positive.
|
|
ProxyProtoUDPSessionTrackingMaxSessions int
|
|
|
|
// MaxGRPCStreams defines the maximum number of concurrent streams per gRPC connection.
|
|
// This is nil if not specified, allowing for a default to be used.
|
|
MaxGRPCStreams *int
|
|
|
|
// MaxGRPCConnections defines the maximum number of concurrent gRPC connections.
|
|
// This is nil if not specified, allowing for a default to be used.
|
|
MaxGRPCConnections *int
|
|
|
|
// MaxHTTPSConnections defines the maximum number of concurrent HTTPS connections.
|
|
// This is nil if not specified, allowing for a default to be used.
|
|
MaxHTTPSConnections *int
|
|
|
|
// MaxHTTPS3Streams defines the maximum number of concurrent QUIC streams for HTTPS3.
|
|
// This is nil if not specified, allowing for a default to be used.
|
|
MaxHTTPS3Streams *int
|
|
|
|
// MaxHTTPS3Connections defines the maximum number of concurrent HTTPS3 connections.
|
|
// This is nil if not specified, allowing for a default to be used.
|
|
MaxHTTPS3Connections *int
|
|
|
|
// Timeouts for connection-oriented servers. Exact applicability depends on transport.
|
|
ReadTimeout time.Duration
|
|
WriteTimeout time.Duration
|
|
IdleTimeout time.Duration
|
|
|
|
// MaxTCPQueries defines the maximum number of queries served on a single TCP/TLS
|
|
// connection before it is closed. -1 means unlimited. This is nil if not specified,
|
|
// allowing for a default to be used.
|
|
MaxTCPQueries *int
|
|
|
|
// TSIG secrets, [name]key.
|
|
TsigSecret map[string]string
|
|
|
|
// allowedOpcodes contains non-default DNS opcodes that plugins have explicitly
|
|
// requested for this server block. QUERY and NOTIFY are accepted by default.
|
|
allowedOpcodes map[int]struct{}
|
|
|
|
// Plugin stack.
|
|
Plugin []plugin.Plugin
|
|
|
|
// Compiled plugin stack.
|
|
pluginChain plugin.Handler
|
|
|
|
// Plugin interested in announcing that they exist, so other plugin can call methods
|
|
// on them should register themselves here. The name should be the name as return by the
|
|
// Handler's Name method.
|
|
registry map[string]plugin.Handler
|
|
|
|
// firstConfigInBlock is used to reference the first config in a server block, for the
|
|
// purpose of sharing single instance of each plugin among all zones in a server block.
|
|
firstConfigInBlock *Config
|
|
|
|
// metaCollector references the first MetadataCollector plugin, if one exists
|
|
metaCollector MetadataCollector
|
|
}
|
|
|
|
// FilterFunc is a function that filters requests from the Config
|
|
type FilterFunc func(context.Context, *request.Request) bool
|
|
|
|
// keyForConfig builds a key for identifying the configs during setup time
|
|
func keyForConfig(blocIndex int, blocKeyIndex int) string {
|
|
return fmt.Sprintf("%d:%d", blocIndex, blocKeyIndex)
|
|
}
|
|
|
|
// GetConfig gets the Config that corresponds to c.
|
|
// If none exist nil is returned.
|
|
func GetConfig(c *caddy.Controller) *Config {
|
|
ctx := c.Context().(*dnsContext)
|
|
key := keyForConfig(c.ServerBlockIndex, c.ServerBlockKeyIndex)
|
|
if cfg, ok := ctx.keysToConfigs[key]; ok {
|
|
return cfg
|
|
}
|
|
// we should only get here during tests because directive
|
|
// actions typically skip the server blocks where we make
|
|
// the configs.
|
|
ctx.saveConfig(key, &Config{ListenHosts: []string{""}})
|
|
return GetConfig(c)
|
|
}
|
|
|
|
// AddPluginToAllServerBlocks adds m once to every server block in c's
|
|
// instance. It is intended for directives that must handle traffic on a
|
|
// listener other than the one where the directive is configured.
|
|
func AddPluginToAllServerBlocks(c *caddy.Controller, m plugin.Plugin) {
|
|
ctx := c.Context().(*dnsContext)
|
|
seen := make(map[*Config]struct{})
|
|
for _, cfg := range ctx.configs {
|
|
first := cfg.firstConfigInBlock
|
|
if first == nil {
|
|
first = cfg
|
|
}
|
|
if _, ok := seen[first]; ok {
|
|
continue
|
|
}
|
|
seen[first] = struct{}{}
|
|
first.AddPlugin(m)
|
|
}
|
|
}
|