Here's a method sidestepping entirely the namespace limitation to forward a TCP port.
socat
and UNIX socket
One kind of communication not hindered by the namespace is standard (named) UNIX socket (only abstract UNIX sockets depend on the network namespace) . Using a pair of socat
commands to proxy TCP through UNIX sockets allows to communicate easily from host to user/net namespace.
Assuming OP's variable $ns_id
(changed with a _
to have a correct syntax) has the correct PID content. Here's an example interactively run using two additional terminals:
term1: (the user/net namespace part)
socat
could be forked directly from OP's user/net namespace in the "do_stuff"
command to spare the use of nsenter
.
Here it's run from host/initial namespace using nsenter
to join the recently created namespace(s):
nsenter --preserve-credentials --user --mount --net -t $ns_id -- socat UNIX-LISTEN:/tmp/conduit,unlink-early,fork TCP4:127.0.0.1:80
term2 (the host/initial namespace part):
socat TCP4-LISTEN:8080,reuseaddr,fork UNIX-CONNECT:/tmp/conduit
Now one can connect to http://<host>:8080/ to reach the user/net namespace's web server listening on port 80. Traffic goes through the UNIX socket /tmp/conduit
.
Notes
This setup doesn't even involve slirp4netns
at all which doesn't even have to be running as long as the user/net namespace received a ip link set dev lo up
command to get TCP/IP available somewhere. One could even imagine configuring the Web server (probably nginx
then) itself to directly listen to an UNIX socket rather than TCP port 80 and keep only the second socat
command (though I don't give any guarantee on the correct handling of any socket credentials if those are used).
One should likewise be able to proxy UDP traffic in a limited way but there are various caveats depending on UDP use. Some uses would just need to change the TCP parts of socat
commands into UDP, other uses need to also change the UNIX socket part from stream sockets to datagram sockets (UNIX-LISTEN
-> UNIX-RECVFROM
etc.). The -T
timeout option in socat
is probably also needed. Not tested.