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.
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