Send IM when site goes offline

This tutorial will show how I used a Python script, Systemd timers, and the XMPP protocol to send myself an instant message when my website goes offline.

Receiving an IM notification about an unreachable website

The Python Script

The script uses the Python requests library to contact the server. If the server is unreachable, returns an http error, or fails to respond within the timeout (5s for my site) the script runs the sendxmpp command (the configuration of which will be covered later in this article).

The script takes two arguments
1. The URL to monitor
2. The address to send the message to

Systemd User Timers

Systemd is a major component of most modern Linux distributions, replacing older utilities such as cron and init. Systemd is used to run services and schedule tasks.

Services can be defined and activated on a per-user basis allowing automation without using the root account.

In my distribution, Fedora, user-specific systemd configuration files reside in $HOME/~.config/systemd/user. You may need to create the directory.

Begin by defining a definition in $HOME/.config/systemd/user/check-website.service. This is what calls the python script.

Don't forget to substitute the example.etherarp.net values with ones applicable to you!.

The next required file is $HOME/.config/systemd/user/check-website.timer which specifies that check-website.service be run at regular intervals

This timer definition states the service will run every ten minutes, provided the system has been up for fifteen minutes (it will run immediately if the timer is manually started)

Run the following commands to activate the timer

systemctl --user daemon-reload
systemctl --user enable check-website.timer
systemctl --user start  check-website.timer

Configure the XMPP client

I decided to use the old Perl based sendxmpp command as my XMPP client because it is extremely simple.

It does have a couple of fairly major flaws:

  • It doesn't understand DNS SRV records
  • Fedora had SSL verification issues (which I fixed)

First, in my home directory, I created a ~/.sendxmpprc file with the following entries specific to my (test) XMPP server

username: test
component: example.etherarp.net
jserver: example.etherarp.net:5222
password: Password!

When I tried running `sendxmpp` on Fedora, I got a fatal SSL error as it couldn't find a CA bundle. I fixed it by editing
/usr/share/perl5/vendor_perl/XML/Stream.pm and looking for the line matching $self->{SIDS}->{default}->{ssl_ca_path} = '';
and changing '' to '/etc/pki/tls/certs/ca-bundle.crt'

On the topic of SSL, the Python script calls sendxmpp with the -t flag which mandates the use of TLS. Remove this flag if you're using a plaintext server.

Configure the XMPP Server

I created a test XMPP server using the prosody package running on a Debian in a Docker container. As this was a quick test, I set it up interactively rather than using a Dockerfile.

I copied a valid SSL certificate/key/dh2048 to it and placed the following in /etc/prosody/prosody.cfg.lua

I started prosody, and then used prosodyctl adduser test@example.etherarp.net and prosodyctl adduser webmaster@example.etherarp.net commands to generate the user and service XMPP accounts.

Then, on my workstation, I set example.etherarp.net to the address of the container in /etc/hosts. I connected over Pidgin client and logged into both accounts, adding and accepting both as 'buddies' of one and other.  

I then verified messages could be sent between them