Visit Jeremy's Blog.
Go Back > Forums > Non-*NIX Forums > Programming
User Name
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.


  Search this Thread
Old 02-27-2008, 03:56 AM   #1
Registered: Jan 2005
Location: NZ
Distribution: Fedora / Debian
Posts: 99

Rep: Reputation: 21
Question Help implementing ssh trickery


I'm after some help with writing a bash script to do the following:

1. Check the users logged in via ssh
2. If two instances of the username exist, kill the connection which is older.

Basically, I want to implement a system where the latest user is allowed to stay, and the old user is disconnected.

I am looking for some help writing a bash script that will execute every minute by cron. The first part I need help with would be how to actually get the usernames + times + PIDs (so the connection can be killed). I know of the `w' and `who' commands. While they provide the time, they do not provide the PIDs. And the `ps x | grep sshd' command which I investigated does not provide the amount of time the user has been logged in.

Is there a 'clean' way of doing what I ask or do I have to ninja it through a bash script?

Any help appreciated!
Old 02-27-2008, 07:40 AM   #2
Registered: May 2001
Posts: 29,361
Blog Entries: 55

Rep: Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547
If you use PAM and have your remote SSH users in a group, then setting "maxlogins" (and "maxsyslogins") for "@groupname" in /etc/security/limits.conf to "4" might be a start to limit the amount of logons. There's an practical explanation why it must be >= 4 and not == 1 but for that you'll have to unravel which of ssh, getty, shell play a part in logging in. For me setting logins+2 worked for years.

Now killing sessions may be a good idea from an admins POV, but if you don't know how to measure session inactivity or what the user is doing at the time then this could be counterproductive. Prevention is better. How about using "on auth" pam_script in your /etc/pam.d/sshd? Here's how to test.
- Set aforementioned logins to "5" (for testing, else the PAM stack already errors out),
- Add line "auth required onauth="/etc/security/" to /etc/pam.d/sshd,
- Create "/etc/security/" with contents
# pam_script auth required /etc/security/ 
/usr/bin/pgrep -u "$1" -f 'ssh ' >/dev/null 2>&1 || exit 0
exit 1
0. Ssh in as unprivileged user. This should work.
1. Now ssh in again as same unprivileged user. This should not work and /var/log/secure should show a "pam_session_open()" denied message.


Last edited by unSpawn; 02-27-2008 at 07:41 AM.
Old 02-28-2008, 10:05 PM   #3
Registered: Jan 2005
Location: NZ
Distribution: Fedora / Debian
Posts: 99

Original Poster
Rep: Reputation: 21
The reason I want to kill the old connection and allow the new one is because the server only provides a secure tunnel, nothing else. I want to eliminate the situation which will arise when the user forgetfully leaves it logged in in at home, and now they can't log in from elsewhere.

I've already managed to limit max number of concurrent logins. Is there a way to actually process output of 'w' or 'who' or 'ps x | grep ssh' or somesuch to disconnect the old / both users?

I just want the thing to DC so the user does not have to actually close the old session in order to get into the server again, while at the same time, the user cannot be logged in twice.

Edit: I think this is the best way to do it:

$ ps x | grep 'sshd:'
24526 ?        Ss     0:01 sshd: root@pts/3
25723 ?        Ss     0:00 sshd: breakaway [priv]
25754 ?        Ss     0:00 sshd: vent [priv]
25846 ?        Ss     0:00 sshd: devon [priv]
25941 ?        Ss     0:00 sshd: breakaway [priv]
26016 pts/3    R+     0:00 grep sshd:
Now to figure out how to use 'tr' to get only the PID and the usernames out and process them, and then kill them both.

Edit 2: figured out how to use 'tr' and 'cut' to get only what I want out of the output:

 $ ps x | grep priv | tr -s " " | cut -f 1,6 -d ' '
25723 breakaway
25754 vent
25846 devon
25941 breakaway
26617 priv
Obviously the last one (26617 priv) can be ignored as it is just grep printing itself.

Now to somehow compare each value (usernames) to every otehr value in order to see if there are any matches. If there are, then pass their PIDs to the 'kill' command.


Last edited by brokenpromises; 02-29-2008 at 02:28 AM.



Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
implementing FiST dip2040 Linux - Software 0 01-02-2007 05:14 AM
implementing ping in C++ allomeen Linux - Networking 0 05-10-2006 05:47 PM
implementing a firewall nitinatindore Linux - Security 1 01-04-2005 10:21 AM
implementing ping? pcdude Programming 4 11-03-2004 04:57 AM
implementing a graph bprasanth_20 Programming 4 10-25-2003 12:44 AM > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:00 AM.

Main Menu
Write for LQ is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration