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.