I use the excellent OpenVPN for my VPN needs. Since version 2 it supports printing a nice status file of currently connected clients but unfortunately it is a bit ugly.
I wrote a simple php library that can parse this file and returns a associative array of logged in users, you can then easily display it using Smarty or whatever you use for templating.
You can download version 1.0 here you can also check out the README and a Sample that I did using Smarty.
Nice script.
I found it best to add a trim() around the [updated] element.
Useful. Thanks.
Suggestion: if the logfile passed to parseLog() fails to fopen() correctly, the script loops endlessly. After the fopen(), do a test to make sure it actually opened, perhaps like this:
function parseLog ($log, $proto) {
$handle = fopen($log, “r”);
if(!$handle)return false;
If you want to use this script with ethernet bridge (aka TAP) mode you need to change the second expression to:
preg_match(“/^(.+[:\.].+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)$/”, $buffer, $match)
I modified this script so that it is possible to get the status info directly from the management console of an openvpn daemon!
function parseLogConnection ($pass,$server=”127.0.0.1″,$port=5555, $proto) {
global $debug_out;
$handle = fsockopen($server, $port, $errno, $errstr, 3);
if(!$handle)
return false;
$uid = 0;
$output = fgets($handle, 15); //”ENTER PASSWORD:” !!no newline at the end
if (strstr($output,”PASSWORD”))
{
fputs($handle, “$pass\n”);
//fflush($connection);
$output = fgets($handle, 100);
if (strstr($output,”SUCCESS”)){
$output = fgets($handle, 100); // INFO: line
fputs($handle, “status\n”);
$buffer=””;
while (!feof($handle) && !strstr($buffer,”END”)) {
$buffer = fgets($handle, 4096);
unset($match);
if (ereg(“^Updated,(.+)”, $buffer, $match)) {
$status[‘updated’] = $match[1];
}
$i=0;
if (preg_match(“/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)$/”, $buffer, $match)) {
$i++;
if ($match[1] > “Common Name”) {
//$debug_out[‘match1’][$i]=$match;
$cn = $match[1];
// associative array to store a numeric id
// for each remote ip:port because smarty doesnt
// like looping on strings in a section
$userlookup[$match[2]] = $uid;
$status[‘users’][$uid][‘CommonName’] = $match[1];
$status[‘users’][$uid][‘RealAddress’] = $match[2];
$status[‘users’][$uid][‘BytesReceived’] = sizeformat($match[3]);
$status[‘users’][$uid][‘BytesSent’] = sizeformat($match[4]);
$status[‘users’][$uid][‘Since’] = $match[5];
$status[‘users’][$uid][‘Proto’] = $proto;
$uid++;
}
}
$i=0;
if (preg_match(“/^(.+[:\.].+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)$/”, $buffer, $match)) {
$i++;
if ($match[1] > “Virtual Address”) {
//$debug_out[‘match2’][$i]=$match;
$address = $match[3];
// find the uid in the lookup table
$uid = $userlookup[$address];
$status[‘users’][$uid][‘VirtualAddress’] = $match[1];
$status[‘users’][$uid][‘LastRef’] = $match[4];
}
}
}
/* if (is_array($debug_out)){
$debug_out[‘userlookup’]=$userlookup;
$debug_out[‘status’]=$status;
$debug_out[‘file’]=file($log);
}
*/
fputs($handle, “exit\n”);
fclose($handle);
return($status);
}
}
return false;
}
Do you have a source php file that generates the output of your sample?
I can’t get it to work due to my lack of Smarty knowledge…
after ALOT of tries i came to this…hope is helps somebody!
thats inside the html-body:
assign(‘tcpusers’, $tcpusers[users]);
$smarty->display(‘smarty_vpn.tpl’);
echo “Letzte Aktualisierung: $tcpusers[updated]“;
?>
the template had to be in a extra ‘templates’ directory…
also there had to be an ‘templates_c’ directory, writeable by the www-user.
hmm…there is missing something i copy/pasted….