от Todor Lazarov(20-02-2002)

рейтинг (0)   [ добре ]  [ зле ]

Printer Friendly Вариант за отпечатване

Ето ви едно решение как да огражичим 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 код >>