From cc8327ed9a7bac9b90670598a9a18f0ea92712d9 Mon Sep 17 00:00:00 2001 From: Matt Keeler Date: Fri, 7 Sep 2018 10:48:29 -0400 Subject: [PATCH] Ensure that errors setting up the DNS servers get propagated back to the shell (#4598) Fixes: #4578 Prior to this fix if there was an error binding to ports for the DNS servers the error would be swallowed by the gated log writer and never output. This fix propagates the DNS server errors back to the shell with a multierror. --- agent/agent.go | 13 +++++++++---- website/source/docs/guides/forwarding.html.md | 4 ++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/agent/agent.go b/agent/agent.go index c9ecc65293..92b901350f 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -38,6 +38,7 @@ import ( "github.com/hashicorp/consul/logger" "github.com/hashicorp/consul/types" "github.com/hashicorp/consul/watch" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/go-uuid" "github.com/hashicorp/memberlist" "github.com/hashicorp/raft" @@ -448,6 +449,7 @@ func (a *Agent) Start() error { func (a *Agent) listenAndServeDNS() error { notif := make(chan net.Addr, len(a.config.DNSAddrs)) + errCh := make(chan error, len(a.config.DNSAddrs)) for _, addr := range a.config.DNSAddrs { // create server s, err := NewDNSServer(a) @@ -462,23 +464,26 @@ func (a *Agent) listenAndServeDNS() error { defer a.wgServers.Done() err := s.ListenAndServe(addr.Network(), addr.String(), func() { notif <- addr }) if err != nil && !strings.Contains(err.Error(), "accept") { - a.logger.Printf("[ERR] agent: Error starting DNS server %s (%s): %v", addr.String(), addr.Network(), err) + errCh <- err } }(addr) } // wait for servers to be up timeout := time.After(time.Second) + var merr *multierror.Error for range a.config.DNSAddrs { select { case addr := <-notif: a.logger.Printf("[INFO] agent: Started DNS server %s (%s)", addr.String(), addr.Network()) - continue + case err := <-errCh: + merr = multierror.Append(merr, err) case <-timeout: - return fmt.Errorf("agent: timeout starting DNS servers") + merr = multierror.Append(merr, fmt.Errorf("agent: timeout starting DNS servers")) + break } } - return nil + return merr.ErrorOrNil() } // listenHTTP binds listeners to the provided addresses and also returns diff --git a/website/source/docs/guides/forwarding.html.md b/website/source/docs/guides/forwarding.html.md index 87824a22fc..f26391eca1 100644 --- a/website/source/docs/guides/forwarding.html.md +++ b/website/source/docs/guides/forwarding.html.md @@ -179,6 +179,10 @@ mapping. [root@localhost ~]# iptables -t nat -A OUTPUT -d localhost -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 8600 ``` +Binding to port 53 will usually require running either as a privileged user (or on Linux running with the +CAP_NET_BIND_SERVICE capability). If using the Consul docker image you will need to add the following to the +environment to allow Consul to use the port: `CONSUL_ALLOW_PRIVILEGED_PORTS=yes` + Note: With this setup, PTR record queries will still be sent out to the other configured resolvers in addition to Consul.