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