for dns resolve errors likely due to a missing name server in /etc/resolv.conf, point user to man page of systemd-resolved, the likely cause

it seems linux machines with systemd-resolved don't always set up
/etc/resolv.conf correctly. there may be no "nameserver" entry, causing Go's
net resolver to fallback to 127.0.0.1 and ::1. Systemd-resolved is listening on
127.0.0.53, so users will likely get a "connection refused". So point users to
the systemd-resolved manual page.

for issue #38 by ArnoSen
This commit is contained in:
Mechiel Lukkien 2023-06-12 14:45:29 +02:00
parent 64ac9872a4
commit d2f7d59fce
No known key found for this signature in database

View file

@ -3,8 +3,10 @@ package dns
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"net" "net"
"os" "os"
"runtime"
"strings" "strings"
"time" "time"
@ -104,12 +106,29 @@ func (r StrictResolver) resolver() Resolver {
return r.Resolver return r.Resolver
} }
func resolveErrorHint(err *error) {
e := *err
if e == nil {
return
}
dnserr, ok := e.(*net.DNSError)
if !ok {
return
}
// If the dns server is not running, and it is one of the default/fallback IPs,
// hint at where to look.
if dnserr.IsTemporary && runtime.GOOS == "linux" && (dnserr.Server == "127.0.0.1:53" || dnserr.Server == "[::1]:53") && strings.HasSuffix(dnserr.Err, "connection refused") {
*err = fmt.Errorf("%w (hint: does /etc/resolv.conf point to a running nameserver? in case of systemd-resolved, see systemd-resolved.service(8))", *err)
}
}
func (r StrictResolver) LookupAddr(ctx context.Context, addr string) (resp []string, err error) { func (r StrictResolver) LookupAddr(ctx context.Context, addr string) (resp []string, err error) {
start := time.Now() start := time.Now()
defer func() { defer func() {
metricLookupObserve(r.Pkg, "addr", err, start) metricLookupObserve(r.Pkg, "addr", err, start)
xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "addr"), mlog.Field("addr", addr), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start))) xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "addr"), mlog.Field("addr", addr), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start)))
}() }()
defer resolveErrorHint(&err)
resp, err = r.resolver().LookupAddr(ctx, addr) resp, err = r.resolver().LookupAddr(ctx, addr)
return return
@ -123,6 +142,7 @@ func (r StrictResolver) LookupCNAME(ctx context.Context, host string) (resp stri
metricLookupObserve(r.Pkg, "cname", err, start) metricLookupObserve(r.Pkg, "cname", err, start)
xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "cname"), mlog.Field("host", host), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start))) xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "cname"), mlog.Field("host", host), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start)))
}() }()
defer resolveErrorHint(&err)
if !strings.HasSuffix(host, ".") { if !strings.HasSuffix(host, ".") {
return "", ErrRelativeDNSName return "", ErrRelativeDNSName
@ -144,6 +164,7 @@ func (r StrictResolver) LookupHost(ctx context.Context, host string) (resp []str
metricLookupObserve(r.Pkg, "host", err, start) metricLookupObserve(r.Pkg, "host", err, start)
xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "host"), mlog.Field("host", host), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start))) xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "host"), mlog.Field("host", host), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start)))
}() }()
defer resolveErrorHint(&err)
if !strings.HasSuffix(host, ".") { if !strings.HasSuffix(host, ".") {
return nil, ErrRelativeDNSName return nil, ErrRelativeDNSName
@ -158,6 +179,7 @@ func (r StrictResolver) LookupIP(ctx context.Context, network, host string) (res
metricLookupObserve(r.Pkg, "ip", err, start) metricLookupObserve(r.Pkg, "ip", err, start)
xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "ip"), mlog.Field("network", network), mlog.Field("host", host), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start))) xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "ip"), mlog.Field("network", network), mlog.Field("host", host), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start)))
}() }()
defer resolveErrorHint(&err)
if !strings.HasSuffix(host, ".") { if !strings.HasSuffix(host, ".") {
return nil, ErrRelativeDNSName return nil, ErrRelativeDNSName
@ -172,6 +194,7 @@ func (r StrictResolver) LookupIPAddr(ctx context.Context, host string) (resp []n
metricLookupObserve(r.Pkg, "ipaddr", err, start) metricLookupObserve(r.Pkg, "ipaddr", err, start)
xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "ipaddr"), mlog.Field("host", host), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start))) xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "ipaddr"), mlog.Field("host", host), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start)))
}() }()
defer resolveErrorHint(&err)
if !strings.HasSuffix(host, ".") { if !strings.HasSuffix(host, ".") {
return nil, ErrRelativeDNSName return nil, ErrRelativeDNSName
@ -186,6 +209,7 @@ func (r StrictResolver) LookupMX(ctx context.Context, name string) (resp []*net.
metricLookupObserve(r.Pkg, "mx", err, start) metricLookupObserve(r.Pkg, "mx", err, start)
xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "mx"), mlog.Field("name", name), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start))) xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "mx"), mlog.Field("name", name), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start)))
}() }()
defer resolveErrorHint(&err)
if !strings.HasSuffix(name, ".") { if !strings.HasSuffix(name, ".") {
return nil, ErrRelativeDNSName return nil, ErrRelativeDNSName
@ -200,6 +224,7 @@ func (r StrictResolver) LookupNS(ctx context.Context, name string) (resp []*net.
metricLookupObserve(r.Pkg, "ns", err, start) metricLookupObserve(r.Pkg, "ns", err, start)
xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "ns"), mlog.Field("name", name), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start))) xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "ns"), mlog.Field("name", name), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start)))
}() }()
defer resolveErrorHint(&err)
if !strings.HasSuffix(name, ".") { if !strings.HasSuffix(name, ".") {
return nil, ErrRelativeDNSName return nil, ErrRelativeDNSName
@ -214,6 +239,7 @@ func (r StrictResolver) LookupPort(ctx context.Context, network, service string)
metricLookupObserve(r.Pkg, "port", err, start) metricLookupObserve(r.Pkg, "port", err, start)
xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "port"), mlog.Field("network", network), mlog.Field("service", service), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start))) xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "port"), mlog.Field("network", network), mlog.Field("service", service), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start)))
}() }()
defer resolveErrorHint(&err)
resp, err = r.resolver().LookupPort(ctx, network, service) resp, err = r.resolver().LookupPort(ctx, network, service)
return return
@ -225,6 +251,7 @@ func (r StrictResolver) LookupSRV(ctx context.Context, service, proto, name stri
metricLookupObserve(r.Pkg, "srv", err, start) metricLookupObserve(r.Pkg, "srv", err, start)
xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "srv"), mlog.Field("service", service), mlog.Field("proto", proto), mlog.Field("name", name), mlog.Field("resp0", resp0), mlog.Field("resp1", resp1), mlog.Field("duration", time.Since(start))) xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "srv"), mlog.Field("service", service), mlog.Field("proto", proto), mlog.Field("name", name), mlog.Field("resp0", resp0), mlog.Field("resp1", resp1), mlog.Field("duration", time.Since(start)))
}() }()
defer resolveErrorHint(&err)
if !strings.HasSuffix(name, ".") { if !strings.HasSuffix(name, ".") {
return "", nil, ErrRelativeDNSName return "", nil, ErrRelativeDNSName
@ -239,6 +266,7 @@ func (r StrictResolver) LookupTXT(ctx context.Context, name string) (resp []stri
metricLookupObserve(r.Pkg, "txt", err, start) metricLookupObserve(r.Pkg, "txt", err, start)
xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "txt"), mlog.Field("name", name), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start))) xlog.WithContext(ctx).Debugx("dns lookup result", err, mlog.Field("pkg", r.Pkg), mlog.Field("type", "txt"), mlog.Field("name", name), mlog.Field("resp", resp), mlog.Field("duration", time.Since(start)))
}() }()
defer resolveErrorHint(&err)
if !strings.HasSuffix(name, ".") { if !strings.HasSuffix(name, ".") {
return nil, ErrRelativeDNSName return nil, ErrRelativeDNSName