Conditionally stop interactive and non-interactive ssh login and give error message

I want to prevent interactive and non-interactive ssh login based on a conditional logic. I need to test the username and give an error message.

People using sftp (non-interactive ssh) should also be subject to the luckness test.

How would I implement that? I have full control of the system.

I tried to use sshd ForceCommand, but according to https://stackoverflow.com/a/33714333/746461 it does not work for notty.

I'm not familiar with PAM and I doubt if PAM can output custom error message in case the login is interactive.

https://linuxhint.com/understanding_bash_shell_configuration_startup/ says non-interactive login shell with --noprofile option can bypass all bash config files. That's why I can't write my logic there.


I figured out. I can implement a PAM module to do that.

Save the following to, say, file /root/checkConnections.

#! /bin/bash

limit=$1
c=$(pgrep -xcu $PAM_USER sshd)
if [[ $c -ge "$limit" ]]; then 
    echo "Max $limit ssh connections allowed, but you have $c."
    exit 1
fi

Then in /etc/pam.d/sshd, add

session required pam_exec.so stdout /root/checkConnections 5

pam_exec.so executes the shell script, stdout outputs messages to user terimal.

When the condition fails, the effect is like this.

$ ssh localhost
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-74-generic x86_64)

94 updates can be installed immediately.
0 of these updates are security updates.
To see these additional updates run: apt list --upgradable

Max 5 ssh connections allowed, but you have 5.
/root/checkConnections failed: exit code 1
Last login: Thu Jun 24 12:19:27 2021 from 172.18.33.67
Connection to localhost closed.