
http://mpd.sourceforge.net/doc5/mpd31.html#31 - реализация небольшой системы учета трафика штатными средствами MPD для демонстрации механизма работы MPD External AAA.
Требуется:
MPD, MySQL, PHP (iconv, hash, mcrypt, mysqli) и прямые руки

Реализация:
(грубая, сырая, 30-и минутная с помощью подручных средств

mpd.conf
Код: Выделить всё
...
set auth max-logins 1
set auth acct-update 60
set auth timeout 15
set auth extauth-script /usr/local/etc/mpd5/auth.php
set auth extacct-script /usr/local/etc/mpd5/acct.php
set auth disable internal
set auth enable ext-auth ext-acct acct-mandatory
...
Код: Выделить всё
...
$db =@new mysqli("<HOST>", "<USER>", "<PASS>", "<NAME>");
/**
* On invocation extauth/extacct scripts receive on stdin set of request
* attribute:value pairs terminated by empty line and must generate response
* in same format on stdout.
*/
$request = array();
$response = array();
$fhandle = fopen("php://stdin", "r");
while ($line = fgets($fhandle)) {
if ($line == "\n")
break;
if (preg_match("/^(.+):(.+)\n$/", $line, $matches))
$request[$matches[1]] = $matches[2];
}
fclose($fhandle);
$result =@$db->query("SELECT `framed_ip_address`, `password` FROM `users` WHERE `username`='".$db->escape_string($request["USER_NAME"])."' AND `blocked`='0'");
if ($result && $result->num_rows > 0) {
list($response["FRAMED_IP_ADDRESS"], $response["USER_PASSWORD"]) = $result->fetch_row();
$response["USER_NAME"] = $request["USER_NAME"];
/**
* Generates the NT-HASH from the given plaintext password.
* Implemented in PEAR Crypt_CHAP by Michael Bretterklieber
* http://pear.php.net/package/Crypt_CHAP
*/
$response["USER_NT_HASH"] = pack("H*", hash("md4", pack("H*", iconv("ASCII", "UTF-16", $response["USER_PASSWORD"]))));
$response["RESULT"] = "UNDEF";
$result->free();
} else
$response["RESULT"] = "FAIL";
/**
* On invocation extauth/extacct scripts receive on stdin set of request
* attribute:value pairs terminated by empty line and must generate response
* in same format on stdout.
*/
$fhandle = fopen("php://stdout", "w");
foreach ($response as $key => $value)
fputs($fhandle, "$key:$value\n");
fputs($fhandle, "\n");
fclose($fhandle);
...
Код: Выделить всё
...
$db =@new mysqli("<HOST>", "<USER>", "<PASS>", "<NAME>");
$request = array();
$response = array();
/**
* On invocation extauth/extacct scripts receive on stdin set of request
* attribute:value pairs terminated by empty line and must generate response
* in same format on stdout.
*/
$fhandle = fopen("php://stdin", "r");
while ($line = fgets($fhandle)) {
if ($line == "\n")
break;
if (preg_match("/^(.+):(.+)\n$/", $line, $matches))
$request[$matches[1]] = $matches[2];
}
fclose($fhandle);
/**
* ACCT_STATUS_TYPE: START UPDATE STOP
*/
switch ($request["ACCT_STATUS_TYPE"]) {
case "START":
$query = "INSERT INTO acct VALUES ('%s', UNIX_TIMESTAMP(), 0, '%s', '%s', 0, 0, 0, 0, 0)";
$query = sprintf($query,
$request["ACCT_SESSION_ID"],
$request["USER_NAME"],
$request["PEER_ADDR"]);
@$db->query($query);
break;
case "UPDATE":
$query = "UPDATE acct SET acct_session_time=%d, acct_input_octets=%d, acct_input_packets=%d, acct_output_octets=%d, acct_output_packets=%d WHERE acct_session_id='%s'";
$query = sprintf($query,
intval($request["ACCT_SESSION_TIME"]),
intval($request["ACCT_INPUT_OCTETS"]),
intval($request["ACCT_INPUT_PACKETS"]),
intval($request["ACCT_OUTPUT_OCTETS"]),
intval($request["ACCT_OUTPUT_PACKETS"]),
$request["ACCT_SESSION_ID"]);
@$db->query($query);
break;
case "STOP":
$query = "UPDATE acct SET session_stop=UNIX_TIMESTAMP() WHERE acct_session_id='%s'";
$query = sprintf($query,
$request["ACCT_SESSION_ID"]);
@$db->query($query);
break;
}
/**
* On invocation extauth/extacct scripts receive on stdin set of request
* attribute:value pairs terminated by empty line and must generate response
* in same format on stdout.
*/
$fhandle = fopen("php://stdout", "w");
foreach ($response as $key => $value)
fputs($fhandle, "$key:$value\n");
fputs($fhandle, "\n");
fclose($fhandle);
...
Код: Выделить всё
CREATE TABLE IF NOT EXISTS `acct` (
`acct_session_id` varchar(20) NOT NULL,
`session_start` int(11) NOT NULL,
`session_stop` int(11) NOT NULL,
`user_name` varchar(20) NOT NULL,
`peer_addr` varchar(15) NOT NULL,
`acct_session_time` int(11) NOT NULL,
`acct_input_octets` int(11) NOT NULL,
`acct_input_packets` int(11) NOT NULL,
`acct_output_octets` int(11) NOT NULL,
`acct_output_packets` int(11) NOT NULL,
KEY `acct_session_id` (`acct_session_id`),
KEY `user_name` (`user_name`)
) ENGINE=MyISAM;
Код: Выделить всё
CREATE TABLE IF NOT EXISTS `users` (
`username` varchar(16) NOT NULL,
`password` varchar(16) NOT NULL,
`blocked` tinyint(1) NOT NULL DEFAULT '0',
`framed_ip_address` varchar(15) NOT NULL,
UNIQUE KEY `username` (`username`),
KEY `password` (`password`)
) ENGINE=MyISAM;