Hello everyone!
As the title says, I am trying to set up email alerts on my server whenever there is a successful ssh connection (will also setup the same for failed connections with fail2ban later). I already have the email script created and it works (I use it to monitor the directories containing all of these security scripts for changes so that I also get notified if anything critical is modified or deleted in those directories).
I also created a very basic user called test for - you guessed it - testing purposes. This user doesn’t have a home directory or anything like that.
Here are the relevant scripts:
$ cat /usr/local/bin/login-alert.sh
#!/bin/bash
# Sends alerts only for real terminals not cron jobs
if [[ -n "$SSH_CONNECTION" ]]; then
USERNAME=$(whoami)
IP=$(echo $SSH_CONNECTION | awk '{print $1}')
HOST=$(hostname)
DATETIME=$(date)
/usr/local/bin/semail \
-s "[CRITICAL] SSH Login to $HOST" \
-b "Login detected:\n\nUser: $USERNAME\nIP: $IP\nTime: $DATETIME\nTTY: $SSH_TTY"
fi
$ cat /usr/local/bin/semail
#!/bin/bash
# Default values
TO="my_email@here.com"
FROM="notifications@my_server.com"
SUBJECT=""
BODY=""
BODY_FILE=""
# Help function
show_help() {
cat <<EOF
Usage: $0 [OPTIONS]
Send a test email using Postfix.
Options:
-t, --to EMAIL Recipient email address (default: $TO)
-s, --subject TEXT Subject of the email (required)
-b, --body TEXT Body text of the email
-f, --body-file FILE File to read body text from (overrides --body)
-h, --help Show this help message
If no body or body-file is provided, you will be prompted to enter the body interactively.
Examples:
$0 -s "Test subject" -b "Hello\nThis is a test"
$0 --subject "Test" --body-file message.txt
EOF
}
# Parse arguments
while [[ "$#" -gt 0 ]]; do
case "$1" in
-t|--to)
TO="$2"
shift 2
;;
-s|--subject)
SUBJECT="$2"
shift 2
;;
-b|--body)
BODY="$2"
shift 2
;;
-f|--body-file)
BODY_FILE="$2"
shift 2
;;
-h|--help)
show_help
exit 0
;;
*)
echo "Unknown option: $1"
show_help
exit 1
;;
esac
done
# Validate required parameters
if [[ -z "$SUBJECT" ]]; then
echo "Error: --subject is required."
show_help
exit 1
fi
# Handle body input
if [[ -n "$BODY_FILE" ]]; then
if [[ ! -f "$BODY_FILE" ]]; then
echo "Error: Body file '$BODY_FILE' does not exist."
exit 1
fi
BODY=$(<"$BODY_FILE")
elif [[ -z "$BODY" ]]; then
echo "Enter the body of the email (end with Ctrl-D):"
BODY=$(</dev/stdin)
fi
# Send email
{
echo "From: $FROM"
echo "To: $TO"
echo "Subject: $SUBJECT"
echo "Content-Type: text/plain; charset=UTF-8"
echo
printf "%b\n" "$BODY"
} | /usr/sbin/sendmail -t -f "$FROM"
# /usr/sbin/sendmail -f "$FROM" "$TO" <<EOF
# From: $FROM
# To: $TO
# Subject: $SUBJECT
# $BODY
# EOF
echo "Email sent to $TO"
And here is the output I see when I login as the test user:
ssh test@my_server.com
test@my_server.com's password:
dir=/ failed: exit code 2
dir=/ failed: exit code 2
Linux my_server 6.1.0-37-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.140-1 (2025-05-22) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Aug 15 07:08:24 2025 from my_ip_address
Could not chdir to home directory /home/test: No such file or directory
I don’t get email alerts for any user, neither the test user nor my regular admin user.
Here is my /etc/pam.d/sshd relevant lines:
# Standard Un*x session setup and teardown.
account optional pam_exec.so seteuid dir=/ /usr/local/bin/login_notify.sh
@include common-session
I also tried with session instead of account and without the dir=/ part.
Can anyone help me troubleshoot this please?
Thanks in advance. Of course if you need any more info I’ll do my best to provide it :)
Your PAM line calls /usr/local/bin/login_notify.sh but your script is named
login-alert.sh
. That alone makes pam_exec fail (ENOENT).Seems like AI hallucination type of mistake.
I corrected it and restarted the ssh service and then logged in as test user but it still give the same output. Tbh I havent slept so I think I should leave it until tomorrow and look at it with fresh eyes.