SSH Login Logging to Discord via Webhooks
So in an effort to get better at log monitoring, especially for SSH, I decided to setup automatic login/logout webhook notifications. Since I already use Discord for gaming, etc. I figured it would be easy to set up a private server for just my homelab and have everything log to it. I ended up using pam.d to invoke a script that handles the webhook.
You will need a sudo enabled user to update pam.d config as well as creating the script for pam.d
If you are looking for a self hosted alternative take a look at my ntfy.sh post, here!
Creating the Webhook
Now I am going to assume that you already have a Discord account, if not you can sign up here, and you have a server setup with a text channel already created. To create the webhook, hover over the text channel you want to use and click on the settings gear. In the channel settings click on “Integrations” and then on “Webhooks”. Click “New Webhook” and change the name to something you will recognize. Then click “Copy Webhook URL” and paste it into notepad so we have it for later. You can then save and exit the channel settings view.
Configuring SSH to Use the Webhook
Now that we have our webhook created we can setup our SSH daemon to send a webhook every time we log in and out of our Linux host. To do this SSH to your host and run the following command to create our script file:
1
sudo touch /sbin/sshd-login
Now edit the file and add the following script to it.
1
sudo nano /sbin/sshd-login
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash
# add to /sbin/ and make executable
# edit /etc/pam.d/sshd and add:
# session optional pam_exec.so /sbin/sshd-login
# to bottom of the file
WEBHOOK_URL=""
DISCORDUSER=""
# Capture only open and close sessions.
case "$PAM_TYPE" in
open_session)
PAYLOAD=" { \"content\": \"$DISCORDUSER: User \`$PAM_USER\` logged in to \`$HOSTNAME\` (remote host: $PAM_RHOST).\" }"
;;
close_session)
PAYLOAD=" { \"content\": \"$DISCORDUSER: User \`$PAM_USER\` logged out of \`$HOSTNAME\` (remote host: $PAM_RHOST).\" }"
;;
esac
# If payload exists fire webhook
if [ -n "$PAYLOAD" ] ; then
curl -X POST -H 'Content-Type: application/json' -d "$PAYLOAD" "$WEBHOOK_URL"
fi
Before saving this file change the WEBHOOK_URL
variable to match your webhook url you obtained earlier. If you want the script to @ notify you on each login/logout change the DISCORDUSER
variable to include your ID. See the docs here if you do not know how to obtain your Discord user ID. Once you have your ID change the variable to "<@yourid>"
.
Example of a completed script setup
Once you are done changing variables save and close the file using CTRL+X
then y
. Then update the script to be executable and make sure the root user owns it.
1
2
sudo chmod +x /sbin/sshd-login
sudo chown root:root /sbin/sshd-login
Updating pam.d Config
In order for our script to send webhook notifications on login and log out we need to update pam.d
to invoke it. To do this we need to edit the sshd
config file located in /etc/pam.d
.
1
sudo nano /etc/pam.d/sshd
Add the following to the bottom of the sshd config file.
1
session optional pam_exec.so /sbin/sshd-login
Save the file by hitting CTRL+X
then y
. Once the file is closed we need to restart the sshd
daemon.
1
sudo systemctl restart sshd
Testing the Webhook
With the script added and setup exit your SSH session and log back in again. If it’s working you should get an @ notification from Discord like the example below.
Troubleshooting
If it does not send a webhook to Discord you can try one of the following troubleshooting steps.
- Check and verify your webhook URL is correct inside the
sshd-login
file. And is surrounded by double quotes ("
). - Verify that root owns the
sshd-login
file and it’s set to be executable. - Verify
sshd
config file in/etc/pam.d
includes thesession optional pam_exec.so /sbin/sshd-login
call at the bottom of the file.
If it still does not work, try rebooting the machine and verify if it’s working after. Let me know down below or via email if you run into any trouble!