How to restrict delivery to local users to a set of users in Exim 4

If you install Exim and choose a configuration type that allows receiving of emails via SMTP, it automatically enables delivery to local users. However you've no way to control which local users should be allowed to receive emails and which not. I've found that a number of system users (eg. man, mail, statd, inetd, ...) can receive emails too and these users will never ever log in and actually read and/or delete them, thus it'd be preferred if these mails would not even be allowed to be delivered.

The default local user delivery method could be considered a security risk too, since if you use the Maildir delivery method, then the emails will be stored in the users' home directories which -in case of system users- can reside on any partition. And a flood of emails targeted at these users might consume all free space on filesystem partitions that you'd not expect ... which might result in a DoS. To avoid this, we can modify the Exim config to allow mail delivery only to a specific set of local users and not all of them.

The Exim configuration can be handled in two ways (depending on the setting "dc_use_split_config" in /etc/exim4/update-exim4.conf.conf): it's either split into a number of small files in /etc/exim4/conf.d or it's in a single file in /etc/exim4/exim4.conf.template. If you use the split configuration, then the file at /etc/exim4/conf.d/router/900_exim4-config_local_user contains the router definition that handles delivery to local users. If you use the one-file configuration, then look for the string "local_user:" in the exim4.conf.template.

The local_user router simply checks whether the local part of the recipient in the received email matches a local username and if it does, then the mail is handled to the local delivery transport that is specified in update-exim4.conf.conf in the "dc_localdelivery" option. In case of the maildir_home transport, Exim switches credentials to the target user and tries to deliver the mail in the user's home directory (inside a Maildir subdirectory). If Maildir does not exist, Exim tries to create it ... still with the target user's credentials.

I've written a small shellscript to list the local users that have write permission to their home directory:
echo "List of local users that have write permission to their home directory:"
for i in $(getent passwd | cut -d: -f1,6); do
  user=$(echo "$i" | cut -d: -f1)
  userhome=$(echo "$i" | cut -d: -f2)
  usergroups=$(id -Gn "$user")
  for grp in $usergroups; do
    groupcond="$groupcond -o ( -group $grp -perm /g=w )"
  permcheck=$(find "$userhome" -maxdepth 0 -type d \( \( -user "$user" -perm /u=w \) $groupcond -o -perm /o=w \) -print 2> /dev/null)
  if [ -n "$permcheck" ]; then
    echo "$user: $userhome"
Nothing too fancy, but it does the job.

On a Debian server (that I manage) it resulted in the following list:
List of local users that have write permission to their home directory:
root: /root
man: /var/cache/man
mail: /var/mail
Debian-exim: /var/spool/exim4
statd: /var/lib/nfs
identd: /var/run/identd
mysql: /var/lib/mysql
public: /home/public
operator: /home/operator
munin: /var/lib/munin

There're a couple of normal users (that I've created manually) on this list, but there're several system users too that should not get any mails delivered.

The solution is quite simple and I don't really know why this is not included in the Exim config by default (at least put into a comment, just so you won't have to crawl the web for Exim config documentation, etc.).

The local_user router has by default this line:
  local_parts = ! root

Its purpose is to prevent delivery to the root user by this router.
You should simply replace it with the following:
  local_parts = ! root : lsearch;/etc/exim4/allowed_users

Create a file at /etc/exim4/allowed_users and list the local users that you want to have local delivery enabled. If you added the above local_parts option to the router, then the allowed_users file _must_ exist for the router to work at all! But of course you would not have added this mod if you didn't want to create a restricting list in the first place. Smile

You can turn around the restriction by adding an exclamation mark to it. Like this:
  local_parts = ! root : ! lsearch;/etc/exim4/blocked_users

This way all users (except for root) will be allowed to receive mails that are not listed in the blocked_users file.

Of course you should restart Exim for any changes in the config to take effect.

PS: there's a separate router for the root user's mail called mail4root (/etc/exim4/conf.d/router/mmm_mail4root). It'll store the incoming mail of root in the file /var/mail/mail if no other routers handled it previously.


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

unrouteable address or unknown user

do you have a solution, where the servers answer is not unrouteable address but "unknown user"?
The router says, if it fails it would respond with "unknown user". But using the local_parts with blocked_ or allowed_ users, the server returns "unrouteable address".

Re: unrouteable address or unknown user

Sorry, I've no idea how to return an "unknown user".

Syndicate content