7

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
user2      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?

13
  • 2
    HIPAA requires you to implement denial of service attacks against yourself?
    – Alex Holst
    Jan 26, 2011 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, 2011 at 20:19
  • 4
    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. Jan 27, 2011 at 21:01
  • 1
    @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, 2011 at 21:30
  • 1
    @mmr — cryptographic tokens are a good way to deal with that. :)
    – mattdm
    Mar 9, 2011 at 21:00

6 Answers 6

6
+100

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

3
  • This looks very promising-- testing it out now, thanks!
    – mmr
    Mar 9, 2011 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, 2011 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. Mar 10, 2011 at 18:30
3

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

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

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.

3
  • 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, 2011 at 22:54
  • 1
    @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, 2011 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. Jun 26, 2020 at 5:23
1

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.

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

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.

3
  • 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, 2011 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. Jan 26, 2011 at 23:08
  • 1
    There's always the "If you are caught logging in from two places simultaneously, there will be consequences." approach.
    – mattdm
    Mar 9, 2011 at 21:01
0

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .