How to Add SSH Login Alert Notification on Debian 12 with MyVesta

Post Reply
User avatar
webxtek
Posts: 67
Joined: Wed Nov 18, 2020 7:43 pm
Been thanked: 2 times

This tutorial shows how to set up an SSH login notification script on a Debian 12 server with MyVesta, using `msmtprc` to send email alerts. The script notifies you when someone logs into your server via SSH, including the username, remote IP, and timestamp. It uses a cache to avoid duplicate notifications from the same IP within an hour.

Step 1: Install and Configure msmtprc
Install `msmtprc` to handle email sending:

Code: Select all

apt update
apt install msmtp -y
Create the configuration file using `nano`:

Code: Select all

nano /etc/msmtprc
Add the following configuration, replacing placeholders with your email server details:

Code: Select all

defaults
auth           on
tls            on
tls_starttls   off
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile        /var/log/msmtp.log

account        default
host           mail.yourdomain.com
port           465
from           [email protected]
user           [email protected]
password       YourSecurePassword
Save and exit `nano` (Ctrl+O, Enter, Ctrl+X). Secure the file:

Code: Select all

chmod 600 /etc/msmtprc
chown root:root /etc/msmtprc
Test the configuration by sending a test email:

Code: Select all

echo -e "Subject: Test\n\nThis is a test email." | msmtp [email protected]
Check `/var/log/msmtp.log` for errors.

Step 2: Create the SSH Login Notification Script
Create the script using `nano`:

Code: Select all

nano /usr/local/bin/ssh-login-notify.sh
Add the following script:

Code: Select all

#!/bin/bash

# Variables
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
TIMESTAMP_SECONDS=$(date +%s)
HOSTNAME="your_hostname"
MESSAGE_ID="ssh-login-$(date +%s)@your_hostname.yourdomain.com"
DATE=$(date -R)

# Capture the real user who logged in
USERNAME=$(logname 2>/dev/null || who am i | awk '{print $1}' | head -1)
if [ -z "$USERNAME" ]; then
    USERNAME=$SUDO_USER
fi
if [ -z "$USERNAME" ]; then
    USERNAME="Unknown"
fi

# Capture the remote IP
REMOTE_IP=$(echo "$SSH_CLIENT" | awk '{print $1}')
if [ -z "$REMOTE_IP" ]; then
    REMOTE_IP=$(who am i | awk '{print $NF}' | sed 's/[()]//g')
fi
if [ -z "$REMOTE_IP" ]; then
    REMOTE_IP=$(last -i -n 1 | grep "$USERNAME" | awk '{print $3}' | sed 's/[()]//g')
fi
if [ -z "$REMOTE_IP" ]; then
    REMOTE_IP="Unknown"
fi

# Cache to prevent repeated notifications
CACHE_DIR="/var/tmp/ssh_login_cache"
CACHE_FILE="$CACHE_DIR/$REMOTE_IP"
mkdir -p "$CACHE_DIR"
find "$CACHE_DIR" -type f -mtime +1 -exec rm -f {} \; 2>/dev/null

# Check if IP was notified in the last hour
if [ -f "$CACHE_FILE" ]; then
    LAST_LOGIN=$(cat "$CACHE_FILE")
    TIME_DIFF=$((TIMESTAMP_SECONDS - LAST_LOGIN))
    if [ "$TIME_DIFF" -lt 3600 ]; then
        echo "[$TIMESTAMP] Login from IP $REMOTE_IP ignored (within 1 hour)." >> /var/log/ssh-login-notify.log
        exit 0
    fi
fi

# Update cache
echo "$TIMESTAMP_SECONDS" > "$CACHE_FILE"

# Create HTML email
cat << EOF > /tmp/ssh-login-message.txt
Subject: SSH Login on $HOSTNAME
From: Server Notification <[email protected]>
Reply-To: [email protected]
Date: $DATE
Message-ID: <$MESSAGE_ID>
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SSH Login Notification</title>
</head>
<body style="font-family: Arial, sans-serif; background-color: #f4f4f9; margin: 0; padding: 20px; color: #333;">
    <div style="max-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); overflow: hidden;">
        <div style="background-color: #2196F3; color: #ffffff; padding: 15px; text-align: center;">
            <h1 style="margin: 0; font-size: 24px;">SSH Login Notification</h1>
        </div>
        <div style="padding: 20px;">
            <p style="font-size: 16px; margin: 10px 0;"><strong>Host:</strong> $HOSTNAME</p>
            <p style="font-size: 16px; margin: 10px 0;"><strong>User:</strong> $USERNAME</p>
            <p style="font-size: 16px; margin: 10px 0;"><strong>Remote IP:</strong> $REMOTE_IP</p>
            <p style="font-size: 16px; margin: 10px 0;"><strong>Time:</strong> $TIMESTAMP</p>
        </div>
        <div style="background-color: #f4f4f9; padding: 10px; text-align: center; font-size: 12px; color: #777;">
            <p style="margin: 0;">This is an automated notification from your server.</p>
        </div>
    </div>
</body>
</html>
EOF

# Send email
sleep 10
if [ -f "/tmp/ssh-login-message.txt" ]; then
    msmtp [email protected] < /tmp/ssh-login-message.txt >> /var/log/ssh-login-notify.log 2>&1
    STATUS=$?
    if [ $STATUS -eq 0 ]; then
        echo "[$TIMESTAMP] SSH login notification sent successfully for IP $REMOTE_IP." >> /var/log/ssh-login-notify.log
    else
        echo "[$TIMESTAMP] Failed to send SSH login notification for IP $REMOTE_IP. Status: $STATUS." >> /var/log/ssh-login-notify.log
    fi
    rm -f /tmp/ssh-login-message.txt
else
    echo "[$TIMESTAMP] Error: Could not create email message file for IP $REMOTE_IP." >> /var/log/ssh-login-notify.log
fi

exit 0
Save and exit `nano` (Ctrl+O, Enter, Ctrl+X). Make the script executable:

Code: Select all

chmod +x /usr/local/bin/ssh-login-notify.sh
Step 3: Trigger the Script on SSH Login
Edit the PAM configuration using `nano`:

Code: Select all

nano /etc/pam.d/sshd
Add this line at the end:

Code: Select all

session optional pam_exec.so /usr/local/bin/ssh-login-notify.sh
Save and exit `nano` (Ctrl+O, Enter, Ctrl+X).

Step 4: Test and Monitor
Log in via SSH to test. Check the log file for debugging:

Code: Select all

tail -f /var/log/ssh-login-notify.log
The script sends an HTML email with login details and caches IPs to avoid duplicate notifications within an hour. Replace `your_hostname` and `yourdomain.com` with your server's hostname and domain.

Let me know if you need help! :mrgreen:
Post Reply