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)
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.
tells tcpd where to look for the *real* daemons to use when you try to use the « easy » tcpd method. More on that after we get the sucker installed.
This is the whole reason we’re recompiling tcpd in the first place. This option enables tcpd to use the « shell_command » feature, which in turn lets use do the banners.
This just tells the compiler to use all the options that will produce a working binary for Linux.
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.
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:
^[[44m***************************************************************** This is a ^[[m^[[44;01mprivate^[[m^[[44m machine *******************************************************************^[[m If you wish to access this machine, please send email to ^[[email@example.com^[[m
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.
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.
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.