3981b56382d892cc3c30edc1692fb903846d3947
[web-hugo.git] / content / posts / ssh-alerts-landchad-style.md
1 ---
2 title: "How to setup SSH alerts like a landchad"
3 date: 2022-08-20T15:04:20+03:00
4 description: "Have you thought of creating a SSH intrusion alert system, but don't want to integrate a full on monitoring-stack such as Nagios? In this blog, I walk you through on installing ntfy, making it a UnifiedPush provider and a useful tool for monitoring your SSH logins."
5 tags: ['privacy', 'linux', 'opensource', 'tutorial']
6 aliases: ["/ssh-alerts-landchad-style.html"]
7 img: 'ssh-ntfy.jpg'
8 type: blog
9 draft: false
10 ---
11
12 # Preface
13 I recently installed ntfy to enable UnifiedPush on several apps on my phone
14 in order to conserve battery life and make notifications work more real-time.
15 That gave me the idea that I can use this same setup for creating SSH intrusion
16 alerts for my server for that extra peace of mind.
17
18 ## Installing ntfy
19 Installing it is quite straightforward. You can find [guide for installing it on their website.](https://ntfy.sh/docs/install/)
20 In my instance, I had to install it for Ubuntu, so following commands had to
21 be executed:
22
23 ```
24 curl -sSL https://archive.heckel.io/apt/pubkey.txt | sudo apt-key add -
25 sudo apt install apt-transport-https
26 sudo sh -c "echo 'deb [arch=amd64] https://archive.heckel.io/apt debian main' \
27 > /etc/apt/sources.list.d/archive.heckel.io.list"
28 sudo apt update
29 sudo apt install ntfy
30 sudo systemctl enable ntfy
31 sudo systemctl start ntfy
32 ```
33
34 Now this enables anonymous access and everything to your server. That is cool
35 and all if you wish to offer this for public, but it comes with its own
36 reprecussions. I wished to keep my instance private just to eliminate interference
37 with my own alerts and also have more trust in the system.
38 You do not want to deal with phishers using YOUR instance or bad actors to
39 derail you with false alerts.
40
41 In order to privatize your instance, you need to open /etc/ntfy/server.yml and
42 edit the following:
43
44 ```
45 auth-file: "/var/lib/ntfy/user.db"
46 auth-default-access: "deny-all"
47 ```
48
49 This leaves you with a bare setup and may not fully suit your previously installed
50 services. In my case I had to create a reverse-proxy for it.
51 You can find the template for your preferred webserver in their docs. One thing
52 to keep in mind though with their nginx template, is that you will need to add
53 IPv6 listener manually should you use IPv6 on your server as it's absent.
54 Generate an SSL certificate using certbot and nginx plugin.
55
56 Edit your configuration again as follows:
57
58 ```
59 base-url: https://<your based domain or subdomain>
60 listen-http: "127.0.0.1:2586" # can be your preferred port too.
61 behind-proxy: true # only if reverse-proxy. otherwise false, listen-http to 0.0.0.0 and provide ssl certs as well in config.
62
63 # optionally enable cache incase your push notif receivers go offline for prolonged time.
64 cache-file: /var/cache/ntfy/cache.db
65 cache-duration: "12h"
66 ```
67
68 If you are also using Debian or Ubuntu, run `systemctl restart ntfy`. You should
69 now have a private instance of ntfy provided your reverse proxy worked out.
70 Next up you should create an admin account for your administrative needs with
71 `ntfy user add --role admin <youradminuser>`. Use this when necessary.
72 You should also create your own user with `ntfy user add <user>`.
73
74 In order to make your instance UnifiedPush compatible, you need to give world
75 access to write to service URLs with `ntfy access everyone 'up*' write-only`.
76 Now you can give permissions for yourself as well - you can be generous here and
77 give read-write to everything with `ntfy access <user> '*' read-write`.
78
79 By now everything should be functioning as intended and your instance is compatible
80 with UnifiedPush and you can start receiving notifications through it.
81
82 Install the ntfy mobile app from F-Droid or your preferred application library.
83 Go to settings of the app, add user pointing to your instance with credentials
84 of your previously created user.
85
86 ## Creating the monitor
87 Subscribe with your device to a new topic on your instance, I used "sysalerts"
88 myself.
89
90 Next up, create a new monitor user on your server: `ntfy user add monitor`.
91 Give it permission to your ssh alerts topic. `ntfy access monitor 'sysalerts' write-only`.
92
93 Create a script file in world-accessible path called "ssh_login.sh".
94 Paste the following and modify according to your setup:
95
96 ```
97 #!/bin/bash
98 MONITOR="monitor:password"
99 CURTIME=$(date)
100 INSTANCE="your.based.server"
101 TOPIC="sysalerts"
102
103 if [ "$PAM_TYPE" != "close_session" ]; then
104 if [ "$PAM_USER" == "git" ]; then
105 exit 0
106 fi
107 ntfy publish \
108 -u "$MONITOR" \
109 --tags warning \
110 --title "Successful SSH authentication" \
111 "$INSTANCE/$TOPIC" \
112 "There has been a successful login to ssh on cernodile.com.
113 User $PAM_USER from IP $PAM_RHOST on $CURTIME"
114 fi
115 ```
116
117 Make it world-executable `chmod ugo+x ssh_login.sh` and edit `/etc/pam.d/sshd`.
118
119 Append the following line to it: `session optional pam_exec.so seteuid /path/to/ssh_login.sh`.
120
121 This will make the script be run every single time someone authenticates through SSH and also not block login if
122 the script is absent.
123
124 Just to be sure, keep your current SSH session and alive and try opening a second one. If everything is done
125 correctly, you should have a notification on your phone (or desktop if you subscribed on it as well).
126
127 ## Closing words
128 I understand this may not be a fully elegant solution and there can be security implications here.
129 I am open to improving this solution, a healthy dialogue is encouraged on the topic. So far this has been
130 working without an issue. You can easily set it up with a public provider too (ntfy themselves have a public
131 instance!), but that would defeat the purpose of being a landchad.
132
133 [The alert looks something like this (img size 33K)](/img/ssh-ntfy.png)
134
135
136 Thanks for reading,
137 - Cernodile