diff options
author | Paul Holzinger <pholzing@redhat.com> | 2021-07-30 14:33:08 +0200 |
---|---|---|
committer | Paul Holzinger <pholzing@redhat.com> | 2021-08-03 16:29:09 +0200 |
commit | e88d8dbeae2aebd2d816f16a21891764163afcd4 (patch) | |
tree | ee84759a07070d7255adc789434f228babf39ecc /test/system | |
parent | d25f8d07b3bbc11be1caa0838a031f0e5dc223a8 (diff) | |
download | podman-e88d8dbeae2aebd2d816f16a21891764163afcd4.tar.gz podman-e88d8dbeae2aebd2d816f16a21891764163afcd4.tar.bz2 podman-e88d8dbeae2aebd2d816f16a21891764163afcd4.zip |
fix rootless port forwarding with network dis-/connect
The rootlessport forwarder requires a child IP to be set. This must be a
valid ip in the container network namespace. The problem is that after a
network disconnect and connect the eth0 ip changed. Therefore the
packages are dropped since the source ip does no longer exists in the
netns.
One solution is to set the child IP to 127.0.0.1, however this is a
security problem. [1]
To fix this we have to recreate the ports after network connect and
disconnect. To make this work the rootlessport process exposes a socket
where podman network connect/disconnect connect to and send to new child
IP to rootlessport. The rootlessport process will remove all ports and
recreate them with the new correct child IP.
Also bump rootlesskit to v0.14.3 to fix a race with RemovePort().
Fixes #10052
[1] https://nvd.nist.gov/vuln/detail/CVE-2021-20199
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'test/system')
-rw-r--r-- | test/system/500-networking.bats | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats index 495c7948b..6ffee7eaf 100644 --- a/test/system/500-networking.bats +++ b/test/system/500-networking.bats @@ -390,4 +390,89 @@ load helpers run_podman network rm -f $netname } +# Test for https://github.com/containers/podman/issues/10052 +@test "podman network connect/disconnect with port forwarding" { + random_1=$(random_string 30) + HOST_PORT=12345 + SERVER=http://127.0.0.1:$HOST_PORT + + # Create a test file with random content + INDEX1=$PODMAN_TMPDIR/hello.txt + echo $random_1 > $INDEX1 + + local netname=testnet-$(random_string 10) + run_podman network create $netname + is "$output" ".*/cni/net.d/$netname.conflist" "output of 'network create'" + + local netname2=testnet2-$(random_string 10) + run_podman network create $netname2 + is "$output" ".*/cni/net.d/$netname2.conflist" "output of 'network create'" + + # First, run a container in background to ensure that the rootless cni ns + # is not destroyed after network disconnect. + run_podman run -d --network $netname $IMAGE top + background_cid=$output + + # Run a httpd container on first network with exposed port + run_podman run -d -p "$HOST_PORT:80" \ + --network $netname \ + -v $INDEX1:/var/www/index.txt:Z \ + -w /var/www \ + $IMAGE /bin/busybox-extras httpd -f -p 80 + cid=$output + + # Verify http contents: curl from localhost + run curl --max-time 3 -s $SERVER/index.txt + is "$output" "$random_1" "curl 127.0.0.1:/index.txt" + + run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").IPAddress}}" + ip="$output" + run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").MacAddress}}" + mac="$output" + + run_podman network disconnect $netname $cid + + # check that we cannot curl (timeout after 3 sec) + run curl --max-time 3 -s $SERVER/index.txt + if [ "$status" -eq 0 ]; then + die "curl did not fail, it should have timed out or failed with non zero exit code" + fi + + run_podman network connect $netname $cid + + # curl should work again + run curl --max-time 3 -s $SERVER/index.txt + is "$output" "$random_1" "curl 127.0.0.1:/index.txt should work again" + + # check that we have a new ip and mac + # if the ip is still the same this whole test turns into a nop + run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").IPAddress}}" + if [[ "$output" == "$ip" ]]; then + die "IP address did not change after podman network disconnect/connect" + fi + run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").MacAddress}}" + if [[ "$output" == "$mac" ]]; then + die "MAC address did not change after podman network disconnect/connect" + fi + + # connect a second network + run_podman network connect $netname2 $cid + + # curl should work + run curl --max-time 3 -s $SERVER/index.txt + is "$output" "$random_1" "curl 127.0.0.1:/index.txt should work" + + # disconnect the first network + run_podman network disconnect $netname $cid + + # curl should still work + run curl --max-time 3 -s $SERVER/index.txt + is "$output" "$random_1" "curl 127.0.0.1:/index.txt should still work" + + # cleanup + run_podman stop -t 0 $cid $background_cid + run_podman rm -f $cid $background_cid + run_podman network rm -f $netname $netname2 +} + # vim: filetype=sh |