From Nick Moffitt on 23 Sep 1998
You mentioned that you might mail me some example conf files to show me how you did all those nifty things we talked about on Saturday. I'm actually working on setting up a chrooted system for public use here at Penguin, so any examples would be keen (and no, I haven't searched through the answer guy archives yet).
[Question stems from a discussion over beer and pizza at one of the local user's groups events in my area. It relates to using TCP Wrappers to launch different services or different variations of a given service depending on the destination address of the incoming request. Normally TCP Wrappers, all those funny looking "/usr/bin/tcpd" references in your /etc/inetd.conf file, is used to limit which hosts can connect to a service by matching against the source address]
Here's a couple of trivial examples (I don't have a copy of 'chrootuid' handy on this box, but you can find it at cs.purdue.edu's "COAST" security tools archive).
# hosts.allow This file describes the names of the hosts which are # allowed to use the local INET services, as decided # by the '/usr/sbin/tcpd' server. # $Revision: 1.2 $ by $Author: lg $ on $Date: 2002/10/09 22:24:28 $ # in.ftpd: 127.0.0.1: ALLOW email@example.com: firstname.lastname@example.org: ALLOW in.ftpd: ALL: DENY email@example.com: ALL: twist /bin/echo "Not Available\: Go Away!" in.ftpd: 192.168.1.: ALLOW ALL: 127.0.0.1 ALL: 192.168.1.
These are order dependent. The first rule that matches will be one one that tcpd uses --- so the ALL: rules at the bottom are significant. If I put them first -- they'd over-ride the more specific ones --- whereas here, they don't.
In this case my "normal" IP address on eth0 is 192.168.1.3 (canopus.starshine.org). For playing with tcpd I add an eth0:1 alias (ifconfig eth0:1 192.168.1.127). That would work as easily if it was a second interface --- ethernet, PPP or whatever.
Now, if I telnet localhost or telnet to canopus, everything works fine. But if I telnet to the ...127 address it tells me to go away. The hosts_options and the hosts_access(5) man pages list a number of replacement operators like %a for the source IP address of the request and %d for the "daemon" name (argv of the process). These parameters can be used in the shell commands.
Note that the "twist" option is completely different than the "spawn" option. "spawn" seems to imply "ALLOW" and spawns a process that is run in addition to the service. This process is spawned with it's standard file descriptors all set to /dev/null --- so it doesn't interact with the user at all.
The twist option runs an alternative to the requested service. Thus, if you request my web server I might "twist" that into a cat command what will spit out an HTTP redirect with a simple 'echo' or 'cat' command like so:
firstname.lastname@example.org: ALL: twist /bin/cat /root/web.redirect
I don't know of a way to to call for both a twist and a spawn -- but you can write a script (or better, a small C wrapper) to run the desired "spawn" commands in the background (with outputs directed to /dev/null, of course).
Naturally, of course, you'll want to follow proper coding practices for "hostile" environments when you're writing something that will be "exposed" to the Internet.
Matt Bishop, at the UC Davis has some excellent papers on this topic, and presents his own, more robust, implementations of the system(), and popen() library calls --- which are called msystem(), and mpopen() in his library.
Matt's site is at: ftp://nob.cs.ucdavis.edu/pub/sec-tools (I think there's a web site there, too).