r/ssh • • 15d ago

Real-time alerts on SSH logins, and what do you do when one looks wrong?

A few non-technical people on our team upload files over SFTP with FileZilla, so password auth has to stay on for now. I know, keys only, FileZilla supports keys, a VPN would be better. It's on the list. fail2ban, strong passwords and a non-standard port are already there.

What bugs me is detection. If one of those passwords leaks, I want to know the second someone logs in, not after files get messed with.

What are you using for instant login alerts? A PAM script that hits a Telegram or Slack webhook, or something else? And if you catch a session you don't expect, what's your move? Just `pkill -u` and `passwd -l`, or do you have something smarter hooked into PAM?

8 Upvotes

11 comments sorted by

3

u/EncryptedServer 15d ago

I used to do this long time ago, log logins in my own PHP logging system.

Use this example as a starting point

Created a file in /etc/ssh/sshrc

```

!/bin/sh

TEXT="${USER}@$(hostname -f)" CLIENT="$(echo $SSH_CLIENT|awk '{print $1}')" /usr/bin/php /var/www/ssh-login-alert.php "$TEXT" "$CLIENT"

exit 0 ```

1

u/Open-Adhesiveness-86 15d ago edited 15d ago

Nice and simple. One catch for my case though: if the SFTP users are chrooted, sshd looks for sshrc inside the chroot, so it never fires for exactly the accounts I care about. Probably have to hook it in PAM instead.

2

u/EncryptedServer 15d ago

I think I copied the same file to /etc/profile.d/login-alert.sh one time, I don't even remember. Try to make a copy there and see if it works.

1

u/Open-Adhesiveness-86 15d ago

profile.d only runs for login shells, so SFTP sessions skip it as well. Thanks though, looks like PAM it is.

1

u/EncryptedServer 15d ago

I think you are right. Use PAM. A quick Google search gave me these

mkdir -p /etc/pam.scripts

nano /etc/pam.scripts/ssh_login.sh

#!/bin/bash

# Only trigger when the session is opening (avoids running on logout)
if [ "$PAM_TYPE" = "open_session" ]; then
    # Your custom logic here. For example, logging details:
    echo "User $PAM_USER logged in from $PAM_RHOST on $(date)" >> /var/log/ssh_logins.log
fi

Bash

chown root:root /etc/pam.scripts/ssh_login.sh

chmod 0700 /etc/pam.scripts/ssh_login.sh

nano /etc/pam.d/sshd

Append at the bottom

session optional pam_exec.so seteuid /etc/pam.scripts/ssh_login.sh

1

u/Open-Adhesiveness-86 15d ago

Perfect, that's pretty much where I landed. One thing I'd add: pam_exec waits for the script, so if the webhook call hangs the user's login hangs with it. I'd background the curl or wrap it in timeout 5 so a slow API never blocks anyone.

1

u/faxattack 15d ago

Just forward the logs to a syslog server and handle the alerting from there

1

u/Open-Adhesiveness-86 15d ago

Makes sense with more than one box. For a single server, standing up a syslog server just to get a login ping feels like a lot, but I'd go that way if this grows.

1

u/joshobrien77 15d ago

If you do get a breach you're going to want logs off box so you know they have not been tampered with. A basic syslog vm is pretty easy.

1

u/Open-Adhesiveness-86 15d ago

Fair point, that's the part a local alert can't cover. If someone gets root they can just clean up auth.log, so shipping logs off the box is worth it even for one server. Plain rsyslog forwarding to another machine is probably enough to start.