Skip Navigation

Trying to set up email alerts for ssh logins on my server with PAM. Getting error code 2

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 :)

12 comments
12 comments