от Todor Lazarov(20-02-2002)
рейтинг (1)
[ добре ]
[ зле ]
Вариант за отпечатване
Ето ви едно решение как да огражичим Dial-up по трафик като
използваме ICRadius
IC-RADIUS 0.18.1 не разполага със средства за да можем да
ограничаваме Dial-up по трафик.
По не аз не можаш да открия.
За това ето едно решение за това.
Хубавото е че Linux е отворена система (т.е. всеки може да
променя кода)
Ето и какво сам добавил:
----------------------------------------------------------------------------------
1. files.c
след ред 429: case PW_WEEKLY_TIME_LIMIT:
се добавя: case PW_MAX_MEGABYTES:
Променлива която се проверява в файла auth.c
----------------------------------------------------------------------------------
2. radius.h
след ред 156: #define PW_WEEKLY_TIME_LIMIT 2006
се добавя: #define PW_MAX_MEGABYTES 2010
Деклариране на тази променлива
----------------------------------------------------------------------------------
3. auth.c
Поставете го например след проверката за WEEKLY_TIME_LIMIT
за Realm
/* New attribute in Mb format */
if (result >=0 && (check_item =
pairfind(authreq->check_pairs, PW_MAX_MEGABYTES)) !=
NULL) {
SQL_ROW row;
char querystr[256];
unsigned long allowed;
unsigned long used = 0;
allowed = check_item->lvalue * 1048576;
/* Проверка дали Realm е надхвърлил трафика
тука можем и да проверяваме и
за месец, ден и т.н */
sprintf(querystr, "SELECT
SUM(AcctInputOctets+AcctOutputOctets) FROM radacct WHERE
Realm ='%s'", authreq->realm);
sql_select_query(socket, querystr);
row = sql_fetch_row(socket);
if (row[0] == NULL)
used = 0;
else
used = atol(row[0]);
sql_finish_select_query(socket);
if (used >= allowed) {
sprintf(umsg, "\r\nYour realm has
reached it's limit of %d
Mb\r\n\n",(int)check_item->lvalue);
user_msg = umsg;
result = -1;
/* Връща се резултат за грешка при
индификацията
с което напрактика се води до
прекъсване на сесията*/
rad_send_reply(PW_AUTHENTICATION_REJECT, authreq,
authreq->reply_pairs, user_msg, activefd);
log(L_ERR, "ERR - Realm usage
limit of %d Mb reached: [%s] (%s)",
(int)check_item->lvalue, authreq->realm,
auth_name(authreq, 1));
}
}
Поставете го например след проверката за MAX_HOURS за
Username
/* New attribute in Mb format */
if (result >=0 && (check_item =
pairfind(authreq->check_pairs, PW_MAX_MEGABYTES)) !=
NULL) {
SQL_ROW row;
char querystr[256];
unsigned long allowed;
unsigned long used = 0;
allowed = check_item->lvalue *
1048576;
/* Проверка дали потребителя е надхвърлил
трафика
тука можем и да проверяваме и
за месец, ден и т.н */
sprintf(querystr, "SELECT
SUM(AcctInputOctets+AcctOutputOctets) FROM radacct WHERE
UserName ='%s'", authreq->realm);
sql_select_query(socket, querystr);
row = sql_fetch_row(socket);
if (row[0] == NULL)
used = 0;
else
used = atol(row[0]);
sql_finish_select_query(socket);
if (used >= allowed) {
sprintf(umsg, "\r\nYour
account has reached its limit of %d Mb\r\n\n",
(int)check_item->lvalue);
user_msg = umsg;
result = -1;
/* Връща се резултат за грешка
при индификацията
с което напрактика се води до
прекъсване на сесията*/
rad_send_reply(PW_AUTHENTICATION_REJECT, authreq,
authreq->reply_pairs, user_msg, activefd);
log(L_ERR, "ERR - Usage
limit of %d Mb reached: [%s] (%s)",
(int)check_item->lvalue, namepair->strvalue,
auth_name(authreq, 1));
}
}
4. Добавете ред в таблица dictionnary:
INSERT INTO dictionnary (Type, Attribute, Value, Format)
VALUES ('ATTRIBUTE', 'MAX_MEGABYTES', '2010',
'integer');
след което си прекомпилирайте ICRadius-a и го стартирайте
отново
Самото задаване го извършвам от модула radius.cgi
Това е показано в прикрепения файл:
Една забележка:
Има само едно слабо место !!!
Както виждате от source данните се четат от таблицата
radacct
А там се записват данните след като сесията свърши.
т.е. Dial-up ноже да превиши дадения му трафик ако го
надхвърли в дадена сесия.
Но при следващо логване машината ще го изхвърли.
Което разбира се е някъкъв резултат. !!!
<< КАК ДА СЕ БЪЛГАРИЗИРАМЕ - нов тертип | Девет препоръки за писане на сигурен php код >>
|