Version: v0.0.0-...-8faa835 Latest Latest

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

Go to latest
Published: Nov 30, 2016 License: Apache-2.0 Imports: 22 Imported by: 0



proxy facilitates both a basic reverse proxy and a robust load balancer. The proxy has support for multiple backends. The load balancing features include multiple policies, health checks, and failovers. If all hosts fail their health check the proxy middleware will fail back to randomly selecting a target and sending packets to it.


In its most basic form, a simple reverse proxy uses this syntax:

proxy FROM TO
  • FROM is the base domain to match for the request to be proxied
  • TO is the destination endpoint to proxy to

However, advanced features including load balancing can be utilized with an expanded syntax:

proxy FROM TO... {
    policy random|least_conn|round_robin
    fail_timeout DURATION
    max_fails INTEGER
    health_check PATH:PORT [DURATION]
    except IGNORED_NAMES...
  • FROM is the name to match for the request to be proxied.
  • TO is the destination endpoint to proxy to. At least one is required, but multiple may be specified. To may be an IP:Port pair, or may reference a file in resolv.conf format
  • policy is the load balancing policy to use; applies only with multiple backends. May be one of random, least_conn, or round_robin. Default is random.
  • fail_timeout specifies how long to consider a backend as down after it has failed. While it is down, requests will not be routed to that backend. A backend is "down" if CoreDNS fails to communicate with it. The default value is 10 seconds ("10s").
  • max_fails is the number of failures within fail_timeout that are needed before considering a backend to be down. If 0, the backend will never be marked as down. Default is 1.
  • health_check will check path (on port) on each backend. If a backend returns a status code of 200-399, then that backend is healthy. If it doesn't, the backend is marked as unhealthy for duration and no requests are routed to it. If this option is not provided then health checks are disabled. The default duration is 10 seconds ("10s").
  • ignored_names... is a space-separated list of paths to exclude from proxying. Requests that match any of these paths will be passed through.
  • spray when all backends are unhealthy, randomly pick one to send the traffic to. (This is a failsafe.)


There are three load-balancing policies available:

  • random (default) - Randomly select a backend
  • least_conn - Select the backend with the fewest active connections
  • round_robin - Select the backend in round-robin fashion

All polices implement randomly spraying packets to backend hosts when no healthy hosts are available. This is to preeempt the case where the healthchecking (as a mechanism) fails.


If monitoring is enabled (via the prometheus directive) then the following metric is exported:

  • coredns_proxy_request_count_total{zone, proto, family}

This has some overlap with coredns_dns_request_count_total{zone, proto, family}, but allows for specifics on upstream query resolving. See the prometheus documentation for more details.


Proxy all requests within to a backend system:

proxy localhost:9005

Load-balance all requests between three backends (using random policy):

proxy . dns1.local:53 dns2.local:1053 dns3.local

Same as above, but round-robin style:

proxy . dns1.local:53 dns2.local:1053 dns3.local {
	policy round_robin

With health checks and proxy headers to pass hostname, IP, and scheme upstream:

proxy . dns1.local:53 dns2.local:53 dns3.local:53 {
	policy round_robin
	health_check /health:8080

Proxy everything except requests to or

proxy . backend:1234 {

Proxy everything except using the host resolv.conf nameservers:

proxy . /etc/resolv.conf {



Package proxy is middleware that proxies requests.



This section is empty.


View Source
var (
	RequestDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{
		Namespace: middleware.Namespace,
		Subsystem: subsystem,
		Name:      "request_duration_milliseconds",
		Buckets:   append(prometheus.DefBuckets, []float64{50, 100, 200, 500, 1000, 2000, 3000, 4000, 5000, 10000}...),
		Help:      "Histogram of the time (in milliseconds) each request took.",
	}, []string{"zone"})

Metrics the proxy middleware exports.


func OnStartup

func OnStartup() error

OnStartup sets up the metrics on startup.

func RegisterPolicy

func RegisterPolicy(name string, policy func() Policy)

RegisterPolicy adds a custom policy to the proxy.


type HostPool

type HostPool []*UpstreamHost

HostPool is a collection of UpstreamHosts.

type LeastConn

type LeastConn struct{}

LeastConn is a policy that selects the host with the least connections.

func (*LeastConn) Select

func (r *LeastConn) Select(pool HostPool) *UpstreamHost

Select selects the up host with the least number of connections in the pool. If more than one host has the same least number of connections, one of the hosts is chosen at random.

type Options

type Options struct {
	Ecs []*net.IPNet // EDNS0 CLIENT SUBNET address (v4/v6) to add in CIDR notaton.

Options ...

type Policy

type Policy interface {
	Select(pool HostPool) *UpstreamHost

Policy decides how a host will be selected from a pool. When all hosts are unhealthy, it is assumed the healthchecking failed. In this case each policy will *randomly* return a host from the pool to prevent no traffic to go through at all.

type Proxy

type Proxy struct {
	Next      middleware.Handler
	Client    *client
	Upstreams []Upstream

Proxy represents a middleware instance that can proxy requests to another DNS server.

func New

func New(hosts []string) Proxy

New create a new proxy with the hosts in host and a Random policy.

func (Proxy) Forward

func (p Proxy) Forward(state request.Request) (*dns.Msg, error)

Forward forward the request in state as-is. Unlike Lookup that adds EDNS0 suffix to the message.

func (Proxy) Lookup

func (p Proxy) Lookup(state request.Request, name string, typ uint16) (*dns.Msg, error)

Lookup will use name and type to forge a new message and will send that upstream. It will set any EDNS0 options correctly so that downstream will be able to process the reply.

func (Proxy) Name

func (p Proxy) Name() string

Name implements the Handler interface.

func (Proxy) ServeDNS

func (p Proxy) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error)

ServeDNS satisfies the middleware.Handler interface.

type Random

type Random struct{}

Random is a policy that selects up hosts from a pool at random.

func (*Random) Select

func (r *Random) Select(pool HostPool) *UpstreamHost

Select selects an up host at random from the specified pool.

type RoundRobin

type RoundRobin struct {
	Robin uint32

RoundRobin is a policy that selects hosts based on round robin ordering.

func (*RoundRobin) Select

func (r *RoundRobin) Select(pool HostPool) *UpstreamHost

Select selects an up host from the pool using a round robin ordering scheme.

type Spray

type Spray struct{}

Spray is a policy that selects a host from a pool at random. This should be used as a last ditch attempt to get a host when all hosts are reporting unhealthy.

func (*Spray) Select

func (r *Spray) Select(pool HostPool) *UpstreamHost

Select selects an up host at random from the specified pool.

type Upstream

type Upstream interface {
	// The domain name this upstream host should be routed on.
	From() string
	// Selects an upstream host to be routed to.
	Select() *UpstreamHost
	// Checks if subpdomain is not an ignored.
	IsAllowedPath(string) bool
	// Options returns the options set for this upstream
	Options() Options

Upstream manages a pool of proxy upstream hosts. Select should return a suitable upstream host, or nil if no such hosts are available.

func NewStaticUpstreams

func NewStaticUpstreams(c *caddyfile.Dispenser) ([]Upstream, error)

NewStaticUpstreams parses the configuration input and sets up static upstreams for the proxy middleware.

type UpstreamHost

type UpstreamHost struct {
	Conns             int64  // must be first field to be 64-bit aligned on 32-bit systems
	Name              string // IP address (and port) of this upstream host
	Fails             int32
	FailTimeout       time.Duration
	Unhealthy         bool
	CheckDown         UpstreamHostDownFunc
	WithoutPathPrefix string

UpstreamHost represents a single proxy upstream

func (*UpstreamHost) Down

func (uh *UpstreamHost) Down() bool

Down checks whether the upstream host is down or not. Down will try to use uh.CheckDown first, and will fall back to some default criteria if necessary.

type UpstreamHostDownFunc

type UpstreamHostDownFunc func(*UpstreamHost) bool

UpstreamHostDownFunc can be used to customize how Down behaves.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
t or T : Toggle theme light dark auto
y or Y : Canonical URL