From 95633146e08aa0bc81aa3d7949c3ef02f38a2308 Mon Sep 17 00:00:00 2001
From: Paul Holzinger <pholzing@redhat.com>
Date: Fri, 29 Apr 2022 15:01:56 +0200
Subject: libpod: host netns keep same /etc/resolv.conf

When a container is run in the host network namespace we have to keep
the same resolv.conf content and not use the systemd-resolve detection
logic.

But also make sure we still allow --dns options.

Fixes #14055

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
---
 libpod/container_internal_linux.go | 6 ++++--
 test/system/500-networking.bats    | 9 +++++++++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 2eaf56c0a..4742b22ab 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -2289,9 +2289,11 @@ func (c *Container) generateResolvConf() error {
 		networkSearchDomains []string
 	)
 
+	hostns := true
 	resolvConf := "/etc/resolv.conf"
 	for _, namespace := range c.config.Spec.Linux.Namespaces {
 		if namespace.Type == spec.NetworkNamespace {
+			hostns = false
 			if namespace.Path != "" && !strings.HasPrefix(namespace.Path, "/proc/") {
 				definedPath := filepath.Join("/etc/netns", filepath.Base(namespace.Path), "resolv.conf")
 				_, err := os.Stat(definedPath)
@@ -2313,7 +2315,7 @@ func (c *Container) generateResolvConf() error {
 
 	ns := resolvconf.GetNameservers(contents)
 	// check if systemd-resolved is used, assume it is used when 127.0.0.53 is the only nameserver
-	if len(ns) == 1 && ns[0] == "127.0.0.53" {
+	if !hostns && len(ns) == 1 && ns[0] == "127.0.0.53" {
 		// read the actual resolv.conf file for systemd-resolved
 		resolvedContents, err := ioutil.ReadFile("/run/systemd/resolve/resolv.conf")
 		if err != nil {
@@ -2346,7 +2348,7 @@ func (c *Container) generateResolvConf() error {
 
 	// Ensure that the container's /etc/resolv.conf is compatible with its
 	// network configuration.
-	resolv, err := resolvconf.FilterResolvDNS(contents, ipv6, c.config.CreateNetNS)
+	resolv, err := resolvconf.FilterResolvDNS(contents, ipv6, !hostns)
 	if err != nil {
 		return errors.Wrapf(err, "error parsing host resolv.conf")
 	}
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index c7007741b..3db0804d1 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -656,6 +656,15 @@ EOF
     run_podman run --network $netname --rm $IMAGE cat /etc/resolv.conf
     is "$output" "search dns.podman.*" "correct search domain"
     is "$output" ".*nameserver $subnet.1.*" "integrated dns nameserver is set"
+
+    # host network should keep localhost nameservers
+    if grep 127.0.0. /etc/resolv.conf >/dev/null; then
+        run_podman run --network host --rm $IMAGE cat /etc/resolv.conf
+        is "$output" ".*nameserver 127\.0\.0.*" "resolv.conf contains localhost nameserver"
+    fi
+    # host net + dns still works
+    run_podman run --network host --dns 1.1.1.1 --rm $IMAGE cat /etc/resolv.conf
+    is "$output" ".*nameserver 1\.1\.1\.1.*" "resolv.conf contains 1.1.1.1 nameserver"
 }
 
 @test "podman run port forward range" {
-- 
cgit v1.2.3-54-g00ecf