Linux has become very popular as the "swiss army knife" for all kinds of networking purposes. One area where Linux is a viable alternative to commercial solutions is firewalling. The Linux kernel offers some very flexible packet filtering features, which enable you to setup highly effective firewalling rules. However, it is sometimes necessary to open a defined hole to the inside of your net, for example if you need to connect to an internal mail- or WWW-Server from outside your firewalling host. This is the part where rinetd kicks in. This program is used to efficiently redirect connections from one IP address/port combination to another.
From the manual page: "Rinetd is a single-process server which handles
any number of connections to the address/port pairs specified in the
etc/rinetd.conf. Since rinetd runs as a single
process using nonblocking I/O, it is able to redirect a large number of
connections without putting much additional load to the machine." Apart
from Linux, rinetd should run on any major Unix flavor without any
trouble. But since the tool is free software, I would like to recommend
using a free operating system as well :^).
It is useful when you are operating virtual servers, firewalls and the like. However, there's one catch: rinetd is not able to redirect FTP connections, because FTP requires more than one socket. Moreover, rinetd can only redirect TCP connections, there's no support for UDP.
Rinetd is Open Source under the terms of the GNU General Public License (see http://www.gnu.org for further info). The author is Thomas Boutell, a famous open source developer. He also created the "gd" library for manipulation of GIF images and several other nice programs. See his WWW-Site http://www.boutell.com for more information about his work.
There are two methods on how to install rinetd on your system. You could either download the source and compile rinetd on your own, or you can use a precompiled binary package for your linux distribution.
Download via ftp from Tom Boutell's ftp-Server: ftp://ftp.boutell.com/pub/boutell/rinetd/rinetd.tar.gz Surprisingly, there is also a 32-bit Windows Version (95/98/NT) available under ftp://ftp.boutell.com/pub/boutell/rinetd/rinetd.zip, but this won't be covered in this article. The windows port has been added recently, in former times rinetd used to run on Unices only.
Extract the source archive using
should first check the Makefile for platform-specific details. Type "make"
to start the compilation afterwards. This should invoke the compiler and
create the binary for your platform. To install the compiled binary,
type "make install" as user "root". If you want to start up the process
at boot time, you should create a separate init script or add rinetd
to an already existing startup script.
Precompiled packages are available for most Linux distributions. For
example, SuSE Linux has a preconfigured package, which can be directly
installed from the CD. You just have to set "START_RINETD" in
/etc/rc.config to "yes" after installing the package
via the SuSE configuration tool "YaST".
Before starting rinetd, you have to create a configuration file
/etc/rinetd.conf. There's a well commented sample config file
in the source package, I would recommend to use this for starters.
The manual (man 8 rinetd) page covers all the possible configuration
The configuration file
/etc/rinetd.conf contains rules, that
define how and if rinetd forwards incoming TCP connections. You need
to restart rinetd, if you make changes to this file while rinetd is
running. The kill -1 signal (SIGHUP) can be used to cause rinetd to
reload its configuration file without interrupting existing connections.
These rules define the main functionality of rinetd: forwarding connections from one address/port-pair to another. The format is "bindaddress bindport connectaddress connectport" For example,
192.168.0.1 80 10.10.0.4 80
would forward all requests on IP address 192.168.0.1 (which could
be an external network interface) on port 80 (www) to an internal
WWW-Server (10.10.0.4 in this example) with no direct route to the other
net. Instead of port numbers, you can also use service names as defined
/etc/services. Therefore, the above mentioned example could
also be written like this:
192.168.0.1 www 10.10.0.4 www
In addition to that, host names instead of IP addresses are also allowed,
if you have a working DNS setup. The special IP address
allows rinetd to respond on all IP addresses that the server has been
configured for (The Linux kernel allows you to set up more than one IP
address for an interface, this is called "IP aliasing"). The forwarding
can either take place on one interface, or you can use two separate
network cards. This depends on the desired functionality.
By using ALLOW and DENY rules, you can effectively define access control to certain rules. Allow and deny rules that appear before the first forwarding rule are applied globally. If the address of a new connection matches one of the DENY rules or does not match any of the ALLOW rules, the connection is immediately rejected.
If ALLOW or DENY rules appear after a certain forwarding rule, they only apply to this specific rule.
By using patterns, you can easily match a broader range of IP addresses. Patterns can contain the following characters: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, . (period), ?, and *. The "?" wildcard matches any single character. The "*" wildcard matches any number of characters, including zero. For example, the line
matches all IP addresses in the 141.73.21 class C domain and would deny certain forwarding rules to take action.
Host names are not permitted in allow and deny rules, since host name lookups would dramatically decrease the performance. Because rinetd is a single process server, all other connections would be forced to pause during the address lookup. However, this should not be a serious shortcoming.
It is possible to create a log file about rinetd's forwarding activity. Moreover, it is able to produce a log file in two different formats: tab-delimited and web server-style "common log format." The latter is easier to parse by regular log-statistic tools.
By default, rinetd logs in a simple tab-delimited format containing the following information:
The following is a sample of rinetd's output:
30/Jun/1999:22:21:03 220.127.116.11 18.104.22.168 80 10.0.0.3 8080 0 0 not-allowed 30/Jun/1999:22:27:56 22.214.171.124 126.96.36.199 80 10.0.0.3 8080 262 0 done-remote-closed
If you prefer a web server-stylish "common log file format", you can add the following keyword to the configuration file:
This would produce the following output:
188.8.131.52 - - [30/Jun/1999:22:32:14 +0200] "GET /rinetd-services/184.108.40.206/80/10.0.0.3/80/done-local-closed HTTP/1.0" 200 1207 - - - 2 220.127.116.11 - - [30/Jun/1999:22:32:38 +0200] "GET /rinetd-services/18.104.22.168/80/10.0.0.3/80/done-local-closed HTTP/1.0" 200 1207 - - - 2
By default, rinetd does not produce a log file. To activate logging,
you need to add the following line to
Please take into account, that writing log files does also require resources on the host. Especially on a heavy-loaded server, the log file can grow significantly and the logging can slow down the forwarding of connections. You should also consider an automated log-rotating mechanism for easier maintenance.
Now let's go for a real-world example. A customer is running a firewall, which is supposed to protect his LAN from the outside world. It has an official IP address 22.214.171.124, which is assigned to one of two NICs. The internal network is using the IP address range 10.10.0.0/16. The customer is running a Web-Server in his internal network (10.10.0.8, Port 8080) and a mail server (10.10.0.2), where the employees can read their mail on the host by logging into the server via the secure shell (SSH). The customer would now like to give access to his WWW-server to a partner company, that is also connected to the Internet using the class C IP network 126.96.36.199/24. In addition to that, he wants to enable his employees to read mail while they are away from their offices. To make this connection a bit more "secure", the connect should take place on the usual telnet port (adding some obscurity does not help a lot, but it may confuse the unexperienced hacker). He also wishes to have a log file about the ongoing connection in the common log file format.
Here's the respective configuration file
# rinetd configuration file (/etc/rinetd.conf) # Allow http connects for all hosts from the partner company 188.8.131.52 www 10.10.0.8 8080 allow 141.73.4.* # Allow ssh connects on telnet port 184.108.40.206 telnet 10.10.0.2 ssh # Log the connections logfile /var/log/rinetd.log logcommon
This solution has one shortcoming: the internal web server does not recognize, which external host initiated the http connection, it only "sees" the firewall's internal IP address. If you need to have that information, you have to match the web server logfiles with the rinetd logfile on the firewall.
Please note, that this is just a simple example to explain the basic functionality of rinetd. It's really up to you and your imagination, how you can effectively utilize this helpful daemon for your purposes. It's possibilities are virtually unlimited!
Lenz Grimmer uses Linux since the 0.99.xx kernel era. After finishing
his studies in computer science, he worked as a system administrator
for an internet consulting agency, where he learned even more about
his favourite operating system. Since April 1998, he works for SuSE
GmbH in Nuremberg, Germany, Europe's biggest Linux distributor. Apart
from his daily work as a supporter and developer, he is the maintainer
of the SuSE FAQ (
http://www.suse.com/Support/Doku/FAQ/) and is also responsible
for some packages of the distribution (rinetd is one of them). You can
reach him via E-Mail at
Lenz.Grimmer@suse.de, or just follow the SuSE Linux
firstname.lastname@example.org, where he tries to be
present, as his time permits. To subscribe to this list, have a