Skip to content

Commit

Permalink
chore: listen for dns requests on 127.0.0.53
Browse files Browse the repository at this point in the history
Turns out there is actually no black magic in systemd, they simply listen on 127.0.0.53 and forward dns requests there in resolv.conf.
Reason is the same as ours — to preserve compatibility with other applications. So we do the same in our code.

This PR also does two things:
- Adds `::1` into resolv.conf for IPv6 only resolvers.
- Drops `SO_REUSEPORT` from control options (it works without them).

Closes #8328

Signed-off-by: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com>
  • Loading branch information
DmitriyMV committed Feb 26, 2024
1 parent 8872a7a commit f8c556a
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 18 deletions.
Expand Up @@ -160,6 +160,8 @@ func (ctrl *DNSResolveCacheController) runServer(originCtx context.Context, r co
MaxTCPQueries: -1,
}
}

l.Info("dns listener created")
}

for netwk, opt := range serverOpts {
Expand Down Expand Up @@ -227,6 +229,8 @@ func closeListener(lis io.Closer, l *zap.Logger) {
if err := lis.Close(); err != nil && !errors.Is(err, net.ErrClosed) {
l.Error("error closing listener", zap.Error(err))
}

l.Info("dns listener closed")
}

func dropResolveResources(ctx context.Context, r controller.Runtime, nets ...resource.ID) error {
Expand Down
Expand Up @@ -77,7 +77,7 @@ func (suite *DNSServer) TestResolving() {
var res *dns.Msg

err := retry.Constant(2*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(func() error {
r, err := dns.Exchange(msg, "127.0.0.1:10700")
r, err := dns.Exchange(msg, "127.0.0.53:10700")

res = r

Expand Down Expand Up @@ -148,7 +148,7 @@ func TestDNSServer(t *testing.T) {
AfterSetup: func(suite *ctest.DefaultSuite) {
suite.Require().NoError(suite.Runtime().RegisterController(&netctrl.DNSUpstreamController{}))
suite.Require().NoError(suite.Runtime().RegisterController(&netctrl.DNSResolveCacheController{
Addr: "127.0.0.1:10700",
Addr: "127.0.0.53:10700",
AddrV6: "[::1]:10700",
Logger: zaptest.NewLogger(t),
}))
Expand Down
4 changes: 2 additions & 2 deletions internal/app/machined/pkg/controllers/network/etcfile.go
Expand Up @@ -176,12 +176,12 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo
}
}

var localDNS = netip.MustParseAddr("127.0.0.1")
var localDNS = []netip.Addr{netip.MustParseAddr("127.0.0.53"), netip.MustParseAddr("::1")}

func pickNameservers(list safe.List[*network.DNSResolveCache], resolverStatus *network.ResolverStatus) []netip.Addr {
if list.Len() > 0 {
// local dns resolve cache enabled, route host dns requests to 127.0.0.1
return []netip.Addr{localDNS}
return localDNS
}

return resolverStatus.TypedSpec().DNSServers
Expand Down
10 changes: 5 additions & 5 deletions internal/app/machined/pkg/controllers/network/etcfile_test.go
Expand Up @@ -221,7 +221,7 @@ func (suite *EtcFileConfigSuite) TestComplete() {
[]resource.Resource{suite.cfg, suite.defaultAddress, suite.hostnameStatus, suite.resolverStatus, suite.dnsServer},
etcFileContents{
hosts: "127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n10.0.0.1 a b\n10.0.0.2 c d\n", //nolint:lll
resolvConf: "nameserver 127.0.0.1\n\nsearch example.com\n",
resolvConf: "nameserver 127.0.0.53\nnameserver ::1\n\nsearch example.com\n",
resolvGlobalConf: "nameserver 1.1.1.1\nnameserver 2.2.2.2\nnameserver 3.3.3.3\n\nsearch example.com\n",
},
)
Expand All @@ -232,7 +232,7 @@ func (suite *EtcFileConfigSuite) TestNoExtraHosts() {
[]resource.Resource{suite.defaultAddress, suite.hostnameStatus, suite.resolverStatus, suite.dnsServer},
etcFileContents{
hosts: "127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n",
resolvConf: "nameserver 127.0.0.1\n\nsearch example.com\n",
resolvConf: "nameserver 127.0.0.53\nnameserver ::1\n\nsearch example.com\n",
resolvGlobalConf: "nameserver 1.1.1.1\nnameserver 2.2.2.2\nnameserver 3.3.3.3\n\nsearch example.com\n",
},
)
Expand All @@ -255,7 +255,7 @@ func (suite *EtcFileConfigSuite) TestNoSearchDomain() {
[]resource.Resource{cfg, suite.defaultAddress, suite.hostnameStatus, suite.resolverStatus, suite.dnsServer},
etcFileContents{
hosts: "127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n",
resolvConf: "nameserver 127.0.0.1\n",
resolvConf: "nameserver 127.0.0.53\nnameserver ::1\n",
resolvGlobalConf: "nameserver 1.1.1.1\nnameserver 2.2.2.2\nnameserver 3.3.3.3\n",
},
)
Expand All @@ -268,7 +268,7 @@ func (suite *EtcFileConfigSuite) TestNoDomainname() {
[]resource.Resource{suite.defaultAddress, suite.hostnameStatus, suite.resolverStatus, suite.dnsServer},
etcFileContents{
hosts: "127.0.0.1 localhost\n33.11.22.44 foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n",
resolvConf: "nameserver 127.0.0.1\n",
resolvConf: "nameserver 127.0.0.53\nnameserver ::1\n",
resolvGlobalConf: "nameserver 1.1.1.1\nnameserver 2.2.2.2\nnameserver 3.3.3.3\n",
},
)
Expand All @@ -279,7 +279,7 @@ func (suite *EtcFileConfigSuite) TestOnlyResolvers() {
[]resource.Resource{suite.resolverStatus, suite.dnsServer},
etcFileContents{
hosts: "",
resolvConf: "nameserver 127.0.0.1\n",
resolvConf: "nameserver 127.0.0.53\nnameserver ::1\n",
resolvGlobalConf: "nameserver 1.1.1.1\nnameserver 2.2.2.2\nnameserver 3.3.3.3\n",
},
)
Expand Down
Expand Up @@ -189,7 +189,7 @@ func (ctrl *Controller) Run(ctx context.Context, drainer *runtime.Drainer) error
&network.AddressStatusController{},
&network.DeviceConfigController{},
&network.DNSResolveCacheController{
Addr: "127.0.0.1:53",
Addr: "127.0.0.53:53",
AddrV6: "[::1]:53",
Logger: dnsCacheLogger,
},
Expand Down
4 changes: 0 additions & 4 deletions internal/pkg/dns/dns.go
Expand Up @@ -274,29 +274,25 @@ func NewUDPPacketConn(network, addr string) (net.PacketConn, error) {

var (
tcpOptions = []controlOptions{
{unix.SOL_SOCKET, unix.SO_REUSEPORT, 1, "failed to set SO_REUSEADDR"},
{unix.IPPROTO_IP, unix.IP_RECVTTL, 1, "failed to set IP_RECVTTL"},
{unix.IPPROTO_TCP, unix.TCP_FASTOPEN, 5, "failed to set TCP_FASTOPEN"}, // tcp specific stuff from systemd
{unix.IPPROTO_TCP, unix.TCP_NODELAY, 1, "failed to set TCP_NODELAY"}, // tcp specific stuff from systemd
{unix.IPPROTO_IP, unix.IP_TTL, 1, "failed to set IP_TTL"},
}

tcpOptionsV6 = []controlOptions{
{unix.SOL_SOCKET, unix.SO_REUSEPORT, 1, "failed to set SO_REUSEADDR"},
{unix.IPPROTO_IPV6, unix.IPV6_RECVHOPLIMIT, 1, "failed to set IPV6_RECVHOPLIMIT"},
{unix.IPPROTO_TCP, unix.TCP_FASTOPEN, 5, "failed to set TCP_FASTOPEN"}, // tcp specific stuff from systemd
{unix.IPPROTO_TCP, unix.TCP_NODELAY, 1, "failed to set TCP_NODELAY"}, // tcp specific stuff from systemd
{unix.IPPROTO_IPV6, unix.IPV6_UNICAST_HOPS, 1, "failed to set IPV6_UNICAST_HOPS"},
}

udpOptions = []controlOptions{
{unix.SOL_SOCKET, unix.SO_REUSEPORT, 1, "failed to set SO_REUSEADDR"},
{unix.IPPROTO_IP, unix.IP_RECVTTL, 1, "failed to set IP_RECVTTL"},
{unix.IPPROTO_IP, unix.IP_TTL, 1, "failed to set IP_TTL"},
}

udpOptionsV6 = []controlOptions{
{unix.SOL_SOCKET, unix.SO_REUSEPORT, 1, "failed to set SO_REUSEADDR"},
{unix.IPPROTO_IPV6, unix.IPV6_RECVHOPLIMIT, 1, "failed to set IPV6_RECVHOPLIMIT"},
{unix.IPPROTO_IPV6, unix.IPV6_UNICAST_HOPS, 1, "failed to set IPV6_UNICAST_HOPS"},
}
Expand Down
8 changes: 4 additions & 4 deletions internal/pkg/dns/dns_test.go
Expand Up @@ -60,7 +60,7 @@ func TestDNS(t *testing.T) {

time.Sleep(10 * time.Millisecond)

r, err := dnssrv.Exchange(createQuery(), "127.0.0.1:10700")
r, err := dnssrv.Exchange(createQuery(), "127.0.0.53:10700")
test.errCheck(t, err)

if r != nil {
Expand All @@ -86,11 +86,11 @@ func TestDNSEmptyDestinations(t *testing.T) {

time.Sleep(10 * time.Millisecond)

r, err := dnssrv.Exchange(createQuery(), "127.0.0.1:10700")
r, err := dnssrv.Exchange(createQuery(), "127.0.0.53:10700")
require.NoError(t, err)
require.Equal(t, dnssrv.RcodeServerFailure, r.Rcode, r)

r, err = dnssrv.Exchange(createQuery(), "127.0.0.1:10700")
r, err = dnssrv.Exchange(createQuery(), "127.0.0.53:10700")
require.NoError(t, err)
require.Equal(t, dnssrv.RcodeServerFailure, r.Rcode, r)

Expand Down Expand Up @@ -118,7 +118,7 @@ func newServer(t *testing.T, nameservers ...string) (context.Context, func()) {

handler.SetProxy(pxs)

pc, err := dns.NewUDPPacketConn("udp", "127.0.0.1:10700")
pc, err := dns.NewUDPPacketConn("udp", "127.0.0.53:10700")
require.NoError(t, err)

runner := dns.NewRunner(dns.NewServer(dns.ServerOptins{
Expand Down

0 comments on commit f8c556a

Please sign in to comment.