"Linux Gazette...making Linux just a little more fun!"

What You Can Do with tcpd

By Kelly Spoon, mars@loeffel.txdirect.net

If you have read my article on security, then you know that tcpd can be used to keep people from getting on your machine, and, thusly, it makes a nice first line defense against Bad Guys. You also know that there is an extra option you can put in the /etc/hosts.allow and /etc/hosts.deny files that the man pages refer to as the "shell_command".

So....are you wondering what all you can do with the "shell_command" option?

Me too. According to the hosts_access man(5) page, you can use it to finger the person who is trying to get to your services. However, the feature that I think is pretty neat is that this gives you the ability to set up personalized banners for whenever someone tries to connect to your machine.

Here's the catch, though. In order to enable this option, you're going to need to recompile and turn this sucker on yourself. The binaries that your favorite Linux distribution installed on your machine probably weren't set up to take advantage of this neat little feature. (At least, they weren't on mine)

Getting and installing tcpd

The first thing you need to do is get a hold of is the source for tcpd. Here is where it's been hidden.

Those of you with keen eyes will note that the name of the file we have downloaded is tcp_wrappers*.tar.gz and not tcpd*.tar.gz. Don't sweat it, this really is the package you want.

tar -zxvf tcp_wrappers*.tar.gz will unpack everything for you into the tcp_wrappers_7.4 directory. It doesn't really matter where you do this, since after we have compiled and installed the binaries, we can get rid of this directory.

Go in there as root. Normally, all we have to do is type make, and Linux will automagically compile the program for us. However, we have to pass some extra options to the make with this program.

Unfortunately, the Makefile for tcpd doesn't have an install option, so you have to put things in place yourself. Here's a quick list of where things should go after you've compiled:

Bin File			Location on Your Machine
--------			-----------------------
safe_finger			/usr/sbin/real-daemon-dir/safe_finger
tcpd				/usr/sbin/tcpd
tcpdchk				/usr/sbin/real-daemon-dir/tcpd-chk
tcpdmatch			/usr/sbin/real-daemon-dir/tcpdmatch
try-from			/usr/sbin/real-daemon-dir/try-from
*.3				/usr/man/man3/*.3
*.5				/usr/man/man5/*.5
*.8				/usr/man/man8/*.8

As always, make sure you back up your *old* files before installing the new ones.

The Fun Part -- Banners and Other Stuff

Now that we have our new tcpd in place, it's time to get the frame work in place for our banners. You can do this in any directory on your machine, but, in keeping with my own warped view of where things belong, I suggest creating a dir called /etc/banners and using that for our homebase. And since I get to be the author, that's the dir I'm going to refer to.

Once we've got /etc/banners created, we're going to need to do this from the tcp_wrappers_7.4 dir:

cp Banners.Makefile /etc/banners/Makefile

And now that the hall is rented and the orchestra engaged, it is time to dance. (ObNiftyStarTrekQuoteThatI'veBeenDyingToUse)

Creating your banners

In order to make a banner, all you have to do is go into /etc/banners, and create a file called prototype. Put anything you want in here. It's your banner. Since this would be a good place for an example, here's what I put for my banner whenever someone is denied access to my machine:

                    This is a ^[[m^[[44;01mprivate^[[m^[[44m machine

          If you wish to access this machine, please send email to 

This prints out a nice looking little banner with the first 3 lines in blue, and the word "private" and root's email address set in bold. Looks pretty official.

Once you have created your prototype, then all you need to do is run a make in the /etc/banners directory. This will then produce 4 files (or more, depending on whether you've hacked the Makefile).

They are in.telnetd, in.ftpd, in.rlogind, and nul. What you need to do next is create another dir, and move these files into it. Since the above example is for the connections that get refused, I put these in /etc/banners/general-reject. The last thing to do is to move the in.* and nul into the new directory. It's also a good idea to stick your prototype in there in case you want to change the banner later on.

Making tcpd use the banners

This is the last step. I promise.

You need to edit your /etc/hosts.allow or /etc/hosts.deny files so that tcpd knows it should throw up a banner whenever someone tries to connect. Basically, my /etc/hosts.deny looks like this:

# /etc/hosts.deny for linux.home.net

ALL:	ALL except .home.net:	banners /etc/banners/general-reject

And that's it. You can now put up customized banners that will be shown based upon the hostname of the person who tries to connect to your machine. Finally, you can take advantage of the "shell_command" option listed in man 5 hosts_access. To see what else you can do with this, check out man 5 hosts_options.

And, if you're scratching your head wondering what's going on, keep reading.

Behind the Scenes

How tcpd Works

As you know, tcpd hangs around on your system and waits for something to wake it up. When that happens, it looks at /etc/hosts.deny and /etc/hosts.allow to see if the person who is trying to connect matches any of the patterns you have listed in these files. If it finds a match, then it either lets the connection go through, or it closes the socket. If it finds a match with a "shell_command" in it, then it will execute that command.

The banners option tells tcpd that it needs to send back a text message to the client that's trying to connect. When it sees banners in the allow or deny file, it goes into the directory that you listed (/etc/banners/general-reject in my example), and tries to find a file with the same name as the service that the client requested. If it finds a file, the contents of the file get pumped back down to the client, and then tcpd either closes the connection or lets it go through. It it doesn't find a file, then tcpd doesn't send anything back.

In plain English, if someone tries to telnet in (which would invoke in.telnetd) and you have a banners options listed for their entry in one of the hosts.* files, then tcpd looks for a file called /etc/banners/general-reject/in.telnetd. If it finds it, it displays the file, if not, ah well.

This is important to remember when setting up a banner for your ftp service. The Banners.Makefile will create a banner file called in.ftpd. Since most Linux distributions use the Washington University FTP server, the service name is actually wu.ftpd. Therefore, if you intend for your banner to also be shown to people trying to ftp to your machine, you either need to change the /etc/banners/general-reject/in.ftpd to wu.ftpd, or you need to change the name of the service.

The 2 Ways to Use tcpd

You generally have 2 choices on how tcpd protects your services: Let inetd handle it, or do a substitution. In my humble opinion, it's best to let inetd handle it.

As you may know, inetd is the "super server". It basically monitors a bunch of ports, and whenever it detects someone trying to use one of them, it starts up the service you have listed in inetd.conf. This is handy because you don't run what you don't need, and thusly, unused daemons aren't sucking up all your system resources.

inetd can be configured to launch tcpd before it starts up the service. In fact, if you take a look in /etc/inetd.conf, you'll see that it already does for many of your services. I'll pull one out so you don't have to flip over to a virutal console:

Service	Socket  Proto   Flags   User     Server name     Arguments
-------	------	-----	-----	----	-----------	---------
telnet  stream  tcp     nowait  root    /usr/sbin/tcpd  /usr/sbin/in.telnetd

The "Service" entry is just the name of the connection from the file /etc/services. This tells inetd what port to listen on.

The other entries that we're concerned about is the "Server Name" and "Arguments". "Server Name", as you can see, points to our good friend tcpd. Whenever inetd gets a request for the "Service", it starts up tcpd with the path to the actual service passed as an "Argument". This lets tcpd know what program to run if it exits and the client has permission to use the service.

See. It's pretty easy.

Your other option is to substitute tcpd for the service directly, and not even bother with inetd. To do this, you just move the daemon you want to protect to /usr/sbin/real-daemon-dir, and then either copy tcpd over to where the service used to be, or put in a symbolic link.

For example, let's say I want to use tcpd on /usr/sbin/in.telnetd. I would simply give the following commands:

mv /usr/sbin/in.telnetd /usr/sbin/real-daemon-dir/in.telnetd
ln -s /usr/sbin/tcp /usr/sbin/in.telnetd

This method is even eaiser than inetd, but I prefer not to have 30 million sym links laying around my system.

One Last Thing to Keep in Mind

Quoting directly from tcpd's man page:

       The  tcpd  program  can  be  set  up  to  monitor incoming
       requests for telnet, finger, ftp, exec, rsh, rlogin, tftp,
       talk,  comsat  and  other  services that have a one-to-one
       mapping onto executable files.

Check out that "...services that have a one-to-one mapping onto executable files" part.

What that means is that tcpd is designed to be used by services that spawn 1 daemon for 1 client. In other words, tcpd won't work for stuff like ircd or Samba. Luckily, these programs usually give you the option to deny access to certain hosts, which accomplishes the same thing as what tcpd does.

And In Closing...

For the answer to any questions you have that I didn't address, please check the README file that comes with tcp_wrapper. It does an excellent job of explaining what's going on, and how to take advantage of some other features (although some of it is ambiguous about exact locations of where config files should live due to the fact that the author created tcp_wrappers to work on a lot of different machines). Also peruse the Makefile sometime and see if there's anything else you want to turn on once you've got a good idea of how this all works.

And last but not least, the author of tcp_wrappers has given us a very useful tool free of charge. If you like it and use it, please take the time to send him a postcard (snail mail addy at the bottom of the README)....he's earned it.

Mail to:mars@loeffel.txdirect.net

Copyright © 1997, Kelly Spoon
Published in Issue 15 of the Linux Gazette, March 1997