Project: SSH Login Email Notification System
A lightweight, automated system that sends email alerts whenever someone logs into your Linux server via SSH. It hooks into PAM (Pluggable Authentication Modules) to trigger notifications on successful login — giving you real-time visibility into who's accessing your infrastructure.
Why build this?
If you're running a homelab or any internet-facing server, knowing when someone logs in is basic security hygiene. Most intrusion detection systems are overkill for a home setup. This script gives you immediate email alerts with zero overhead — no daemons, no dependencies beyond mailutils, and it runs entirely through PAM.
Features
- Detailed alerts — Emails include username, source IP/hostname, login time, and SSH port
- Rate limiting — Prevents email spam by limiting notifications per user (default: 1 email every 5 minutes)
- Syslog integration — Logs all login events to
/var/log/auth.logfor audit purposes - Automated setup — Includes installation and uninstallation scripts
- Safe by design — Uses PAM
optionalflag, so a script failure will never lock you out
Prerequisites
Before installing, make sure you have:
- Root or sudo access — Required to modify PAM configuration
- A working mail utility — Install if you don't have one:
# Debian/Ubuntu
sudo apt-get install mailutils
# RHEL/CentOS
sudo yum install mailxVerify mail is working before proceeding:
echo "test" | mail -s "SSH test" [email protected]Installation
Step 1: Download the project files
Place all three files in the same directory on your server:
install.sh— Automated installeruninstall.sh— Clean removal scriptssh-login-notify.sh— The notification script itself
Step 2: Make the scripts executable
chmod +x install.sh uninstall.sh ssh-login-notify.shStep 3: Run the installer
sudo ./install.shThe installer will prompt you for:
- Recipient email — Where you want to receive login alerts
- From address — The sender address (defaults to
ssh-monitor@hostname) - Rate limiting — Enable/disable and set the cooldown window (default: 300 seconds)
Step 4: Test it
The installer offers to send a test email at the end. Check your inbox (and spam folder) to confirm delivery. Then open a new SSH session to your server — you should receive an alert within seconds.
What the installer does
Behind the scenes, the installation script:
- Copies
ssh-login-notify.shto/usr/local/bin/ - Backs up your existing PAM config to
/etc/pam.d/sshd.backup.<timestamp> - Adds a
session optional pam_exec.soline to/etc/pam.d/sshd - Creates a rate-limiting directory if enabled
- Sets appropriate file permissions
Uninstallation
To remove everything cleanly:
sudo ./uninstall.shThis removes the notification script, reverts the PAM configuration, and cleans up rate-limit directories.
Technical details
- Script location:
/usr/local/bin/ssh-login-notify.sh - PAM config: Adds
session optional pam_exec.soto/etc/pam.d/sshd - Rate limit state: Stored in
/tmp/ssh-notify-ratelimit/ - Log entries: Tagged with
ssh-login-notifyin syslog
View logs with:
grep ssh-login-notify /var/log/auth.logTroubleshooting
No emails received
- Check your spam folder — server-sent mail often lands there initially
- Verify your server can send mail:
echo "test" | mail -s "test" [email protected] - Check the logs:
grep ssh-login-notify /var/log/auth.log - If using Gmail, you may need to allow "less secure apps" or use an App Password
PAM errors
- The script uses
optionalin PAM, so a failure should never block SSH access - If something goes wrong, your original PAM config is backed up at
/etc/pam.d/sshd.backup.<timestamp> - You can always restore it:
sudo cp /etc/pam.d/sshd.backup.* /etc/pam.d/sshd
Rate limiting not working
- Check the rate-limit directory exists:
ls -la /tmp/ssh-notify-ratelimit/ - Ensure the script has write permissions to
/tmp/
Customisation ideas
- HTML email template — Edit
/usr/local/bin/ssh-login-notify.shto customise the email body with HTML formatting - Webhook alerts — Replace the
mailcommand with acurlcall to send notifications to Slack, Discord, or Telegram - GeoIP lookup — Add
geoiplookupto include the geographic location of the source IP in alerts - Exclude trusted IPs — Add a whitelist to skip notifications for known IPs (e.g., your home network)