| Local References (* works-in-progress) |
| Workstation | Security | Server | Other |
| Setting up custom terminal windows | * Explanation of inetd and rc.conf usage with links to hardening the box | Quick Perl setup within Apache Chroot of OpenBSD | Various loopback wiring diagrams |
| Making gtk-gnutella 0.93.3 on OpenBSD 3.3 | * IPF and the examples from /usr/share/ipf/ | Additional Setup for MySQL/Perl within Apache Chroot of OpenBSD | * ICMP types and codes |
Quick-Fix for using Perl's MySQL Modules within an OpenBSD Apache Chroot
Original: February 8, 2004
Updated: February 10, 2004
Introduction
There's not enough detail given here, use at your own risk, and all that stuff. Basically, this is a quick-n-dirty way to make Perl CGI scripts that use DBI and DBD/mysql work within the Apache Chroot of OpenBSD. There are likely files that are copied here which won't be needed in all installs, something to look into if you've got a specific need - but if you're contemplating passing httpd the -u flag to make Perl MySQL calls work this will likely be the safer route.
This document is similar to one on making Perl work within an Apache Chroot. In fact those steps are a subset of the ones in this document. For those that either want to lessen the number of files added to the chroot, or are trying to work out something other than the Perl/MySQL combination, I've included notes on how I arrived at these particular instructions. The short description is that I gave it every file it requested as recorded by systrace -A.
Steps
The assumptions made are that the Apache Chroot is /var/www, all currently installed Perl and Apache Modules are to be copied, and that paths should mimic the system layout so that CGIs in the chroot specify the same paths they would outside the chroot - this essentially means mapping /usr/dir to /var/www/usr/dir. Also, it should go without saying, you'll need to su - first to have sufficient permissions. Additionally, you must know how to use ports and install packages.
cd /var/www
mkdir -p var/run
cd var/run
mkdir mysql
chown _mysql:_mysql mysql
cp /var/run/ld.so.hints .
cd /var/www
mkdir -p usr/share
cp -R /usr/share/zoneinfo usr/share
cp -R /usr/share/nls usr/share
mkdir -p usr/local/lib
cd usr/local/lib
cp -R /usr/local/lib/mysql .
ln -s mysql/libmysqlclient.so.10.0 libmysqlclient.so.10.0
cd ..
mkdir -p share
cp -R /usr/local/share/mysql share
cd ../lib
cp /usr/lib/libz.so.2.0 .
cd ..
mkdir -p etc
cp /etc/services etc
if [ X"${mysql}" != X"NO" -a -x /usr/local/bin/safe_mysqld ]; then
echo -n ' mysqld'
/usr/local/bin/safe_mysqld --socket=/var/www/var/run/mysql/mysql.sock &
if [ ! -L /var/run/mysql/mysql.sock ]; then
mkdir -p /var/run/mysql
chown _mysql:_mysql /var/run/mysql
chmod 711 /var/run/mysql
ln -s /var/www/var/run/mysql/mysql.sock /var/run/mysql/mysql.sock
fi
fi
Additional Notes
It turned out to be a bigger pain than I had expected making use of DBI with DBD::mysql under Perl, within a Chroot'd Apache. The main problem was that there was no useful warnings or errors output, a test script simply stopped cold. After copying the files I thought would be required, and adding warns to DBI.pm and DBD/mysql.pm, I narrowed the problem to one line:
bootstrap DBD::mysql $VERSION;
within usr/local/libdata/perl5/site_perl/i386-openbsd/DBD/mysql.pm. I didn't know what that was supposed to be doing, so it didn't really help. I wasn't even that sure I knew which module had that function.
So I turned to systrace. First I populated a temporary directory right off the root partition, with the appropriate contents from within the chroot, essentially just the path to the virtual host, and the script and what custom stuff it needed. This allowed me to run the script from the command line successfully. systrace -A ./script.cgi put a nice log of every system call into $HOME/.systrace. Since I also knew the /var/www/usr/libdata and /var/www/usr/local/libdata directories contained a fresh mirror of the originals, grep out lines that match and the resulting list of files shrank considerably. I was a literal generous, for example, copying /usr/share/zoneinfo when only my timezone file was actually read.