Universal Relay

Universal Relay is a simple TCP->TCP relay for (isolated) network namespaces. It supports a variety of modes of operation, such as tunneling all traffic through a SOCKS server, as well as custom routing of network destinations.

Universal Relay was originally intended to be a means of causing all network traffic in a network namespace to be tunneled through a SOCKS proxy (such as the one created by ssh -D). Similar in overall spirit to slirp4netns, but instead of creating a TUN device and using a userspace TCP/IP stack, we reuse the kernel's TCP/IP stack using the following redirection in the newly created network namespace:

ip route add local dev lo
ip route add local ::/0 dev lo

and use ctrtool ns_open_file to create listening sockets in the network namespace.

TCP/IP connections are read from the namespace's listening sockets; when a new connection is made, the destination is read (using the same technique as previously used in IPv6 Things and Socketbox) and translated into SOCKS5 CONNECT commands on the host.

Unlike slirp4netns, Universal Relay specifically accounts for the fact that there might be a whole network that it should be applied to, so you can create subnets, static routes, and even BGP sessions in that network namespace to other network namespaces to make all your VMs and (rootless) Docker containers use it, for example. It's also a very effective way to experiment with various routing protocols (BGP, OSPF, RIP, etc.) using network namespaces. Unlike a traditional address translator, this is possible even if the IP addresses conflict with the host network.

Also intended to be a NAT64 CLAT / PLAT by rewriting IPv4 destinations into their IPv6 equivalent with NAT64 prefix, or vice versa. Quite difficult to do on the layer 3, but rather trivial on the application layer. Unix domain socket destinations will also be supported.

Also intended to be used in conjunction with a protocol that will be developed for use with Socket Enhancer, to take "transparent proxying" off the latter's to do list.

Also intended to be a more flexible and general-purpose version of Snippets:Node.js NAT64 TCP relay, inet-relay, and socketbox-relay.

TCP port forwarding as implemented in slirp4netns will not be supported in Universal Relay itself due to fundamental complexities, as Node.js would need to be able to create sockets in multiple network namespaces (which it doesn't really support). Instead, the recommended solution is to use ctrtool ns_open_file or socketbox to create a listening socket in the host network namespace, then use HAProxy (or a similar tool) in the foreign network namespace with bind fd@${CTRTOOL_NS_OPEN_FILE_FD_n} (if using ctrtool ns_open_file) or bind sockpair@${CTRTOOL_NS_OPEN_FILE_FD_n} (if using Socketbox) in a frontend to relay data from the host network namespace over to the foreign namespace.

TODO: implement address rewriting / ACLs i.e. ipRewrite(). Need to move all opaque identifiers in the "dest" object to one single property of that object. SOCKS server with domain containing an IPv6 address enclosed in square brackets does not currently work.