Make non-local services appear to come from local ports
As we saw in [Hack #47], it is simple to forward TCP and UDP ports from a firewall to internal hosts using iptables. But what if you need to forward traffic from arbitrary addresses to a machine that isn't even on your network? Try an application layer port forwarder, like rinetd .
This simple bit of code is a couple of years old but is small, efficient, and perfect for just this sort of problem. Unpack the archive and simply run make, and you'll be presented with a tiny rinetd binary that will let you forward TCP ports to your heart's content. Unfortunately, UDP ports aren't supported by rinetd.
The configuration file is dead simple:
[Source Address] [Source Port] [Destination Address] [Destination Port]
Each port to be forwarded is specified on a separate line. The source
and destination addresses can be either host names or IP addresses,
and an IP address of
rinetd to every available local IP:
0.0.0.0 80 some.othersite.gov 80 220.127.116.11 25 18.104.22.168 25 0.0.0.0 5353 my.shellserver.us 22
Save the file to /etc/rinetd.conf, and copy rinetd to somewhere handy (like /usr/local/sbin/, for example.) Then start it by simply running rinetd.
The first example forwards all web traffic destined for any local address to some.othersite.gov. Note that this will only work if there isn't another process (like Apache) already bound to local port 80.
The next forwards inbound SMTP traffic destined for 22.214.171.124 to the mail server at 126.96.36.199 (but doesn't interfere with any SMTP agents bound to other local IPs). The final example will forward any inbound traffic on port 5353 to the ssh server on my.shellserver.us. These all work without NAT or any special kernel configuration. Simply run rinetd, and it daemonizes and starts listening on the ports you have specified.
This utility can really help ease the transition when renumbering or physically relocating servers, as services can appear to remain up on the original IP (even though they are actually coming from another network entirely). rinetd doesn't even need to run as root, if you're only binding to ports higher than 1024. There are also extensive options for providing access control and keeping logs. This tiny tool is well worth having handy for when TCP port indirection is called.