mirror of https://github.com/containers/podman.git
Fix rootlesskit port forwarder with custom slirp cidr
The source ip for the rootlesskit port forwarder was hardcoded to the standard slirp4netns ip. This is incorrect since users can change the subnet used by slirp4netns with `--network slirp4netns:cidr=10.5.0.0/24`. The container interface ip is always the .100 in the subnet. Only when the rootlesskit port forwarder child ip matches the container interface ip the port forwarding will work. Fixes #9828 Signed-off-by: Paul Holzinger <paul.holzinger@web.de>
This commit is contained in:
parent
8465626e31
commit
f99b7a314b
|
@ -577,7 +577,7 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) error {
|
||||||
// set up port forwarder for CNI-in-slirp4netns
|
// set up port forwarder for CNI-in-slirp4netns
|
||||||
netnsPath := ctr.state.NetNS.Path()
|
netnsPath := ctr.state.NetNS.Path()
|
||||||
// TODO: support slirp4netns port forwarder as well
|
// TODO: support slirp4netns port forwarder as well
|
||||||
return r.setupRootlessPortMappingViaRLK(ctr, netnsPath)
|
return r.setupRootlessPortMappingViaRLK(ctr, netnsPath, "")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,7 +312,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error {
|
||||||
if netOptions.isSlirpHostForward {
|
if netOptions.isSlirpHostForward {
|
||||||
return r.setupRootlessPortMappingViaSlirp(ctr, cmd, apiSocket)
|
return r.setupRootlessPortMappingViaSlirp(ctr, cmd, apiSocket)
|
||||||
}
|
}
|
||||||
return r.setupRootlessPortMappingViaRLK(ctr, netnsPath)
|
return r.setupRootlessPortMappingViaRLK(ctr, netnsPath, netOptions.cidr)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -363,7 +363,7 @@ func waitForSync(syncR *os.File, cmd *exec.Cmd, logFile io.ReadSeeker, timeout t
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runtime) setupRootlessPortMappingViaRLK(ctr *Container, netnsPath string) error {
|
func (r *Runtime) setupRootlessPortMappingViaRLK(ctr *Container, netnsPath, slirp4CIDR string) error {
|
||||||
syncR, syncW, err := os.Pipe()
|
syncR, syncW, err := os.Pipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "failed to open pipe")
|
return errors.Wrapf(err, "failed to open pipe")
|
||||||
|
@ -391,6 +391,16 @@ func (r *Runtime) setupRootlessPortMappingViaRLK(ctr *Container, netnsPath strin
|
||||||
}
|
}
|
||||||
|
|
||||||
childIP := slirp4netnsIP
|
childIP := slirp4netnsIP
|
||||||
|
// set the correct childIP when a custom cidr is set
|
||||||
|
if slirp4CIDR != "" {
|
||||||
|
_, cidr, err := net.ParseCIDR(slirp4CIDR)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to parse slirp4netns cidr")
|
||||||
|
}
|
||||||
|
// the slirp container ip is always the hundredth ip in the subnet
|
||||||
|
cidr.IP[len(cidr.IP)-1] = cidr.IP[len(cidr.IP)-1] + 100
|
||||||
|
childIP = cidr.IP.String()
|
||||||
|
}
|
||||||
outer:
|
outer:
|
||||||
for _, r := range ctr.state.NetworkStatus {
|
for _, r := range ctr.state.NetworkStatus {
|
||||||
for _, i := range r.IPs {
|
for _, i := range r.IPs {
|
||||||
|
|
|
@ -77,35 +77,47 @@ load helpers
|
||||||
# FIXME: randomize port, and create second random host port
|
# FIXME: randomize port, and create second random host port
|
||||||
myport=54321
|
myport=54321
|
||||||
|
|
||||||
# Container will exit as soon as 'nc' receives input
|
for cidr in "" "$(random_rfc1918_subnet).0/24"; do
|
||||||
# We use '-n -v' to give us log messages showing an incoming connection
|
myport=$(( myport + 1 ))
|
||||||
# and its IP address; the purpose of that is guaranteeing that the
|
if [[ -z $cidr ]]; then
|
||||||
# remote IP is not 127.0.0.1 (podman PR #9052).
|
# regex to match that we are in 10.X subnet
|
||||||
# We could get more parseable output by using $NCAT_REMOTE_ADDR,
|
match="10\..*"
|
||||||
# but busybox nc doesn't support that.
|
else
|
||||||
run_podman run -d --userns=keep-id -p 127.0.0.1:$myport:$myport \
|
# Issue #9828 make sure a custom slir4netns cidr also works
|
||||||
$IMAGE nc -l -n -v -p $myport
|
network_arg="--network slirp4netns:cidr=$cidr"
|
||||||
cid="$output"
|
# slirp4netns interface ip is always .100
|
||||||
|
match="${cidr%.*}.100"
|
||||||
|
fi
|
||||||
|
|
||||||
# emit random string, and check it
|
# Container will exit as soon as 'nc' receives input
|
||||||
teststring=$(random_string 30)
|
# We use '-n -v' to give us log messages showing an incoming connection
|
||||||
echo "$teststring" | nc 127.0.0.1 $myport
|
# and its IP address; the purpose of that is guaranteeing that the
|
||||||
|
# remote IP is not 127.0.0.1 (podman PR #9052).
|
||||||
|
# We could get more parseable output by using $NCAT_REMOTE_ADDR,
|
||||||
|
# but busybox nc doesn't support that.
|
||||||
|
run_podman run -d --userns=keep-id $network_arg -p 127.0.0.1:$myport:$myport \
|
||||||
|
$IMAGE nc -l -n -v -p $myport
|
||||||
|
cid="$output"
|
||||||
|
|
||||||
run_podman logs $cid
|
# emit random string, and check it
|
||||||
# Sigh. We can't check line-by-line, because 'nc' output order is
|
teststring=$(random_string 30)
|
||||||
# unreliable. We usually get the 'connect to' line before the random
|
echo "$teststring" | nc 127.0.0.1 $myport
|
||||||
# string, but sometimes we get it after. So, just do substring checks.
|
|
||||||
is "$output" ".*listening on \[::\]:$myport .*" "nc -v shows right port"
|
|
||||||
|
|
||||||
# This is the truly important check: make sure the remote IP is
|
run_podman logs $cid
|
||||||
# in the 10.X range, not 127.X.
|
# Sigh. We can't check line-by-line, because 'nc' output order is
|
||||||
is "$output" \
|
# unreliable. We usually get the 'connect to' line before the random
|
||||||
".*connect to \[::ffff:10\..*\]:$myport from \[::ffff:10\..*\]:.*" \
|
# string, but sometimes we get it after. So, just do substring checks.
|
||||||
"nc -v shows remote IP address in 10.X space (not 127.0.0.1)"
|
is "$output" ".*listening on \[::\]:$myport .*" "nc -v shows right port"
|
||||||
is "$output" ".*${teststring}.*" "test string received on container"
|
|
||||||
|
|
||||||
# Clean up
|
# This is the truly important check: make sure the remote IP is not 127.X.
|
||||||
run_podman rm $cid
|
is "$output" \
|
||||||
|
".*connect to \[::ffff:$match*\]:$myport from \[::ffff:$match\]:.*" \
|
||||||
|
"nc -v shows remote IP address is not 127.0.0.1"
|
||||||
|
is "$output" ".*${teststring}.*" "test string received on container"
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
run_podman rm $cid
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# "network create" now works rootless, with the help of a special container
|
# "network create" now works rootless, with the help of a special container
|
||||||
|
|
Loading…
Reference in New Issue