Setting up Amavisd to run chroot on OpenBSD

Over on The Register, I’ve been doing a series of articles about setting up your own email server with spam and virus filtering. You can find them here: part 1, part 2, part 3.

In the third part, I show how to set up a basic Amavis configuration, which is a spam filter that calls on ClamAV to check for viruses, and SpamAssassin to check for junk mail. On my own system, I run this in a chroot environment, which means that if there were some flaw discovered, there are a few extra hoops to jump through for a successful exploit.

However, setting up everything to run chroot is pretty involved, and the article on The Register is already 50% longer than originally anticipated. So, the details of how to set things up to run chroot are here instead.

First. you’ll need to edit the /etc/fstab file, as the chroot environment requires that we create some device nodes. We’re putting everything under /var/amavisd and by default, you can’t created devices anywhere other than on the main file system. So edit fstab and you’ll see a line referring to /var, something like

a54919c2f4ea97d7.e /var ffs rw,nodev,nosuid 1 2

Remove the ‘nodev’ and the comma following it, and save the file. Then reboot the system, and you’re almost ready to set up the chroot environment. The code below is based on using OpenBSD 5.7 and the packages installed automatically when you add Amavisd to your system. If you’re using a later version, the library files will very likely have different version numbers.

You can either copy this script and save, then run it. Or you can simply type all the commands, omitting the ‘echo’ and ‘read’ ones. Click here to download it as a text file: chroot_config.txt

# Amavisd setup script
#
# This script will create the necessary directories for Amavisd
# and copy the files needed for it to run in a secure chroot
# environment
# 
# Either run this script by typing sh amavisd-setup
# or type each of the commands in the main section in turn
# (you don't need to type the echo commands!)
#
# This version: for Open BSD 5.7
# Prepared September 2015
# If you use different versions of the packages, you will need
# to check the library versions

echo 'Preparing the amavisd chroot environment'

echo 
echo 'Remember you need to edit the fstab file first!'


read cont?'Press Enter when you are ready to continue or Ctrl-C to exit'

# main section

# create directories and special files
echo 'Creating directories and special files'

mkdir -p /var/amavisd/tmp
chown _vscan:_vscan /var/amavisd/tmp
chmod 750 /var/amavisd/tmp
mkdir /var/amavisd/quarantine
chown _vscan:_vscan /var/amavisd/quarantine
chmod 750 /var/amavisd/quarantine

cd /var/amavisd
mkdir -p etc dev tmp var/run var/log bin var/run var/dcc var/db/clamav var/virusmails .razor .spamassassin
mkdir -p usr/bin usr/sbin usr/share/zoneinfo usr/lib usr/libexec usr/local/share/clamav usr/local/lib

chown -R _vscan:_vscan usr/local/share var/log var/dcc .spamassassin
chmod -R 744 usr/local/share/clamav var/log
chmod 755 usr/local/share

mknod dev/null c 2 2
mknod dev/urandom c 45 2

ln -s / var/amavisd

# copy special files for chroot environment
echo 'Copying special files'

cp /etc/protocols etc
cp /etc/services etc
cp /etc/hosts etc
cp /etc/magic etc
cp /etc/resolv.conf etc
cp /etc/group etc
cp /etc/passwd etc

# copy executable files
echo 'Copying program files'

cd /usr/bin
cp ar file gzip uncompress /var/amavisd/usr/bin
cp /bin/pax /var/amavisd/usr/bin
cd /usr/local/bin
cp arc bzip2 cabextract clamdscan clamscan freshclam lha lzmadec lzop lz4c ripole rpm2cpio xzdec zoo 7z 7za 7zr /var/amavisd/usr/bin
cp /usr/local/sbin/clamd /var/amavisd/usr/sbin

# copy library files required
# get the list of libraries for each program with ldd, eg ldd bzip2
echo 'Copying library files'

cp /usr/lib/libc.so.78.1 /usr/local/lib/libbz2.so.10.4 /usr/lib/libssl.so.32.0 /usr/lib/libcrypto.so.32.0 /usr/lib/libpthread.so.18.1  /usr/local/lib/libclam* /usr/local/lib/libxml2.so.15.1 /usr/lib/libz.so.5.0 /usr/local/lib/liblzma.so.2.0 /usr/local/lib/libiconv.so.6.0 /usr/lib/libm.so.9.0 /usr/local/lib/libltdl.so.5.0 /usr/local/lib/liblzo2.so.0.0 /usr/lib/libiberty.so.12.0 /usr/lib/libstdc++.so.57.0 /var/amavisd/usr/lib
cp /usr/libexec/ld.so /var/amavisd/usr/libexec

cd /var/amavisd
cp -R /usr/local/share/spamassassin usr/local/share
cp -R /usr/local/lib/p7zip usr/local/lib

# copy config files
cp /etc/freshclam.conf /etc/clamd.conf /var/amavisd/etc
cp -R /etc/mail/spamassassin /var/amavisd/etc

# other final tasks
echo 'Finishing up - setting permissions'

# set up the password file
echo '_vscan:*:530:530::0:0:Amavisd-new Daemon:/var/amavisd:/sbin/nologin' > /var/amavisd/etc/master.passwd
pwd_mkdb -d /var/amavisd/etc -p /var/amavisd/etc/master.passwd

# set file permissions
cd /var/amavisd
chown -R root:wheel etc dev tmp usr var
chown -R _vscan:_vscan .spamassassin .razor quarantine var/dcc
chmod 1777 tmp
chmod 666 dev/null
chown _vscan:_vscan /var/amavisd /var/amavisd/var/db/clamav /var/amavisd/db /var/amavisd/var/virusmails
chmod 750 /var/amavisd

# create basic permission lists
echo 'nigel@nigelwhitfield.com' > /var/amavisd/whitelist
echo 'postmaster@mydomain.com' > /var/amavisd/spam_lovers
echo 'gorby@kremvax.ru' > /var/amavisd/blacklist
chown _vscan:_vscan whitelist blacklist spam_lovers

# that's it
echo 'Setup finished. Please remember to check your configuration files'

You now need to edit the amavis.conf file, and tell it to run in a chroot environment. Make sure that the $MYHOME variable is set to /var/amavisd, and then find the line that says something like

$daemon_chroot_dir = $MYHOME;   # chroot directory or undef, -R

By default, this has a # at the start to comment it out. Remove the # to run in chroot mode. You also need to change the startup scripts for clamd and freshclam, to tell them to run in the chroot environment. In /etc/rc.d/freshclam edit the line

daemon="/usr/local/bin/freshclam -d"

to read instead

daemon="chroot /var/amavisd /usr/bin/freshclam -d"

and then edit /etc/rc.d/clamd changing

daemon="/usr/local/sbin/clamd"

to

daemon="chroot /var/amavisd /usr/sbin/clamd"

In the versions of freshclam.conf and clamd.conf in /var/amavisd/etc, change the User (in clamd.conf) and DatabaseOwner (in freshclam.conf) from _clamav to _vscan

Now, you can restart and amavisd should run in the chroot environment, and still detect all the tools on which it relies. You don’t need to change anything in the Postfix config files.

There are some things to watch out for – you need enough space on the /var filesystem to download the virus definitions, and depending on the size of your disk, it may be quite full already, especially if you’ve been running ClamAV without chroot. If you see an error from freshclam in the log, complaining about not being able write a file, that’s probably the cause. Just delete the files from the original database (/var/db/clamav) to save space.

Is it worth all this work to run chroot? Actually, the more I think about it, the less convinced I am, really. Since none of the parts of the mail system run as root anyway, I think you’d probably be almost as safe running without it, really, and making sure all the permissions and links are setup is a pain; I daresay I’ve missed something obvious in the script above.

Leave a Reply

Your email address will not be published. Required fields are marked *