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="[email protected]"
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 :)


It looks like pam_exec has a log file option and a debug option. Those will give you some more info about what’s going on.
There’s also one piece that I don’t think you mentioned, and that’s sshd config settings for pam. See if usePAM is set there.
Ill try adding the log options, and come back with results.
As for the sshd config, UsePAM is set to yes.