netnstcpbridge

Special TCP forwarder (proxy) where listening part and connecing part can move to other Linux network namespaces using setns(2) call.

It is somewhat analogous to using a pair of socats, each in different netns.

It works forking into two processes: listener and connector and by passing (SCM_RIGHTS) connected sockets from listener over a socketpair(2) to the connector process. Each part can be moved into each own network namespace.

Build it with cargo build --release or download it from Github releases.

Example session

usual_netns# unshare --net xterm& usual_netns# dig +short example.com | new_netns# ip link set lo up 93.184.216.34 | usual_netns# ip route get 93.184.216.34 | new_netns# ip route get 93.184.216.34 93.184.216.34 via 192.168.0.1 dev wlan0 | RTNETLINK answers: Network is unreachable src 192.168.0.185 uid 0 cache | usual_netns# curl --head http://93.184.216.34/ | new_netns# curl --head http://93.184.216.34/ HTTP/1.1 404 Not Found | curl: (7) Couldn't connect to server Content-Type: text/html | new_netns# curl --head http://127.0.0.1/ Date: Mon, 08 Aug 2022 23:48:10 GMT | curl: (7) Failed to connect to 127.0.0.1 Server: ECS (nyb/1D07) | port 80: Connection refused Content-Length: 345 | new_netns# echo $$ | 6448 usual_netns# netns_tcp_bridge -l 127.0.0.1:80 \ | -f /proc/6448/ns/net \ | -c 93.184.216.34:80 | | new_netns# curl --head http://127.0.0.1/ | HTTP/1.1 404 Not Found | Content-Type: text/html | Date: Mon, 08 Aug 2022 23:53:32 GMT | Server: ECS (nyb/1D2E) | Content-Length: 345

Limitations

Note that I have implemented more modes (e.g. using raw FDs), but have tested only the most straightforward mode.

Usage message

``` netnstcpbridge --help Usage: netnstcpbridge [OPTIONS]

Optional arguments: -h, --help -l, --listen LISTEN Socket address (e.g. 127.0.0.1:1234 or [::1]:1234) to bind socket to. -L, --listen-fd LISTEN-FD File descriptor to use as a listening socket -S, --preaccepted-fd PREACCEPTED-FD File descriptor to use as a single connected client (skip listening and accepting loop) -c, --connect CONNECT Socket address to forward incoming connections to. -C, --connect-fd CONNECT-FD Pre-connected file descriptor to forward just one accepted connection to -f, --listen-netns-file LISTEN-NETNS-FILE Path to a nsfs file with mounted network namespace where listening part of the forwarder should operate. E.g. /proc/1234/ns/net -F, --listen-netns-fd LISTEN-NETNS-FD Already opened file descriptor to use for the setns call on listening side -t, --connect-netns-file CONNECT-NETNS-FILE Path to a nsfs netns file to setns on the connecting side -T, --connect-netns-fd CONNECT-NETNS-FD Already opened file descriptor to use for the setns call on the connecting side ```