Биллинговая система Nodeny

Главная категория => Nodeny 49 => Тема начата: vitaliych от 14 Апреля 2011, 11:13:31



Название: Учет трафика pptp-сессий
Отправлено: vitaliych от 14 Апреля 2011, 11:13:31
Собственно вопрос - как? Accounting на радиусе настроил, радиус accounting-пакеты аккуратно шлет:
rad_recv: Accounting-Request packet from host 127.0.0.1 port 57523, id=174, length=141
        Acct-Session-Id = "4DA6B632096000"
        User-Name = "testuser"
        Acct-Status-Type = Interim-Update
        Service-Type = Framed-User
        Framed-Protocol = PPP
        Acct-Authentic = RADIUS
        Acct-Session-Time = 243
        Acct-Output-Octets = 288
        Acct-Input-Octets = 250122
        Acct-Output-Packets = 6
        Acct-Input-Packets = 4690

        Calling-Station-Id = "10.0.0.10"
        NAS-Port-Type = Async
        Framed-IP-Address = 192.168.0.200
        NAS-IP-Address = 10.0.0.1
        NAS-Port = 0
        Acct-Delay-Time = 0

Вопрос - как в биллинге посчитать трафик? Процедура radreply аж ни разу данные в базу не заносит, только проверяет состояние соединения.
Похоже, что трафик рртр вообще не считается биллингом?
Заранее извиняюсь, если вопрос повторный, поиском ничего не нашел на эту тему.


Название: Re: Учет трафика pptp-сессий
Отправлено: stix от 14 Апреля 2011, 11:29:15
учет идет через нетфлоу, потому как больше ориентировано на сети без ppp доступа


Название: Re: Учет трафика pptp-сессий
Отправлено: Efendy от 14 Апреля 2011, 15:00:27
Радиус не дает детализацию трафика, поэтому эта фича не используется. С другой стороны, если детализация трафика пофик, то можно обновлять по radupdate. Только учтите, что radupdate посылает общий трафик за сессию, поэтому нужно за каждую итерацию получать разницу и добавлять ее к текущим показаниям. В проекте ПБ я это сделал через промежуточную таблицу radcounts. Даю пример, только учтите, что он несовместим с NoDeny напрямую, его стоит взять тока за основу

Код:
DROP PROCEDURE IF EXISTS `radupdate`;
DELIMITER $$
CREATE PROCEDURE `radupdate` (
  IN login VARCHAR(64),
  IN ses_id VARCHAR(32),
  IN ses_time INT,
  IN ses_traf_in BIGINT(20),
  IN ses_traf_out BIGINT(20),
  IN ip VARCHAR(16),
  IN Calling_Station_Id VARCHAR(32),
  IN Called_Station_Id VARCHAR(32)
)
BEGIN
  CheckBlock:BEGIN
    DECLARE usr_id INT;
    DECLARE tm INT;
    DECLARE t_in, t_out BIGINT(20);

    SELECT parent_id INTO usr_id FROM dopdata WHERE field_alias='_login' AND field_value=login LIMIT 1;
    IF( usr_id IS NULL ) THEN LEAVE CheckBlock; END IF;

    SELECT traf_in, traf_out, time INTO t_in, t_out, tm FROM radcounts WHERE session=ses_id LIMIT 1;
    IF( t_in is NULL ) THEN
       SET t_in  = 0;
       SET t_out = 0;
       SET tm    = 0;
       INSERT INTO radcounts SET session=ses_id;
    END IF;

    SET t_in  = ses_traf_in  - t_in;
    SET t_out = ses_traf_out - t_out;
    SET tm    = ses_time - tm;
    UPDATE radcounts SET traf_in=ses_traf_in, traf_out=ses_traf_out, time=ses_time WHERE session=ses_id LIMIT 1;   

    INSERT dopvalues SET parent_id=usr_id, field_value=t_in, dopfield_id=
      (SELECT id FROM dopfields WHERE field_alias='_traf_in' LIMIT 1)
      ON DUPLICATE KEY UPDATE field_value=field_value+t_in;

    INSERT dopvalues SET parent_id=usr_id, field_value=t_out, dopfield_id=
      (SELECT id FROM dopfields WHERE field_alias='_traf_out' LIMIT 1)
      ON DUPLICATE KEY UPDATE field_value=field_value+t_out;

    INSERT dopvalues SET parent_id=usr_id, field_value=tm, dopfield_id=
      (SELECT id FROM dopfields WHERE field_alias='_work_time' LIMIT 1)
      ON DUPLICATE KEY UPDATE field_value=field_value+tm;

    INSERT into login_query SET
        uid        = usr_id,
        act        = 0,
        time       = unix_timestamp(),
        ip         = INET_ATON(ip),
        session    = ses_id,
        router     = Called_Station_Id,
        properties = CONCAT('|client:' , Calling_Station_Id, '|');

  END;
END$$
DELIMITER ;

в конфиге радиуса:

accounting_update_query = "call radupdate( \
           '%{SQL-User-Name}','%{Acct-Session-Id}',%{Acct-Session-Time},%{Acct-Output-Octets},%{Acct-Input-Octets}, \
           '%{Framed-IP-Address}','%{Calling-Station-Id}','%{Called-Station-Id}')"



Название: Re: Учет трафика pptp-сессий
Отправлено: Efendy от 14 Апреля 2011, 15:07:52
Разница в том, что общий трафик в примере хранится в дополнительных полях, а в NoDeny в отдельной таблице


Название: Re: Учет трафика pptp-сессий
Отправлено: vitaliych от 14 Апреля 2011, 15:39:13
Детализация не нужна, пока во всяком случае.
Да в базу получить данные не проблема, вполне достатчно примеров из самого радиуса, на выходе будем иметь таблицу radacct, в которой будет вся необходимая информация по сессии. Вопрос в том, что эту таблицу нужно как-то в биллинг занести.Придется писать что-то вроде коллектора своего.
Я вопрос задал в надежде, что чего-то не дочитал в документации и что начну изобретать велосипед. Но, видимо, все-таки разработчики такое не реализовали:
учет идет через нетфлоу, потому как больше ориентировано на сети без ppp доступа
. Видимо, именно для того, чтобы получить детализацию.


Название: Re: Учет трафика pptp-сессий
Отправлено: 0xbad0c0d3 от 14 Апреля 2011, 15:41:11
Да, правильнее всего это свой коллектор.


Название: Re: Учет трафика pptp-сессий
Отправлено: vitaliych от 19 Апреля 2011, 12:47:16
Все гораздо проще оказалось: ipcad+iptables ULOG.
Может кому пригодится:

Система CentOS 5.5:

# /etc/ipcad.conf - меняем интерфейс на:
interface  ulog group 1;

#  добавляем правило для iptables:
iptables -I FORWARD -j ULOG --ulog-nlgroup 1

Все, все остальные настройки по документации. Считается весь транзитный трафик, сразу решаем проблему с учетом локального трафика.
Способ универсальный, не только для pptp.


Название: Re: Учет трафика pptp-сессий
Отправлено: versus от 26 Апреля 2011, 14:22:37
Вы 5 дней искали то, что в биллинге идет по умолчанию через диверт.


Название: Re: Учет трафика pptp-сессий
Отправлено: vitaliych от 27 Апреля 2011, 11:36:02
Не совсем. Для FreeBSD - да. У меня же Linux, я выше писал.Хотя механизм с ULOG - это, по сути, аналог BSD-шного divert.