3 minutes
Gotify as notification service
Intro:
You want to sleep calmly through the night? 😴 For security reasons I wan’t to get notified if something happens on my servers. My way to go is to use gotify instead of using for example the default email/sendmail way. Gotify is a simple, open source, MIT-licensed, docker deployable, push-messaging implementation in golang. It is lightweight, fast, and intuitive. Another great thing is the android app. Also it is free and open source. So you can receive instant gotify messages on android devices as well as on every notebook or desktop computer with a browser like firefox installed on.
Installation
We need a gotify server to use the services.
For the server installation take a quick look at the Installation Guide from the officall site. It is very easy to setup up a gotify server.
I’m using the docker-compose installation method by portrainer. You could also use rancher with an kubernetes cluster.
my docker-compose.yml looks like:
version: "3"
services:
gotify:
image: gotify/server
ports:
- 8080:80
environment:
- GOTIFY_DEFAULTUSER_PASS=SECRET # YOU SHOULD CHANGE THIS
- TZ="Europe/Berlin"
volumes:
- "./gotify_data:/app/data"
Use docker-compose up -d
to start the docker instance.
Alternatively you could use the binary to run the gotify server without docker. Just check out their website.
configuration
In my docker-compose.yml environment variables I have defined the administrator password as SECRET. So the initial login will work with admin:SECRET. Onced login the administrator password should be changed!
When you first login in and change the password you could also create another user MENU –> USERS. It is best practice to not use the admin account or a user with admin privilages.
The next step is to add apps you wan’t to connect with gotify. I’m using a different api-key and api-token for every app. In my example I wan’t to show you an SSH login notification. So I called the app sshnotify.
The simplest way to push messages with gotify under linux is:
$ curl "https://push.example.de/message?token=<apptoken>" -F "title=my title" -F "message=my message" -F "priority=5"
$ http -f POST "https://push.example.de/message?token=<apptoken>" title="my title" message="my message" priority="5"
so you only have to add your apptoken to the URL and change the selfexplaining parameters to your use.
Here is the script for the ssh-login-notification. I got it from: peekread.info check also out his awesome blog!
#!/bin/bash
exec &> /dev/null #Hide output
Gotify_URL='https://gotify.stecher.space'
Gotify_Token='AQ_TZBdcy-U13FG'
notify()
{
now=$(date -d "-60 seconds" +%s) #Get current time minus 60 seconds
end=$((SECONDS+30)) #Set 30s Timeout for loop
while [ $SECONDS -lt $end ]; do
SSHdate=$(date -d "$(who |grep pts|tail -1 | awk '{print $3, $4}')" +%s) #Check for the latest SSH session
if [ $SSHdate -ge $now ]; then #Once who is updated continue with sending Notification
title="SSH Login for $(/bin/hostname -f)"
message="$(/usr/bin/who | tr -s ' ')"
/usr/bin/curl -X POST -s \
-F "title=${title}" \
-F "message=${message}" \
-F "priority=5" \
"${Gotify_URL}/message?token=${Gotify_Token}"
break
fi
done
}
notify & #Run in background to prevent holding up the login process
Next step is to set executive privileges
chmod +x /usr/local/bin/sshnotif
And lastly edit the following file
user@hostname:~$ vi /etc/pam.d/sshd
session optional pam_exec.so /usr/local/bin/sshnotif
optional because if the script fail you still want to get logged in.
conclusion
I really love how easy gotify could be used to get push-notifications. The possibilties are endless. My next plans are to send automated notifications for:
- security audits
- finished backups
- notification if storage usage is above 70%
All this checks could run via cronjob and are fastly and easy written. Even if gotify apptoken gets leaked it cannot be abused to distribute spam and viruses like an email service.