« XMail No Root | Main | AES »

09 October 2004

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...


Posted by ngps at 23:09 | Comments (0) | Trackbacks (0)
Comments
There is no comment.
Trackbacks
Please send trackback to:http://sandbox.rulemaker.net/ngps/133/tbping
There is no trackback.