Read system mail with neomutt(1)

This post takes a look at how to read "system mail" with the neomutt(1) program on FreeBSD. For those unfamiliar, the periodic(8) utility is run regularly via /etc/crontab and its output is sent as mail to root. By default the scripts executed via periodic(8) perform system tasks such as running security checks, among other system maintenance tasks that are worth keeping an eye on.

My preferred email client happens to be neomutt(1) but as a rule of thumb I try to avoid running programs outside the FreeBSD base system as root. That led me down the path of configuring a separate (unprivileged) user account for reading "system mail", and in this post I will share how my setup eventually took shape.

useradd

The first step is to create a new user account whose primary responsibility will be reading "system mail" with the neomutt(1) program:

##
# FreeBSD: add user
root@localhost# pw useradd \
  -n _sysmail \
  -d /home/_sysmail \
  -M 700 \
  -s /bin/sh \
  -m \
  -c "Reads system mail"

alias

The second step is to create a mail alias that forwards mail sent to root onto our new user account. This can be done by editing the /etc/mail/aliases file, and there should already be plenty of aliases defined in this file.

At the very end of the file, add a new alias, and afterwards run newaliases to rebuild the alias database. Once that is done, the new alias should take effect:

##
# FreeBSD: add mail alias
root@localhost# echo "\nroot: _sysmail" >> /etc/mail/aliases
root@localhost# newaliases

neomutt

When it comes to the third step we now have everything in place to read system mail as the _sysmail user. Keep in mind that after you create the _sysmail user account it is unlikely to have any mail. This can be fixed by running periodic daily manually (as root) or waiting for the next time periodic runs via cron. After you're sure there is mail to read, neomutt is ready to go:

##
# FreeBSD: read system mail
_sysmail@localhost$ neomutt -f /var/mail/_sysmail

doas (optional)

The next step is optional but recommended. It can help streamline the process of running neomutt as the _sysmail user. Otherwise running neomutt as the _sysmail user can be cumbersome.

The following doas.conf configuration will allow members of the _sysmail group to run neomutt as the _sysmail user without being prompted for a password:

##
# FreeBSD: /usr/local/etc/doas.conf
permit nopass :_sysmail as _sysmail cmd /usr/local/bin/neomutt args -f /var/mail/_sysmail

It is up to you to decide who should be a member of the _sysmail group, it could be restricted to just root and in that case privileges are being dropped rather than elevated:

##
# FreeBSD: add group membership
root@localhost# pw groupmod _sysmail -m root

/usr/local/bin/sysmail (optional)

The cherry on top is a small shell script that wraps neomutt with the doas(1) command. This script can be placed in the /usr/local/bin/ directory:

#!/bin/sh
# FreeBSD: /usr/local/bin/sysmail
doas -u _sysmail neomutt -f /var/mail/_sysmail

Afterwards make sure the script has the expected ownership and permissions:

##
# FreeBSD: add ownership and permissions
root@localhost# chmod u=rwx,g=rx,o= /usr/local/bin/sysmail
root@localhost# chown root:_sysmail /usr/local/bin/sysmail

Conclusion

In conclusion I hope this post was helpful. In closing I'd like to suggest a few links for further reading. They explore this topic with a bit more depth and I highly recommend taking a look if that's what you're after: