From fb2ab832a7b99e48dabde99df4b212630788ce03 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Fri, 17 May 2024 11:35:14 +0200 Subject: [PATCH] fix incorrect host.containers.internal entry for rootless bridge mode We have to exclude the ips in the rootless netns as they are not the host. Now that fix only works if there are more than one ip one the host available, if there is only one we do not set the entry at all which I consider better as failing to resolve this name is a much better error for users than connecting to a wrong ip. It also matches what --network pasta already does. The test is bit more compilcated as I would like, however it must deal with both cases one ip, more than one so there is no way around it I think. Fixes #22653 Signed-off-by: Paul Holzinger --- libpod/container_internal_common.go | 9 +++++++++ test/system/505-networking-pasta.bats | 29 ++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/libpod/container_internal_common.go b/libpod/container_internal_common.go index 78dd31b39c..d76dea2995 100644 --- a/libpod/container_internal_common.go +++ b/libpod/container_internal_common.go @@ -2299,6 +2299,15 @@ func (c *Container) addHosts() error { var exclude []net.IP if c.pastaResult != nil { exclude = c.pastaResult.IPAddresses + } else if c.config.NetMode.IsBridge() { + // When running rootless we have to check the rootless netns ip addresses + // to not assign a ip that is already used in the rootless netns as it would + // not be routed to the host. + // https://github.com/containers/podman/issues/22653 + info, err := c.runtime.network.RootlessNetnsInfo() + if err == nil { + exclude = info.IPAddresses + } } return etchosts.New(&etchosts.Params{ diff --git a/test/system/505-networking-pasta.bats b/test/system/505-networking-pasta.bats index 9a96c61836..80282e1c42 100644 --- a/test/system/505-networking-pasta.bats +++ b/test/system/505-networking-pasta.bats @@ -778,7 +778,7 @@ EOF assert "$output" =~ "$mac2" "mac address from cli is set on custom interface" } -### Rootless unshare testins +### Rootless unshare testing @test "Podman unshare --rootless-netns with Pasta" { skip_if_remote "unshare is local-only" @@ -794,3 +794,30 @@ EOF run_podman unshare --rootless-netns ip addr is "$output" ".*${pasta_iface}.*" } + +# https://github.com/containers/podman/issues/22653 +@test "pasta/bridge and host.containers.internal" { + skip_if_no_ipv4 "IPv4 not routable on the host" + pasta_ip="$(default_addr 4)" + + for network in "pasta" "bridge"; do + # special exit code logic needed here, it is possible that there is no host.containers.internal + # when there is only one ip one the host and that one is used by pasta. + # As such we have to deal with both cases. + run_podman '?' run --rm --network=$network $IMAGE grep host.containers.internal /etc/hosts + if [ "$status" -eq 0 ]; then + assert "$output" !~ "$pasta_ip" "pasta host ip must not be assigned ($network)" + assert "$(hostname -I)" =~ "$(cut -f1 <<<$output)" "ip is one of the host ips ($network)" + elif [ "$status" -eq 1 ]; then + # if only pasta ip then we cannot have a host.containers.internal entry + # make sure this fact is actually the case + assert "$pasta_ip" == "$(hostname -I | tr -d '[:space:]')" "pasta ip must the only one one the host ($network)" + else + die "unexpected exit code '$status' from grep or podman ($network)" + fi + done + + host_ip=$(hostname -I | cut -f 1 -d " ") + run_podman run --rm --network=pasta:-a,169.254.0.2,-g,169.254.0.1,-n,24 $IMAGE grep host.containers.internal /etc/hosts + assert "$output" =~ "^$host_ip" "uses host first ip" +}