Thin Jail
FreeBSD's manpage on setting up a jail speaks thusly:
In many cases this example would put far more stuff in the jail than is needed. In the other extreme case a jail might contain only one single file: the executable to be run in the jail. We recommend experimentation and caution that it is a lot easier to start with a ``fat'' jail and remove things until it stops working, than it is to start with a ``thin'' jail and add things until it works.
If the application one intends to run is packaged simply, then it really isn't too difficult to start with a "thin" jail. In this example, the single executable to be jailed is simple_httpd, part of the PicoBSD distribution.
A FreeBSD jail is started by running its /etc/rc script. The regular version of that does a whole bunch of stuff and is supported all those other /etc/rc* files you see in a standard-issue FreeBSD host or jail. To run just one binary, though, /etc/rc can be very simple:
#!/bin/sh /usr/bin/su www -c "/usr/libexec/simple_httpd"
This runs simple_httpd as the user www, because, as always, one doesn't want the application to run as root, where possible, even in a jail.
This simple script also tells us what other executables are needed:
# ls -l bin usr/bin bin: sh usr/bin: su #
Following convention, simple_httpd will live in /usr/libexec. It needs the ELF image loader ld-elf.so.1 in the same directory.
# ldd simple_httpd
simple_httpd:
libc.so.4 => /usr/lib/libc.so.4 (0x28072000)
#
simple_httpd itself needs libc.so.4 to run. The other dynamically-linked binary in the jail, /usr/bin/su, needs these:
# ldd su
su:
libutil.so.3 => /usr/lib/libutil.so.3 (0x28072000)
libskey.so.2 => /usr/lib/libskey.so.2 (0x2807b000)
libmd.so.2 => /usr/lib/libmd.so.2 (0x28082000)
libcrypt.so.2 => /usr/lib/libcrypt.so.2 (0x2808b000)
libc.so.4 => /usr/lib/libc.so.4 (0x280a4000)
#
So let's copy all these .so files into the jail's /usr/lib. Of course, one may also build a statically-linked version of su, alternatively. But anyways, here is /usr/lib:
# ls usr/lib libc.so.4 libm.so.2 libskey.so.2 libcrypt.so.2 libmd.so.2 libutil.so.3 #
What about device special files? As it turns out, simple_httpd needs none.
Next, let's look at /etc:
# ls -l etc total 88 -rw-r--r-- 1 root wheel 94 Oct 9 00:32 group -rw------- 1 root wheel 182 Oct 9 00:56 master.passwd -rw-r--r-- 1 root wheel 172 Oct 9 00:56 passwd -rw-r--r-- 1 root wheel 40960 Oct 9 00:56 pwd.db -rw-r--r-- 1 root wheel 92 Oct 9 22:16 rc -rw------- 1 root wheel 40960 Oct 9 00:56 spwd.db
The files passwd, pwd.db and spwd.db are generated by vipw operating on master.passwd, which itself contains two entries:
root:*:0:0::0:0:Charlie &:/root:/bin/csh www:*:80:80::0:0:World Wide Web Owner:/pkg/simple_httpd:/bin/sh
The file group also contains two entries:
wheel:*:0:root www:*:80:
From the entry in master.passwd, we see that the home directory of simple_httpd is /pkg/simple_httpd. Set up this directory following the instructions in simple_httpd's README file.
Getting there now: Edit /usr/local/etc/jailadmin.conf in the host to include this jail, which I've called nano. Then start it up:
# jailadmin start nano Starting server nano... # jailadmin status nano Server: nano USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND www 435 0.0 0.2 876 412 p3 SJ 10:49PM 0:00.00 /usr/libexec/simple_httpd #
By default, simple_httpd listens on port 1080 if it isn't root. Check it out:
$ telnet 192.168.xx.xx 1080 Trying 192.168.xx.xx... Connected to 192.168.xx.xx. Escape character is '^]'. GET / HTTP/1.0 HTTP/1.0 200 OK Server: FreeBSD/PicoBSD simple_httpd 1.1 Date: Sat, 09 Oct 2004 14:54:20 GMT Content-type: text/html Last-Modified: Fri, 08 Oct 2004 16:47:20 GMT <html> <head> <title>Nano Nano</title> </head> <body> <p> Welcome to the nano-simple_httpd-jail! </p> </body> </html> Connection closed by foreign host.
Let's take a look at simple_httpd's logging:
14:55:06 09/10/104 (192.168.xx.xx) GET / HTTP/1.0
Hey! Not Y2K compliant! ;-)
Of course, running a simple file-serving httpd isn't very exciting. It will be more fun to run a Common Lisp or Smalltalk web application server, with ssh access, in a minimalist jail, but that will be a story or five for other days...