- Transparent Proxy and Redirection with LINUX 2.2
- User-Space Redirection--The Illusion of the Facade
- Transparent Proxy Support--Slight of Hand
- Kernel Port Forwarding--High Wizardry
User-Space Redirection—The Illusion of the Facade
The first—and likely the most common—method of redirection is to use a user-space process to listen to networking requests on the desired interface and port, and then to forward these unaltered to the destination system and port. To a large extent, these processes are like proxies. In fact, these processes are often referred to as proxies, although I think redirector is more precise. If all goes well with the redirection, the user can't tell the difference between connecting to the redirecting destination and the true destination. (Note, however, that the destination sees the connection attempt come from the redirecting server.) One positive upshot of all this is that servers with private IP addresses can still be used to provide services to Internet clients. Figure 1 depicts the topology.
User-space redirection of traffic.
Because this type of topology is frequently used (or at least frequently desired), and in many cases admins don't choose to run HTTP daemons on their firewalls or external routers, people have invested some time in developing redirection solutions. Several popular redirection packages are available, some of which are listed in the following paragraphs.
transproxy provides a daemon, tproxy, which is easy to set up and use. It has no configuration file—all options are passed as command-line arguments. It's very simple to configure after you take a look at the man page, so I won't go into detail. But since I've used it a lot, here are a few notes on things that may not be obvious immediately:
-
It can be run either from inetd or as a stand-alone server (the absence of -s port indicates that it should run from inetd).
-
You need to specify -t when you're not proxying HTTP—the default mode is for HTTP translate, which is for use when connecting to HTTP proxy servers Squid or Apache.
-
Use -r username to have the proxy run as a non-root user. This is valid even if the listening port is 1023.
-
You can use -b ipaddress to force the daemon to bind to a particular interface or IP address.
transproxy is available from the upstream source ftp://ftp.nlc.net.au/pub/linux/www/. (There may be a Debian package, too.) Some instructions are floating around out there that incorrectly note that you need to have transparent proxying enabled in the kernel to be able to use the daemon; you can safely ignore this. Note that transproxy is for "simple" TCP connections, so it won't work for every application protocol. You have to use something like the next tool for FTP.
redir, like transproxy, is only for TCP connections. It does everything that transproxy does, and adds some nice capabilities. You can download the sources from http://www.ibiblio.org/linsearch/lsms/redir-2.2.html or use the Debian package redir. The additional functionality above transproxy is listed here by the command-line switches used to invoke it:
-
--ftp handles passive-mode FTP connections.
-
--timeout=n closes the connection after n seconds of inactivity.
-
--syslog enables logging via syslog. It's not in the man page, but it will log to the facility daemon at the level notice.
-
--name=string or --ident=string1 uses string instead of redir in the syslog entries.
-
--debug writes debugging information to stderr, or to syslog if you're using the --syslog switch.
-
--transproxy in conjunction with a kernel running transparent proxying,2 reports the original sender's address and port to the proxied destination.
Here's an example. When machineA connects to the redirector running on routerB, which forwards the traffic to machineC, machineC sees the packet as having originated from machineA. When machineC replies to machineA, the packet is intercepted by routerB, which bound itself to the sender's interface IP and port. This is possible only if redir is running as root and IP: transparent proxy support is compiled into the kernel. Furthermore, works correctly only for connections that are symmetrically routed (in other words, in both directions) by the system running redir. Finally, there's always the chance that the sender's port is already in use on the firewall, and won't be available for use. Nonetheless, it's a neat and useful trick. One benefit is that things like Web server logs will contain the correct source address for generating access statistics. See the transproxy.txt file accompanying the distribution for more information.
rinetd is a multi-headed (and multithreaded) server that acts like redir and transproxy. Like these, it redirects only TCP connections (but not FTP, so keep a copy of redir around!). rinetd sets itself apart with its configuration file. Unlike the previous two, it can listen to an arbitrary number of ports simultaneously, each of which may be bound to a (possibly different) interface address on the router. These port/address tuples are specified in the configuration file with lines in the format of bindaddress bindport connectaddress connectport. The addresses may be hostnames, and the ports may be service names. rinetd's configuration file may also include global and service-specific allow and deny lines, reminiscent of the configuration file used by the TIS FWTK. Any connection from a source that's explicitly denied or isn't found in a global allow will be immediately rejected. The next feature is a choice of logfile formats. You may choose to have no logfile whatsoever, use rinetd's format, or use a common Web server format. Like inetd, rinetd can be made to reload its configuration by sending it a SIGHUP.
rinetd can be found at http://www.boutell.com/rinetd/. There's also a Debian package of the same name. The following is an excerpt from the man page that provides a good synopsis.
rinetd redirects TCP connections from one IP address and port to another. rinetd is a single-process server that handles any number of connections to the address/port pairs specified in the file /etc/rinetd.conf. Since rinetd runs as a single process using nonblocking I/O, it's able to redirect a large number of connections without a severe impact on the machine. This makes it practical to run services on machines inside an IP masquerading firewall.
If none of the packages listed above fits your needs, you can always roll your own. If the nitty-gritty network programming scares you, use one of the general-purpose socket utilities such as socket or netcat. They should be available anywhere, but if you have problems finding them, refer to the socket and nc Debian packages. The next section is about using the kernel to do some of the work of redirection, normally in conjunction with a user-space redirector.