www_mr72_com.gif
 

HTTPD in chroot'd environment

OpenBSD currently ships with a highly modified version of the Apache webserver as part of the default install. The folks who develop OpenBSD feel that Apache contains many security holes and/or potential security holes. While they have addressed many of these issues in the httpd server that ships with OpenBSD, they have also sought to minimize the impact of any holes that may still exist in the server by modifying it to run in a chroot'd environment.

Essentially, this means that httpd (thus any users connecting to the machine via http/s) will have access ONLY to resources that exist within the directory to which httpd is chroot'd. By default, this directory is /var/www, though it is easy to change that in httpd.conf or with command line options when starting the server (see man httpd).

The immediate impact I noticed by using chroot'd httpd is that NONE of my CGI scripts nor programs worked. In hindsight, the man page gave me all of the information I needed to get this to work, but at the time, it was not entirely clear what I needed to do.

There are two options: 1) run httpd in non-chroot'd mode by using the -u option when starting httpd, or 2) copying the necessary resources into the directory to which httpd is chroot'd. If security is not an issue, Option 1 may be your best solution. However, my opinion is that most folks who use OpenBSD do so (at least in large part) because of it's security features... therefore let us proceed with Option 2.

Turns out it is easy:

Since the majority of the CGI I write is in Perl, I will use that as an example.

ldd `which perl` at the command line produces the following output: (as of OpenBSD 3.9, type ldd command or ldd /path/to/command)

        Start    End      Type Ref Name
        00000000 00000000 exe   1  /usr/bin/perl
        02009000 22026000 rlib  1  /usr/lib/libperl.so.8.1
        069fe000 26a05000 rlib  1  /usr/lib/libm.so.1.0
        0e81a000 2e81f000 rlib  1  /usr/lib/libutil.so.9.0
        0267b000 226b4000 rlib  1  /usr/lib/libc.so.30.3
        0badb000 0badb000 rtld  1  /usr/libexec/ld.so

As my httpd is chroot'd to /usr/web, I have copied the above files to the following locations:

/usr/web/usr/bin/perl
/usr/web/usr/lib/libperl.so.8.1
/usr/web/usr/lib/libm.so.1.0
etc.

Any Perl modules needed by scripts will also need to be copied into the directory. The easy way to accomplish (all or most of) this is to copy the directories (and all contents, of course) "/usr/libdata/perl5" and "/usr/local/libdata/perl5" in the same manner as the executable and lib example above. Of course, you may have modules located elsewhere as well... so there may be more locations you need to copy.

A cleaner method would be to copy, one by one, modules that are needed in your scripts. It is up to you.

I have done the same for mysql, and a few other programs that I use in CGI scripts. The key is to look in the httpd error logs to see what your scripts/programs are missing and copy those items over.

If you are running mysqld on the same machine on which httpd is running, it will be necessary to tell mysql to look for mysqld not locally, but rather to treat it as remote. In most cases that means referring to the database to connect to not as "databasename" but as "databasename:server.name" or "databasename:ip_address" or "databasename:127.0.0.1"

Of course, it does not hurt to check out the official documentation :-)