How can I disconnect ssh users, or limit the number of ssh logins?

I have an application that is using ssh to authenticate. Due to a variety of regulations (HIPAA, etc) users can only be logged in for a certain amount of time, and they can only be logged in once.

I would like for sshd to automatically disconnect a user if another, second connection is attempted. The idea is: user 1 is connected. user 2 uses user 1's credentials to try to log in. both are kicked (we aren't sure if user 1 or user 2 is legit).
If this happens more than X times in Y minutes, the account is frozen until an administrator unfreezes it (most likely due to a password reset).

Right now, users are sandboxed in their own scponly directories; I'm not sure if that matters.

Trying to kill individual sshd connections is like playing whackamole, and I'd prefer this to be something that sshd does itself, and not a root-level script.

EDIT: This is on

2.6.31-22-server #73-Ubuntu SMP


And my limits.conf file contains lines like:

user1      hard   maxlogins    1


and my sshd_config file contains the line:

UsePAM yes


Yet I can still log in as user1 from multiple different machines. What am I doing wrong here, so that I can at least block user1 from having multiple logins?

• HIPAA requires you to implement denial of service attacks against yourself? – Alex Holst Jan 26 '11 at 20:07
• We are required to have an audit trail. Multiple logins suggests that two people are using the same login, which means that the audit trail is fuzzy, to say the least. – mmr Jan 26 '11 at 20:19
• It is a bad thing because you are wasting money and time trying to implement something that will decrease productivity and you are trying to use HIPAA to justify it. I assume you are trying to satisfy 164.312.a.2.i (unique user names) iii (automatic logoff). For the purposes of HIPAA you are logged off if you have to re-enter your password, which is exactly what a screensaver can do. – Mark Wagner Jan 27 '11 at 21:01
• @embobo-- no, I'm trying to increase income by preventing a single user from sharing credentials with others and thereby decrease the number of licenses of a product, and using HIPAA to justify it. – mmr Jan 27 '11 at 21:30
• @mmr — cryptographic tokens are a good way to deal with that. :) – mattdm Mar 9 '11 at 21:00

Setting up maxlogins limit actually works here. Just make sure you use '-' limit type, not 'hard'.

user1          -       maxlogins       1


If you want to kick users who made double login using scponly, here's quick and dirty script, which does that. Put it into crontab, so it executes every minute.

#!/bin/sh

for user in grep scponly /etc/passwd | gawk -F: '{print $1}'; do echo "Checking user:$user"
instances=ps -u $user| grep scponly | wc -l echo "scponly instances$instances"
if [ $instances -gt 1 ] ; then echo "Too many connections detected, slaying scponly for user$user"
if [ -e /tmp/$user ] ; then attempts=cat /tmp/$user
echo "Detected $attempts attempts" # increment attempts counter echo$(($attempts+1)) > /tmp/$user

if [ $attempts -gt 3 ] ; then echo "Blocking$user"
/usr/sbin/usermod -L $user fi else echo "1" > /tmp/$user
fi
killall -u $user scponly fi done  Download script: http://dl.dropbox.com/u/17194482/kill-scponly.sh • This looks very promising-- testing it out now, thanks! – mmr Mar 9 '11 at 19:41 • OK, when I check ps -u <user>, I'm getting 'sshd' and 'sftp-server', not scponly. Which should mean that the maxlogins limit should be used, right? But I can still login via ssh using the same user account, even with the limits set. – mmr Mar 10 '11 at 17:05 • My example is based on scponly shell login attempt. Replace scponly with sftp-server in following line: instances=ps -u$user| grep scponly | wc -l. If you try to login via ssh (not scp), scponly will be spawned. Perhaps you want to check for both. – Dmitry Alexeyev Mar 10 '11 at 18:30

The PAM limits won't catch scp or sftp connections because they are not allocated a pty or written to utmp.

• good to know. So, with that in mind, the cronjob script is the better way to go? – mmr Mar 9 '11 at 22:33

You might look at /etc/security/limits.conf for these sort of limits. http://linux.die.net/man/5/limits.conf

There is a 'maxlogins' limit that can be configured on a per user or per usergroup basis. This won't disconnect previous sessions but will restricted concurrent sessions.

• I just tried it, and it doesn't work. I put in the line 'username hard maxlogins 1', and that username can still login multiple times. – mmr Jan 26 '11 at 22:54
• @mmr: you'll need to have sshd using PAM and pam_limits configured for the ssh login path. Also sshd does not use PAM to authenticate keys, only password or challenge-response authentication schemes can use PAM – DerfK Jan 27 '11 at 0:25
• If UsePAM is set to yes, sshd does in fact use PAM when logging in in with keys, but only for session and account handling. This holds even when password and challenge-response authentication is used. The problem here is that maxlogins is not enforced if you don't allocate a pty. – Tenders McChiken Jun 26 '20 at 5:23

Since you are using a special shell without remote execution abilities, you can't do a little hack in their login shell. It would be pretty easy to just in the shell figure out if they are already logged in and if not, log them out.

We used to have idled, which did exactly this. (http://idled.sourceforge.net/ or http://www.ibiblio.org/pub/Linux/system/admin/idle/!INDEX.html), It doesn't seem that it's all that well maintained now, since PAM has come to life.

PAM gives you a bajillion ways to do what you want, see the list of PAM modules here: http://www.kernel.org/pub/linux/libs/pam/modules.html

Any single one probably doesn't do all the things you want, but together you can do whatever you want, or even write your own module. Like @DerfK said, you have to configure SSH to use PAM.

• I thought that the line UsePAM Yes meant that ssh was configured to use PAM then; is that wrong? – mmr Mar 9 '11 at 18:58
• openssh.com/faq.html#3.15 – Tara Mar 9 '11 at 21:11

If it's because of accounting reasons as mentioned in the comments, you might want to look at the GNU Accounting Utilities. These will allow you to do everything upto and including seeing which users ran what process, for how long, and how much CPU and RAM they took. This does require kernel support, but most modern distros will have it compiled in already.

• will this allow me to kick doubly-connected users? Or just see who's doing what, without necessarily allowing me to take action? – mmr Jan 26 '11 at 23:05
• It will allow you to audit who's doing what and where they were logged in from. It won't do anything about logging them out, but it might avoid the necessity. – Niall Donegan Jan 26 '11 at 23:08
• There's always the "If you are caught logging in from two places simultaneously, there will be consequences." approach. – mattdm Mar 9 '11 at 21:01

I'm not sure using a cron each minute is the best approach. I tried this workaround and that works for me. Hopefully there is no side effect.

Match User foo
ForceCommand /usr/sbin/sftp-limit


With the following script redirecting stdin/stdout to the sftp-server process only if the number of processes for a given user doesn't exceed the "SFTP_LIMIT_PER_USER" var.

#!/bin/bash

SFTP_LIMIT_PER_USER=1
out="$(ps aux | grep -c "${USER} .*sftp-server")"
if [ $out -gt$SFTP_LIMIT_PER_USER ]; then
logger "sftp-limit: limit reached for user \$USER"
exit 0
fi
/usr/libexec/openssh/sftp-server <&0 >&1


HTH.