All *nix operating-systems want to send email notifications for a variety of possible problems, and it’s a good idea to not ignore those.
In the default configuration, emails will usually be delivered locally, and you’d see something like this when you login:
You have new mail in /var/mail/lukas
Crontab outputs will be sent there, as explained in the crontab -l
output:
# Output of the crontab jobs (including errors) is sent through # email to the user the crontab file belongs to (unless redirected).
Also a notification will be sent to root on failed sudo attempts. Or a PHP script on a webserver could try to email users, all of those needs working email. If you don’t want to get emails for certain events, you will be able to configure them individually. For example, in cronjobs we can redirect the output somewhere else (even errors, if you wish to do so), sudo can be reconfigured to not send any notifications, etc.
However we do want to receive those emails; just not via local delivery (we may login only sporadically), but properly send them to a SMTP server/smarthost.
To do this, we could just install postfix
or exim4
on our Debian/Ubuntu OS, however those software stacks are overkill for what we are trying to achieve. We just need to deliver it to our SMTP server, which then takes care of the rest – no need for a local SMTP server. Here comes ssmtp
.
Installation
First we install ssmtp
:
$ sudo apt update $ sudo apt install ssmtp
Now we can put some aliases in /etc/ssmtp/revaliases
to rewrite sender addresses based on the local user:
root:[email protected]:smtp.example.org:587 www-data:[email protected]:smtp.example.org:587 lukas:[email protected]:smtp.example.org:587
And in /etc/ssmtp/ssmtp.conf
we configure the rest:
# domain: rewriteDomain=example.com FromLineOverride=NO # local settings: hostname=host1.example.com [email protected] # outgoing smtp mailhub=smtp.example.org:587 UseSTARTTLS=YES [email protected] AuthPass=passsecret
Read man pages or configuration examples to find out what the individual configuration statements do (and don’t copy and paste everything from random blog posts on the Internet, do research and understand before deploying). A service reload/restart is not necessary, because this is not a daemon running in the background.
Make sure your mail servers actually allows you to send with this particular domain and sender addresses. Non-existing domains may not be allowed or will end up in spam folders at the recipients mailbox.
Test
We should be able to send an email just be invoking sendmail with it:
$ echo "Test" | sendmail [email protected] $
We see no output, that’s good. Now wait a few minutes and check your emails, it should be there.
Monitoring
Now that we have a working email setup, what if something silently breaks: we won’t notice, because the lack of emails could actually be a good thing. We can send periodic emails to humans, but that is a terrible idea: people don’t like to get flooded with “I’m alive” emails, and after the third email will ignore all of them, including those with actual errors. Instead we can use something like healthchecks.io to test our setup periodically (including the SMTP server we send emails through), and generate alerts to humans only in the absence of periodic emails reaching the healthchecks.io service.
After setting up account and a check at healthchecks.io, we can send emails to the address of our specific health check that we just setup, by resetting the MAILTO variable and generating output (just like a real crontab job would):
# cron mail health [email protected] 44 7 * * * echo "I am alive"
Make sure to put this after existing cron jobs, so that the MAILTO
variable only affects this specific job (otherwise your real cron notifications would not reach you anymore as they’d be send to the healthchecks.io check as well).
Summary
In this post we learned how to setup email submission to external SMTP servers, allowing proper notifications. Testing and monitoring with the healthchecks.io service was also covered.