summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2022-04-29 13:45:59 -0400
committerGitHub <noreply@github.com>2022-04-29 13:45:59 -0400
commit2e75cb72caaa7f2f651726ede83986a336ca22fa (patch)
tree03029fcb3204207d78a77fb5ac3710d93087201d
parent95ff349de22e01eaa76cfc19891cc37952789b82 (diff)
parent01acc2565ac6bba44da270d59b90231a0bca3319 (diff)
downloadpodman-2e75cb72caaa7f2f651726ede83986a336ca22fa.tar.gz
podman-2e75cb72caaa7f2f651726ede83986a336ca22fa.tar.bz2
podman-2e75cb72caaa7f2f651726ede83986a336ca22fa.zip
Merge pull request #14062 from Luap99/resolv.conf
libpod: host netns keep same /etc/resolv.conf
-rw-r--r--libpod/container_internal_linux.go55
-rw-r--r--test/system/500-networking.bats24
2 files changed, 49 insertions, 30 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 3c88cc75f..4742b22ab 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -2123,15 +2123,9 @@ func (c *Container) makeBindMounts() error {
}
} else {
if !c.config.UseImageResolvConf {
- newResolv, err := c.generateResolvConf()
- if err != nil {
+ if err := c.generateResolvConf(); err != nil {
return errors.Wrapf(err, "error creating resolv.conf for container %s", c.ID())
}
- err = c.mountIntoRootDirs("/etc/resolv.conf", newResolv)
-
- if err != nil {
- return errors.Wrapf(err, "error assigning mounts to container %s", c.ID())
- }
}
if !c.config.UseImageHosts {
@@ -2288,23 +2282,25 @@ rootless=%d
}
// generateResolvConf generates a containers resolv.conf
-func (c *Container) generateResolvConf() (string, error) {
+func (c *Container) generateResolvConf() error {
var (
nameservers []string
networkNameServers []string
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)
if err == nil {
resolvConf = definedPath
} else if !os.IsNotExist(err) {
- return "", err
+ return err
}
}
break
@@ -2314,17 +2310,17 @@ func (c *Container) generateResolvConf() (string, error) {
contents, err := ioutil.ReadFile(resolvConf)
// resolv.conf doesn't have to exists
if err != nil && !os.IsNotExist(err) {
- return "", err
+ return err
}
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 {
if !os.IsNotExist(err) {
- return "", errors.Wrapf(err, "detected that systemd-resolved is in use, but could not locate real resolv.conf")
+ return errors.Wrapf(err, "detected that systemd-resolved is in use, but could not locate real resolv.conf")
}
} else {
contents = resolvedContents
@@ -2347,21 +2343,21 @@ func (c *Container) generateResolvConf() (string, error) {
ipv6, err := c.checkForIPv6(netStatus)
if err != nil {
- return "", err
+ return err
}
// 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")
+ return errors.Wrapf(err, "error parsing host resolv.conf")
}
dns := make([]net.IP, 0, len(c.runtime.config.Containers.DNSServers)+len(c.config.DNSServer))
for _, i := range c.runtime.config.Containers.DNSServers {
result := net.ParseIP(i)
if result == nil {
- return "", errors.Wrapf(define.ErrInvalidArg, "invalid IP address %s", i)
+ return errors.Wrapf(define.ErrInvalidArg, "invalid IP address %s", i)
}
dns = append(dns, result)
}
@@ -2412,20 +2408,15 @@ func (c *Container) generateResolvConf() (string, error) {
destPath := filepath.Join(c.state.RunDir, "resolv.conf")
if err := os.Remove(destPath); err != nil && !os.IsNotExist(err) {
- return "", errors.Wrapf(err, "container %s", c.ID())
+ return errors.Wrapf(err, "container %s", c.ID())
}
// Build resolv.conf
if _, err = resolvconf.Build(destPath, nameservers, search, options); err != nil {
- return "", errors.Wrapf(err, "error building resolv.conf for container %s", c.ID())
+ return errors.Wrapf(err, "error building resolv.conf for container %s", c.ID())
}
- // Relabel resolv.conf for the container
- if err := c.relabel(destPath, c.config.MountLabel, true); err != nil {
- return "", err
- }
-
- return destPath, nil
+ return c.bindMountRootFile(destPath, "/etc/resolv.conf")
}
// Check if a container uses IPv6.
@@ -2600,17 +2591,21 @@ func (c *Container) createHosts() error {
return err
}
- if err := os.Chown(targetFile, c.RootUID(), c.RootGID()); err != nil {
+ return c.bindMountRootFile(targetFile, config.DefaultHostsFile)
+}
+
+// bindMountRootFile will chown and relabel the source file to make it usable in the container.
+// It will also add the path to the container bind mount map.
+// source is the path on the host, dest is the path in the container.
+func (c *Container) bindMountRootFile(source, dest string) error {
+ if err := os.Chown(source, c.RootUID(), c.RootGID()); err != nil {
return err
}
- if err := label.Relabel(targetFile, c.MountLabel(), false); err != nil {
+ if err := label.Relabel(source, c.MountLabel(), false); err != nil {
return err
}
- if err = c.mountIntoRootDirs(config.DefaultHostsFile, targetFile); err != nil {
- return err
- }
- return nil
+ return c.mountIntoRootDirs(dest, source)
}
// generateGroupEntry generates an entry or entries into /etc/group as
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index 01571d176..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" {
@@ -723,4 +732,19 @@ EOF
is "${#lines[@]}" "5" "expect 5 host entries in /etc/hosts"
}
+@test "podman run /etc/* permissions" {
+ userns="--userns=keep-id"
+ if ! is_rootless; then
+ userns="--uidmap=0:1111111:65536 --gidmap=0:1111111:65536"
+ fi
+ # check with and without userns
+ for userns in "" "$userns"; do
+ # check the /etc/hosts /etc/hostname /etc/resolv.conf are owned by root
+ run_podman run $userns --rm $IMAGE stat -c %u:%g /etc/hosts /etc/resolv.conf /etc/hostname
+ is "${lines[0]}" "0\:0" "/etc/hosts owned by root"
+ is "${lines[1]}" "0\:0" "/etc/resolv.conf owned by root"
+ is "${lines[2]}" "0\:0" "/etc/hosts owned by root"
+ done
+}
+
# vim: filetype=sh