sendxmpp as a replacement for mail(1)

Published 2020-08-28 on Anjan's Homepage

Tools like cron use mail(1) to notify the server admin of failing services. It is trivial to configure postfix to only send mail. However, moving to my new server, the mail port (port 25) is blocked by my internet service provider and I cannot send email from my network. I could use something like msmtp to have my email service provider (migadu, gmail, etc.) send my emails for me but I would be using up my daily outgoing message quota. To avoid running into this limit, I looked to employ a different protocol - xmpp.

1 go-sendxmpp

go-sendxmpp is a command line replacement for mail command on linux. It allows reading in from stdin and sending xmpp messages to anyone on the xmpp network including multi user chatrooms. The original program was written in perl but I could not package it for alpine linux. I prefer the go implementation because it compiles into a single binary that I can copy to all my machines. Go's binaries are statically linked by default so if most of my system is falling apart, it's more likely I will get a message that my system is falling apart.

The program's documentation is great for installing and setting up go-sendxmpp. However, there is one mistake in the documentation as it says the config file must contain:

username: <your_jid>
jserver: <jabber_server>
port: <jabber_port>
password: <your_jabber_password>

My xmpp server uses default settings so I was able to get go-sendxmpp working with:

username: <your_jid>
password: <your_jabber_password>

Since this file will stored unencrypted on multiple possibly insecure computers, it is wise to make a new jabber account to send yourself notifications.

2 Server

2.1 Message on ssh login

When changing the sshd config, make sure you leave the terminal from which you are editing the config open and login from a new terminal window. It is very easy to lock yourself out of your own computer when configuring sshd.

The first thing I setup upon discovering go-sendxmpp was a message on ssh login.

On alpinelinux, I installed the following packages:

doas apk add openssh-server-pam linux-pam

Then, I opened /etc/ssh/sshd_config and set:

UsePAM yes

Finally, I made a script to send messages on login 1:

server:~$ doas cat /etc/ssh/login-notify.sh
#!/bin/sh

# Change these two lines:
SENDXMPP_CONFIG="/home/anjan/.sendxmpprc"
RECIPIENT="anjan@momi.ca"

if [ "$PAM_TYPE" != "close_session" ]; then
        host="`hostname`"

        # do not send message if Im sshing from a known ip address
        [ "$PAM_RHOST" = "192.168.1.1" ] && exit 0 
        subject="SSH Login: $PAM_USER from $PAM_RHOST on $host"
        # Message to send, e.g. the current environment variables.
        message="`env`"
        echo "$message" | /home/anjan/go/bin/go-sendxmpp -f "$SENDXMPP_CONFIG"  "$RECIPIENT"
fi

Finally, I enabled my login script by adding the following line to /etc/pam.d/sshd:

session optional pam_exec.so seteuid /etc/ssh/login-notify.sh

Make sure you restart the sshd service.

Now, when I log onto my server from an external IP address, I get an xmpp message.

2.2 Cron

go-sendxmpp is trivial to use in a cronjob. For example, to check every 20 minutes if my server was running out of system resources, I put the following commands in my crontab:

#min    hour    day     month   weekday cmd
*/20    *       *       *       *       [ `df -h | grep sda3 | awk '{ print $5 }' | sed 's/%//'` -gt 20 ] && echo "server: space taken up on /" | ~/go/bin/go-sendxmpp anjan@momi.ca
*/20    *       *       *       *       cat /proc/loadavg | awk '{print $1}' | awk '{ if($1 > 0.50) printf("server: Current CPU Utilization is: %.2f%\n"), $0;}' | ~/go/bin/go-sendxmpp anjan@momi.ca
*/20    *       *       *       *       free | grep Mem | awk '{print $3/$2 * 100.0}' | awk '{ if($1 > 50) printf("server: Current Ram Utilization is: %.2f%\n"), $0;}' | ~/go/bin/go-sendxmpp anjan@momi.ca

Alpine also has an autoupdate program you can set up as a cronjob. I like running updates manually but if I was running updates automatically, I would send the output of the auto update cronjob to go-sendxmpp.

3 Pinephone

I am using sxmo on my pinephone which allows the user to define commands to run when the phone receives a call or text. Most people use this feature to setup a script to switch to the speaker sink, set volume to 100%, and tell mpv to play a ringing sound. My android phone required constant babysitting where I would have to consider when I cannot have my phone ring (sleeping, before meetings, etc.) and I needed to remember to put my phone on silent. Keeping my phone on silent all the time caused me miss calls and texts because I wouldn't pay attention to it.

Introducing go-sendxmpp - no babysitting required, I will never miss a call/text, and my phone will never ring at an inopportune times.

3.1 xmpp message on new text or call

For sms messages, enter the following into $XDG_CONFIG_HOME/sxmo/hooks/sms:

INCOMING_NUMBER="$1"
echo "Pinephone text from: $INCOMING_NUMBER" | go-sendxmpp anjan@momi.ca

For call messages, enter the following into $XDG_CONFIG_HOME/sxmo/hooks/ring:

INCOMING_NUMBER="$1"
echo "Pinephone Call from: $INCOMING_NUMBER" | go-sendxmpp anjan@momi.ca

Replace "anjan@momi.ca" with your own jabberid and set the run permissions on the ring and sms files.

3.2 notification on low battery

I added the following line to my cronjob:

*/10    *       *       *       *       [ `cat /sys/class/power_supply/axp20x-battery/capacity` -le 30 ] && [ `cat /sys/class/power_supply/axp20x-battery/status` = "Discharging" ] && echo "pinephone low battery" | ~/.config/go/bin/go-sendxmpp anjan@momi.ca

I never forget to charge my phone now.

4 Conclusion

go-sendxmpp allows for a universal, easy to setup notification system for all your *nix devices. Furthermore, it shows the advantages of using a unix-like operating system for things that are commonly not tradition unix boxes (ie. your phone).

Try out go-sendxmpp. Can you think of other uses for a service like this? If so, feel free to send an email to my public-inbox.

Footnotes:

1

Taken from StackExchange user Fritz See: https://askubuntu.com/posts/448602/revisions

Have a comment on one of my posts? Start a discussion in my public inbox by sending an email to ~anjan/public-inbox@lists.sr.ht [mailing list etiquette]

Articles from blogs I follow around the net

These articles/blogs do not represent my own opinions or views.

A few ways to make money in FOSS

I work on free and open-source software full time, and I make a comfortable living doing it. And I don’t half-ass it: 100% of my code is free and open-source. There’s no proprietary add-ons, no periodic code dumps, just 100% bona-fide free and open source so…

via Drew DeVault's blog November 20, 2020

How to Make Biomass Energy Sustainable Again

From the Neolithic to the beginning of the twentieth century, coppiced woodlands, pollarded trees, and hedgerows provided people with a sustainable supply of energy, materials, and food.

via LOW←TECH MAGAZINE September 20, 2020

Eshell versus M-x shell

I’ve used and defended Eshell for years. Sadly, Eshell has some long standing issues that I grew tired of in the long run. So I’ve decided to switch to M-x shell and see how much of my Eshell workflow I could port. Language and the underlying shell pr…

via Pierre Neidhardt's homepage June 26, 2020

Generated by openring