Chrooting sendmail on FreeBSD
Brian M. Clapper, bmc @ clapper . org
$Id: sendmail-chroot.html 6964 2007-08-12 15:24:39Z bmc $
Introduction
This document outlines a procedure for running the open source
sendmail SMTP server in a
chroot'd area on FreeBSD.
It is specific to sendmail version 8.12. I developed this
document while chrooting sendmail on a
FreeBSD 4.8 system. With minor modifications, these procedures should work
with other configurations; as usual, of course,
YMMV.
Before attempting to follow these instructions, you should read all
pertinent documentation for sendmail. Start with the README file
in the top-level directory of the unpacked sendmail sources.
Feel free to send any suggestions, corrections, or enhancements to this
document directly to me, at the above email address.
Chrooting Sendmail
- Log in as, or su(8) to, root.
- Decide where you're going to create the chroot
directory structure. This document assumes you'll be using
/usr/local/chroot/sendmail, but you're obviously free
to substitute some other directory.
- Create the directory tree. You'll need the following directories, with
the following permissions. Note: If you're using the sendmail
"runAsUser" feature, to run sendmail as a non-root user, some of
the directories must be owned by that user, rather than by root.
Those directories are marked with an asterisk ("*") in the table
below. (The "runAsUser" feature is controlled by sendmail
configuration option "O RunAsUser=user". See the
sendmail configuration README file, located in
sendmail-source/cf/README, for details.)
| Directory |
Permission Mode |
Owner |
Group |
| /usr/local/chroot/sendmail/bin |
0755 (drwxr-xr-x) |
root |
wheel |
| /usr/local/chroot/sendmail/etc |
0755 (drwxr-xr-x) |
root |
wheel |
| * /usr/local/chroot/sendmail/etc/mail |
0755 (drwxr-xr-x) |
root (or the "run-as" user) |
wheel |
| /usr/local/chroot/sendmail/usr |
0755 (drwxr-xr-x) |
root |
wheel |
| /usr/local/chroot/sendmail/usr/lib |
0755 (drwxr-xr-x) |
root |
wheel |
| /usr/local/chroot/sendmail/usr/sbin |
0755 (drwxr-xr-x) |
root |
wheel |
| /usr/local/chroot/sendmail/usr/bin |
0755 (drwxr-xr-x) |
root |
wheel |
| /usr/local/chroot/sendmail/usr/libexec |
0755 (drwxr-xr-x) |
root |
wheel |
| /usr/local/chroot/sendmail/tmp |
01777 (drwxrwxrwt) |
root |
wheel |
| /usr/local/chroot/sendmail/var |
0755 (drwxr-xr-x) |
root |
wheel |
| /usr/local/chroot/sendmail/var/run |
0755 (drwxr-xr-x) |
root |
wheel |
| /usr/local/chroot/sendmail/var/spool |
0755 (drwxr-xr-x) |
root |
wheel |
| /usr/local/chroot/sendmail/var/spool/clientmqueue |
0770 (drwxrwx---) |
smmsp |
smmsp |
| * /usr/local/chroot/sendmail/var/spool/mqueue |
0755 (drwxr-xr-x) |
root (or the "run-as" user) |
daemon |
| /usr/local/chroot/sendmail/dev |
0755 (drwxr-xr-x) |
root |
wheel |
- Copy /bin/sh and /bin/ls (which are statically
linked) to the /usr/local/chroot/sendmail/bin directory.
Note: This is temporary. Having a shell and the ls(1)
command in the chrooted area can be helpful for debugging. You'll
delete these files later.
- Copy /etc/master.passwd, /etc/passwd and
/etc/group to the
/usr/local/chroot/sendmail/etc directory.
- With your favorite text editor, pare down master.passwd
and passwd so they contain only the following users:
root
daemon
smmsp
mailnull
nobody
- Move the edited /usr/local/chroot/sendmail/etc/master.passwd
to a temporary file. (I'll use "/tmp/foo").
It'll be rebuilt in the next step.
- Update the password database in your chroot'd area by
running the pwd_mkdb(8) command, as shown below:
# pwd_mkdb -d /usr/local/chroot/sendmail/etc /tmp/foo
- Edit /usr/local/chroot/sendmail/etc/group, paring it down to
the following groups:
wheel
daemon
mail
smmsp
mailnull
nogroup
nobody
- Copy /etc/services, /etc/resolv.conf and
/etc/localtime to directory
/usr/local/chroot/sendmail/etc/
- Copy /etc/hosts to directory
/usr/local/chroot/sendmail/etc/. Make sure
there's an entry for each of the local IP addresses, plus
127.0.0.1. If your sendmail configuration also refers to other
IP addresses, then you'll need entries for those, as well. For
example:
127.0.0.1 localhost localhost.example.org
192.168.1.1 inside-ip inside-ip.example.org
192.168.1.2 inside-mail-relay inside-mail-relay.example.org
- Copy /etc/host.conf to directory
/usr/local/chroot/sendmail/etc/. It should look like
this:
hosts
bind
- Create /usr/local/chroot/sendmail/dev/null, using the
mknod(8) command. First, take a look at the existing
/dev/null, and be sure to match the major and minor
numbers.
# ls -l /dev/null
crw-rw-rw- 1 root wheel 2, 2 Apr 11 10:11 /dev/null
# mknod /usr/local/chroot/sendmail/dev/null 2 2 root:wheel
- Copy /usr/lib/libc.so.4 and /usr/lib/libutil.so.3
to directory /usr/local/chroot/sendmail/usr/lib.
- Copy /usr/libexec/ld-elf.so.1
to directory /usr/local/chroot/sendmail/usr/libexec.
- Verify that the chroot area is set up properly by firing
up a chroot'd shell:
# chroot /usr/local/chroot/sendmail /bin/sh
-r-xr-sr-x 1 root smmsp 516944 Apr 9 13:17 /usr/local/chroot/sendmail/usr/sbin/sendmail
- Copy /usr/libexec/sendmail/sendmail to directory
/usr/local/chroot/sendmail/usr/sbin. Make sure it
has the following permissions:
# ls -l /usr/local/chroot/sendmail/usr/sbin/sendmail
-r-xr-sr-x 1 root smmsp 516944 Apr 9 13:17 /usr/local/chroot/sendmail/usr/sbin/sendmail
- Copy /usr/sbin/mailstats and /usr/sbin/makemap
to /usr/local/chroot/sendmail/usr/sbin. Both should be
owned by root, have group wheel, and mode 0755.
- In directory /usr/local/chroot/sendmail/usr/bin,
create two symlinks:
# cd /usr/local/chroot/sendmail/usr/bin
# ln -s ../sbin/sendmail mailq
# ln -s ../sbin/sendmail newaliases
(This step probably isn't strictly necessary, but it doesn't hurt.)
- Copy the contents of your existing /etc/mail directory to
/usr/local/chroot/sendmail/etc/mail. Note: If you're
using the "run-as" feature, you must ensure that the various
"*.db" files are owned by that user.
- In the real file system (not the chroot'd area), replace
/etc/mail, /var/spool/mqueue, and
/var/spool/clientmqueue with symlinks to their counterparts
in the chroot'd area. This step isn't required, but it
allows you to use commands like mailq(1) without being
in the chroot'd area.
- Next, you need to edit /etc/rc.conf, to:
- ensure that syslogd(8) creates a Unix socket in the
chroot'd area, so sendmail can issue its log
messages, and
- have sendmail run in the chroot'd area
To do that, make sure /etc/rc.conf contains these entries:
SENDMAIL_TOP=/usr/local/chroot/sendmail
sendmail_program="chroot $SENDMAIL_TOP /usr/sbin/sendmail"
sendmail_pidfile=$SENDMAIL_TOP/var/run/sendmail.pid
sendmail_mspq_pidfile=$SENDMAIL_TOP/var/spool/clientmqueue/sm-client.pid
sendmail_flags="-bd -q15m"
syslogd_flags="-s -l $SENDMAIL_TOP/var/run/log"
- At this point, you should be ready to try your chroot'd
sendmail. Run this command:
# sh /etc/rc.sendmail restart
- Examine /var/log/maillog, and use ps(1), to verify
that sendmail has come up properly. Send some test email
messages. Once you're sure sendmail is running fine,
remove /usr/local/chroot/sendmail/bin/sh
$Id: sendmail-chroot.html 6964 2007-08-12 15:24:39Z bmc $