From 14cd28c262da85146d4fd4bd1465f3d8f0cdc8bd Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 15 Jun 2023 12:27:28 +0200 Subject: [PATCH] add hostname to /etc/hosts when running with host network Some tools depend on the hostname being present in /etc/hosts. I would argue they are broken but its not like we can do anything about that. This adds the hostname with the local host ip when the host network is used. For private networking we already add the hostname. We also now correctly force host networking in chroot mode, it was silently ignored before thus causing extra confusion here. Fixes #4446 Signed-off-by: Paul Holzinger --- run_common.go | 28 +++++++++++++++++++++++++++- run_freebsd.go | 2 +- run_linux.go | 2 +- tests/run.bats | 6 +++++- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/run_common.go b/run_common.go index d0226f958..05e722b73 100644 --- a/run_common.go +++ b/run_common.go @@ -35,6 +35,7 @@ import ( "github.com/containers/common/libnetwork/network" "github.com/containers/common/libnetwork/resolvconf" netTypes "github.com/containers/common/libnetwork/types" + netUtil "github.com/containers/common/libnetwork/util" "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/subscriptions" imageTypes "github.com/containers/image/v5/types" @@ -117,7 +118,7 @@ func (b *Builder) addResolvConf(rdir string, chownOpts *idtools.IDPair, dnsServe } // generateHosts creates a containers hosts file -func (b *Builder) generateHosts(rdir string, chownOpts *idtools.IDPair, imageRoot string) (string, error) { +func (b *Builder) generateHosts(rdir string, chownOpts *idtools.IDPair, imageRoot string, spec *spec.Spec) (string, error) { conf, err := config.Default() if err != nil { return "", err @@ -128,12 +129,34 @@ func (b *Builder) generateHosts(rdir string, chownOpts *idtools.IDPair, imageRoo return "", err } + var entries etchosts.HostEntries + isHost := true + if spec.Linux != nil { + for _, ns := range spec.Linux.Namespaces { + if ns.Type == specs.NetworkNamespace { + isHost = false + break + } + } + } + // add host entry for local ip when running in host network + if spec.Hostname != "" && isHost { + ip := netUtil.GetLocalIP() + if ip != "" { + entries = append(entries, etchosts.HostEntry{ + Names: []string{spec.Hostname}, + IP: ip, + }) + } + } + targetfile := filepath.Join(rdir, "hosts") if err := etchosts.New(&etchosts.Params{ BaseFile: path, ExtraHosts: b.CommonBuildOpts.AddHost, HostContainersInternalIP: etchosts.GetHostContainersInternalIP(conf, nil, nil), TargetFile: targetfile, + ContainerIPs: entries, }); err != nil { return "", err } @@ -368,6 +391,9 @@ func checkAndOverrideIsolationOptions(isolation define.Isolation, options *RunOp if (pidns != nil && pidns.Host) && (userns != nil && !userns.Host) { return fmt.Errorf("not allowed to mix host PID namespace with container user namespace") } + case IsolationChroot: + logrus.Info("network namespace isolation not supported with chroot isolation, forcing host network") + options.NamespaceOptions.AddOrReplace(define.NamespaceOption{Name: string(specs.NetworkNamespace), Host: true}) } return nil } diff --git a/run_freebsd.go b/run_freebsd.go index eaaf31d95..0ff7ae720 100644 --- a/run_freebsd.go +++ b/run_freebsd.go @@ -196,7 +196,7 @@ func (b *Builder) Run(command []string, options RunOptions) error { hostFile := "" if !options.NoHosts && !contains(volumes, config.DefaultHostsFile) && options.ConfigureNetwork != define.NetworkDisabled { - hostFile, err = b.generateHosts(path, rootIDPair, mountPoint) + hostFile, err = b.generateHosts(path, rootIDPair, mountPoint, spec) if err != nil { return err } diff --git a/run_linux.go b/run_linux.go index 9a085eeb7..9bee763a1 100644 --- a/run_linux.go +++ b/run_linux.go @@ -264,7 +264,7 @@ func (b *Builder) Run(command []string, options RunOptions) error { hostFile := "" if !options.NoHosts && !contains(volumes, config.DefaultHostsFile) && options.ConfigureNetwork != define.NetworkDisabled { - hostFile, err = b.generateHosts(path, rootIDPair, mountPoint) + hostFile, err = b.generateHosts(path, rootIDPair, mountPoint, spec) if err != nil { return err } diff --git a/tests/run.bats b/tests/run.bats index e5b4f857f..1086a47aa 100644 --- a/tests/run.bats +++ b/tests/run.bats @@ -682,7 +682,8 @@ function configure_and_check_user() { run_buildah from --quiet --pull=false $WITH_POLICY_JSON debian cid=$output - run_buildah run --network=host $cid cat /etc/hosts + run_buildah run --network=host --hostname $hostname $cid cat /etc/hosts + assert "$output" =~ "$ip[[:blank:]]$hostname" hostOutput=$output m=$(buildah mount $cid) run cat $m/etc/hosts @@ -690,6 +691,9 @@ function configure_and_check_user() { expect_output --substring "" run_buildah run --network=host --no-hosts $cid cat /etc/hosts [ "$output" != "$hostOutput" ] + # --isolation chroot implies host networking so check for the correct hosts entry + run_buildah run --isolation chroot --hostname $hostname $cid cat /etc/hosts + assert "$output" =~ "$ip[[:blank:]]$hostname" run_buildah rm -a run_buildah from --quiet --pull=false $WITH_POLICY_JSON debian