Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Limit OS X Server VPN connections to one per user OS X Server
VPN in Mac OS X Server (all versions, I think) allows users to have as many sessions from as many different computers as they want to the VPN server. I didn't like this, so I tried to find a way to restrict them to only one session. I tried looking at plists, thinking maybe Apple had some hidden option for this, but I couldn't find it. I then dug around in man files for vpn and pppd and such, and found something of interest in pppd's man page:
/etc/ppp/auth-up
A program or script which is executed after the remote system successfully authenticates itself. It is executed with the parameters:

interface-name peer-name user-name tty-device speed

Note that this script is not executed if the peer doesn't authenticate itself, for example when the noauth option is used.
Great! All I need now is some code and a way to find out which users are currently online.

After some more man reading, I found this command with grep to do just that:
serveradmin command vpn:command = getConnectedUsers | grep -G "vpn:ConnectedUsers:_array_index:[[:xdigit:]]*:name"
Then I made the script. Copy and paste this into the file /private/etc/ppp/auth-down: What the script does is to check if the user who just logged in is already logged in. If he is, we kill his connection. Yes, it's a little dirty, but it works great. Please comment on this if you have a better way to do it, or improvements to the above script.
    •    
  • Currently 2.10 / 5
  You rated: 1 / 5 (10 votes cast)
 
[10,308 views]  

Limit OS X Server VPN connections to one per user | 6 comments | Create New Account
Click here to return to the 'Limit OS X Server VPN connections to one per user' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Limit OS X Server VPN connections to one per user
Authored by: mannyveloso on Jun 26, '08 01:49:17PM

I do this another way on my server. The main problem is that if a user is using an L2TP/IPsec connection, they won't be notified by the OS that their connection was terminated.

Other than that, this method works pretty well.



[ Reply to This | # ]
Limit OS X Server VPN connections to one per user
Authored by: Johnny_B on Jun 26, '08 07:25:28PM

Care to share your method?



[ Reply to This | # ]
Limit OS X Server VPN connections to one per user
Authored by: mannyveloso on Jun 27, '08 04:04:02PM

Well, I tail system.log looking for logins, then when I get a login I pass that to a script that essentally does the same thing as this script does.

I might move to the auth-up/down scripts, though, because it looks like they might be more reliable than system.log in relation to logouts.



[ Reply to This | # ]
Limit OS X Server VPN connections to one per user
Authored by: Johnny_B on Mar 22, '09 10:14:24AM
There is an error in the hint... Please replace this line:
Then I made the script. Copy and paste this into the file /private/etc/ppp/auth-down:
With:
Then I made the script. Copy and paste this into the file /private/etc/ppp/auth-up:


[ Reply to This | # ]
Limit OS X Server VPN connections to one per user
Authored by: Johnny_B on Jun 02, '09 05:01:06PM
There is an error in the hint... Please replace this line:
my $interface =$ARGV[0]
With:
my $interface =$ARGV[0];


[ Reply to This | # ]
Limit OS X Server VPN connections to one per user
Authored by: Cerberus on Oct 30, '09 12:02:16PM
Thank you for this! I was wandering around the interwebs wondering if there was anyway to easily watch who was in and out of my VPN service and I found this. This is an AWESOME start!

What I ran into was that once applied, any client would immediately be disconnected saying there were already logged in. And this is true if you count the CURRENT connection...

So I started down a path that took me all the way to possibly finding a bug.I have submitted it to bugtracker. The gist is that pppd does not pass the ttydevice to auto-up nor to ip-up. So I had to write a few lines to get this info.

I am the type of admin that does NOT like process' doing things in the 'dark', so I captured some pertinent info into /var/log/auto-up and /var/log/ip-up and it now notifies syslog when it force kills a connection. I may sort the data better once I am comfortable it all works consistently (it has been fine for the past 6 hours but I want longer before blessing it completely.

Next code change will be some way to allow a group or something to have more than one (don't know why I want that but I hate being pigeon-holed)

#!/usr/bin/perl
use Fcntl; #The Module

# Version 1.0
# made june 25. by Simen S. .ya, simen@mac.com
# please don't remove my name from the credits if you modify the source
# from http://www.macosxhints.com/article.php?story=20080625145536473

# Modified 30 Oct 2009 - Peter J Scordamaglia
# send notification of forcibly denied VPN Connections to authpriv.notice

my $in = `/usr/sbin/serveradmin command vpn:command = getConnectedUsers | /usr/bin/grep -G "vpn:ConnectedUsers:_array_index:[[:xdigit:]]*:name"`;
my $interface = $ARGV[0];
my $peername  = $ARGV[1];
my $username  = $ARGV[2];
my $ttydevice = $ARGV[3];
my $speed     = $ARGV[4];

my $filepath = "/private/var/log/auth-up";
($sec,$min,$hour,$mday,$mon,$year) = localtime(time);

my @list = split(/\n/, $in);
my $s;
my $u;
my $i;
my $checktty;

  open ( TEXT, ">", $filepath ) or die "$filepath cannot be opened: $!";
  printf TEXT "%4d-%02d-%02d %02d:%02d:%02d ",$year+1900,$mon+1,$mday,$hour,$min,$sec;

  printf TEXT "full list of VPN Users-------\n\n$in\n";

foreach $l (@list) {
   $s=index($l, "=");
   $line=substr($l,$s+3);
   my @array_index = split(/:/, $l);
   chop($u=$line);
   printf TEXT "\nlist split = '$l'\n";
   printf TEXT "index_array= $array_index[3]\n";
   printf TEXT "userfound  = '$u'\n";
   printf TEXT "interface  = '$interface'\n";
   printf TEXT "peername   = '$peername'\n";
   printf TEXT "username   = '$username'\n";
   printf TEXT "ttydevice  = '$ttydevice'\n";
   printf TEXT "TTY speed  = '$speed'\n";
   my $ttyarray = `/usr/sbin/serveradmin command vpn:command = getConnectedUsers | /usr/bin/grep -G "vpn:ConnectedUsers:_array_index:$array_index[3]:InterfaceName"`;
   $i=index($ttyarray, "=");
   $checktty=substr($ttyarray,$i+3);
   chomp($checktty);
   chop($checktty);
   printf TEXT "Checktty   = '$checktty' (Array_Index'$array_index[3]')\n";
   if ($u eq $peername) {
       printf TEXT "Username did match peername. Checking interface.\n";
       if ($checktty eq $interface) {
          printf TEXT "Checktty Equals Interface!\n";
          printf TEXT "Checktty   = '$checktty'\n";
          printf TEXT "Interface  = '$interface'\n";
       } else {
     printf TEXT "\n ***** Forcably killing $peername\@$interface\n\n";
          system("/bin/kill `/bin/cat /private/var/run/$interface.pid`");
     system("/usr/bin/logger -p authpriv.notice -t auth-up \"Multiple VPN Connections Denied for $peername\"");
       }
   } else {
       printf TEXT "Username did not match peername\n";
   }
}
   close (TEXT);


[ Reply to This | # ]