O'Reilly logo

Linux Server Hacks by Rob Flickenger

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Hack #48. Forwarding TCP Ports to Arbitrary Machines

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 0.0.0.0 binds rinetd to every available local IP:

0.0.0.0 80 some.othersite.gov 80
216.218.203.211 25 123.45.67.89 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 216.218.203.211 to the mail server at 123.45.67.89 (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.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required