It's actually pretty straightforward to get Sendmail running as an unprivileged user on your mail relay servers. There's just a little bit of system reconfiguration & then a new configuration directive in your Sendmail configuration file.
One of the negative criticism on Sendmail from a security point of view is that the MTA daemon that's listening on port 25 is running with root privileges. The problem there is that if there's a remotely exploitable vulnerability in it, then the attacker instantly gets root privileges, allowing them to do anything at all on the system. It turns out, however, that when you have a mail server that is operating purely as a mail relay, a machine that is always just forwarding email & never actually doing local delivery or alias expansion, it is possible to run Sendmail as an unprivileged user. Other MTA daemons like Postfix & QMail already run as non-privileged users in their default configuration. This is one of the architectural advantages these mail systems have over Sendmail from a security perspective.
To understand where it is appropriate to run Sendmail as an unprivileged user, consider the reasons why it runs as root:
- Only processes running as root are allowed to bind to network ports below 1024, at least on Unix machines. So the MTA daemon needs to be root in order to bind to port 25/tcp, the default SMTP port.
- When Sendmail is performing local delivery, it needs to be root so that it has appropriate privileges when appending email to different user's mailboxes, reading & executing the instructions in user .forward files & handling aliases that execute external programs.
- Various Sendmail configuration files & directories, like the aliases database & the mail queue directory, are only accessible to the root user. Sendmail must run as root to access this information.
The first point doesn't seem to be much of an obstacle. There are many daemons;Apache, BIND, etc;that are initially started with root privileges so that they can bind to a low port number, but which then subsequently give up root privileges when handling incoming service requests. Sendmail actually includes similar functionality. The third point doesn't seem that difficult to handle either. The work-around here is to simply identify the directories Sendmail needs to operate in & then make sure to properly set the permissions & ownerships on those directories so that they're accessible only by the special unprivileged user that the Sendmail daemon will be running as.
The second point is the show-stopper in many cases. If the machine is performing local delivery, then it can be difficult to get around the need to have the Sendmail MTA running as root. However, these days it's becoming increasingly rare for organizations to use their Unix Sendmail servers for local delivery. In most cases, Sendmail is used as a pure relay, ie. the machines that move incoming Internet email into an organization's internal mail infrastructure & vice-versa. Since these machines just flip email from one machine to another & never do any part of the normal local delivery process, we can simply ignore any privilege requirements in this case. Happily, these mail relay systems are also typically the machines where we are most concerned about security, since they are the machines that speak directly to other Internet connected hosts & which are in the most vulnerable positions in our network architecture.
The first step is to create a new user ID & group ID that your Sendmail MTA daemon will run as. Do not use the special "smmsp" user & group that the MSP uses, create a new user & group ID. We will create a user & group called "sendmail" with UID & GID 24 (smmsp is usually UID & GID 25). Nobody will ever actually log in as this user, so you can lock the password entry & use an invalid shell & home directory. Here are some sample commands you can use for setting up this user & group, assuming your system supports the traditional useradd & groupadd commands:
Note that you need to create the new group first, because we're going to use that group as one of the arguments to the useradd command. As you can probably guess, the "-u" & "-g" options are used to specify the user ID & group ID for the new user & group. The "-d" option specifies the home directory for the new user & the "-M" option tells the useradd command not to create this directory, since it already exists. The "-s" option specifies the default command shell for the user;here /dev/null is an invalid shell to help prevent user logins via this account. Note that some useradd commands refuse to allow you to specify a shell that isn't listed in /etc/shells.groupadd -g 24 sendmail
useradd -u 24 -g 24 -M -d /var/spool/mqueue \
-s /dev/null sendmail
Now we've to work with ownerships & permissions of various files & directories. It's a good idea to shut down the running Sendmail daemon so that it doesn't get confused while you're in the middle of making your changes. On most systems the commands "/etc/init.d/sendmail stop" or "pkill sendmail" will work.
There are really two critical directories for the MTA process: the queue directory (/var/spool/mqueue) & the /etc/mail configuration area. The following commands should set appropriate permissions on these directories:The queue directory should be owned by whatever user & group you created to run the MTA daemon ie "sendmail" & "sendmail" here. The permissions on the /var/spool/mqueue directory should already be mode 700.chown -R sendmail:sendmail /var/spool/mqueue
chmod 700 /var/spool/mqueue
chgrp -R sendmail /etc/mail
chmod -R g+r /etc/mail
chmod g+s /etc/mail
You still want the /etc/mail directory & the files in it to be owned by root, because you only want legitimate system administrators to be messing around with these files. But we need to make sure that the files in this directory are at least readable by the MTA daemon when it's running unprivileged. So what we're going to do is change the group ownership on the directory & its contents to our "sendmail" group & then use "chmod -R g+r /etc/mail" to give group read permissions to everything in the directory. Actually, the files in there are probably already group readable.
The last "chmod g+s /etc/mail" command adds the "set-GID" bit onto the /etc/mail directory. On Unix systems, if set-GID is set on a directory, then any new file created in that directory will automatically inherit the group ownership of the directory. In this way we can make sure that any newly created files end up with the proper ownerships, like when you're rebuilding your access DB or mailertable & virtusertable databases with the makemap program.
Note that if you're on a platform that keeps the aliases database in the /etc directory instead of /etc/mail, then you'll want to run the command "chgrp sendmail /etc/aliases*" in addition to the commands you see on this slide. You would need to issue the same command every time you rebuilt the aliases database, but since we are assuming that the mail relay we're configuring never actually looks at its alias database then this shouldn't really be an issue.
Tweaking Sendmail configuration: - The RUN_AS_USER Option:
Sendmail allows you to specify an alternate user & group to run as with the RUN_AS_USER configuration option. If you're adding this directive to an m4
style macro configuration file, then the correct syntax is:While not recommended practice, the alternative would be to edit your sendmail.cf file directly & make sure the RunAsUser option is set as follows:define(`confRUN_AS_USER', `sendmail:sendmail')Creating your configuration files from m4 macros is much more maintainable in the long run, however, so try to avoid directly hacking on your sendmail.cf files.O RunAsUser=sendmail:sendmail
Use m4 to generate your new sendmail.cf & overwrite the existing configuration file on your mail server. Now start the Sendmail process ("/etc/init.d/sendmail start" in most cases). If you look at the running MTA process after your reconfiguration, you may be surprised to see that it's still running as root. This is expected behavior. The master MTA process always runs as root, but remember that when a new SMTP connection comes in the master MTA process must fork a copy of itself to handle the incoming connection. The "child" process will run as the unprivileged user & group you specify with the RUN_AS_USER option. So while the master MTA process itself runs as root, outsiders will only ever be able to communicate with unprivileged child processes.
You can test the configuration by using telnet to connect to port 25 ("telnet localhost 25"). In the process listing on the server, you should see a sendmail process running as the sendmail user.
There is no difficulty using this unprivileged Sendmail configuration with common Milters, like MIMEDefang & milter-greylist. You just need to make sure that the socket created by these Milters is readable by your unprivileged sendmail user. Don't forget to pay attention to the permissions on the socket itself & also the permissions on the directory where the socket is created.
With Sendmail running as an unprivileged user, it would also be fair to run Sendmail chroot()ed. There's not much point in running a root-owned process under chroot() restriction, since an attacker who takes over the process can use root privilege to escape the chroot() restriction in most cases. But with our unprivileged relay configuration, chroot() might actually be useful & not that difficult to configure since Sendmail doesn't need to interact with much of the OS when operating purely as a relay.
I hope you find this configuration useful for improving the security of your mail relay servers.