In order to monitor some of the machines I maintain, I rely on a simple email setup using logcheck. Unfortunately that system completely breaks down if mail delivery stops.
This is the simple setup I've come up with to ensure that mail doesn't pile up on the remote machine.
Server setup
The first thing I did on the server-side is to follow Sean Whitton's advice and configure postfix so that it keeps undelivered emails for 10 days (instead of 5 days, the default):
postconf -e maximal_queue_lifetime=10d
Then I created a new user:
adduser mailq-check
with a password straight out of pwgen -s 32
.
I gave ssh permission to that user:
adduser mailq-check sshuser
and then authorized my new ssh key (see next section):
sudo -u mailq-check -i
mkdir ~/.ssh/
cat - > ~/.ssh/authorized_keys
Then I added restrict,command="/usr/bin/mailq"
to the authorized_keys
entry so that
it looks like this:
restrict,command="/usr/bin/mailq" ssh-ed25519 AAAAC3N... francois@machine
This means that this account cannot use any of the powerful ssh features like port forwarding and is limited to running a single command.
If your server also allows users to login using GDM,
then you'll probably want to hide that user from the list of available
users by putting the following in /var/lib/AccountsService/users/mailq-check
:
[User]
XSession=
SystemAccount=true
Laptop setup
On my laptop, the machine from where I monitor the server's mail queue, I first created a new password-less ssh key:
ssh-keygen -t ed25519 -f .ssh/egilsstadir-mailq-check
cat ~/.ssh/egilsstadir-mailq-check.pub
which I then installed on the server.
Then I added this cronjob in /etc/cron.d/egilsstadir-mailq-check
:
0 2 * * * francois /usr/bin/ssh -o ClearAllForwardings=yes -i /home/francois/.ssh/egilsstadir-mailq-check mailq-check@egilsstadir mailq | grep -v "Mail queue is empty"
and that's it. I get a (locally delivered) email whenever the mail queue on the server is non-empty.
The ClearAllForwardings
option is there to disable any LocalForward
you
may have set in ~/.ssh/config
and which could cause this cron job to fail
if you are already logged into that machine (and therefore using up the
local port).
There is a race condition built into this setup since it's possible that the server will want to send an email at 2am. However, all that does is send a spurious warning email in that case and so it's a pretty small price to pay for a dirt simple setup that's unlikely to break.
Recently I've discovered healthchecks.io, which is a free (and also FOSS) service that can check whether your mail server can deliver email.
The way it works: you configure a cron script on your server to send email to
<uuid>@healtchecks.io
, and if that email doesn't arrive for a set period (say, 24 hours, if you want one daily check), healtchecks.io will drop you a notification.