Информация
Услуги
  • Внедрение
  • Настройка
  • Поддержка
  • Ремонт
Контакты
Новинка
Распродажа
Новости
Доставка
Оплата
Загрузки
  • Прошивки
    • WinBox
    • RouterOS
    • Мобильные приложения MikroTik
    • Архив
  • RouterOS
  • Мобильные приложения MikroTik
  • Архив
Форум
Настройка
    info@mikrotik.moscow
    +7 495 320-55-52
    Заказать звонок
    Mikrotik.moscow
    Каталог
    • Акции
      Акции
    • Маршрутизаторы
      Маршрутизаторы
    • Коммутаторы
      Коммутаторы
    • Радиомосты и уличные точки доступа
      Радиомосты и уличные точки доступа
    • Wi-Fi для дома и офиса
      Wi-Fi для дома и офиса
    • LTE/5G
      LTE/5G
    • Powerline адаптеры
      Powerline адаптеры
    • IoT устройства
      IoT устройства
    • Оборудование 60 ГГц
      Оборудование 60 ГГц
    • Материнские платы RouterBOARD
      Материнские платы RouterBOARD
    • Корпуса
      Корпуса
    • Интерфейсы
      Интерфейсы
    • SFP/QSFP трансиверы
      SFP/QSFP трансиверы
    • Аксессуары
      Аксессуары
    • Антенны
      Антенны
    • Архив
      Архив
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Скачать WinBox Скачать Прошивки Форум > RouterOS Форум > SwOS Форум > Железо
    Mikrotik.moscow
    Каталог
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Mikrotik.moscow
    Телефоны
    +7 495 320-55-52
    Заказать звонок
    0
    0
    0
    Mikrotik.moscow
    • +7 495 320-55-52
      • Назад
      • Телефоны
      • +7 495 320-55-52
      • Заказать звонок
    • info@mikrotik.moscow
    • г. Москва, ул. Бакунинская, 84
    • Пн-Пт: 09-00 до 18-00
      Сб-Вс: выходной


    • Кабинет
    • 0 Сравнение
    • 0 Избранное
    • 0 Корзина
    Главная
    Форум
    Форум
    RouterOS
    Проблема с RADIUS AcctSessionId (дублированный учёт).

    Проблема с RADIUS AcctSessionId (дублированный учёт).

    Форумы: RouterOS, Аппаратное обеспечение, SwOS, Обратная связь, Объявления, Сторонние инструменты
    Поиск  Пользователи  Правила  Войти
    Страницы: 1
    RSS
    Проблема с RADIUS AcctSessionId (дублированный учёт)., RouterOS
     
    poinths
    Guest
    #1
    0
    30.05.2006 22:22:00
    RouterOS генерирует RADIUS AcctSessionId, который не очень уникален. Один и тот же session-id иногда генерируется в течение нескольких дней или часов. Если этот session-id ранее использовался для пользователя, и теперь этот же пользователь получает тот же session-id, то Radius accounting (radacct) обновит как новую, так и старую запись учета. Эта проблема усиливается при установке нескольких устройств RouterOS и роуминге пользователей между ними.

    Пример: Старая запись radacct: AcctSessionId: 80f000e0, UserName: testuser, Date: 2006-05-20 21:44:13

    Новая запись radacct: AcctSessionId: 80f000e0, UserName: testuser, Date: 2006-05-30 16:14:23 (Обратите внимание: один и тот же AcctSessionId)

    FreeRadius radacct использует AcctSessionId, UserName и NASIPAddress для обновления записи сессии:
    accounting_update_query = "UPDAT E ${acct_table1} SET FramedIPAddress = ‘%{Framed-IP-Address}’, AcctSessionTime = ‘%{Acct-Session-Time}’, AcctInputOctets = ‘%{Acct-Input-Octets}’, AcctOutputOctets = ‘%{Acct-Output-Octets}’ WHERE AcctSessionId = ‘%{Acct-Session-Id}’ AND UserName = ‘%{SQL-User-Name}’ AND NASIPAddress= ‘%{NAS-IP-Address}’"

    В этом сценарии Radius обновит обе записи, что означает, что время сессии и трафик загрузки/выгрузки будет учтен дважды.

    Текущие AcctSessionId’s в RouterOS: 80f000e0, 80f000e1, 80f000e2, 80f000e3, 80f000e5

    Другие производители используют более уникальный Id: 447ce53300000013, 447c862f0000000f, 447c57cd00000006

    Если я создам уникальный SQL-ключ для AcctSessionId и UserName, то INSERT будет проигнорирован, а "старая" запись будет обновлена. Это работает, но приведет к некорректным записям учета, так как старая запись будет перезаписана. Желателен более уникальный AcctSessionId! Или есть способ задать длину sessionId?
     
     
     
    savage
    Guest
    #2
    0
    31.05.2006 04:14:00
    Не обновляйте свои базы данных, используя RadSessionId, используйте RadUniqueID. В конфигурационном файле radius есть настройка, в которой можно указать, какие атрибуты использовать для создания этой уникальной хэш-суммы, чтобы она оставалась уникальной. Я использую acct_unique { key = “User-Name, Acct-Session-Id, NAS-IP-Address, Client-IP-Address, NAS-Port” }. Пока что проблем не возникало.
     
     
     
    poinths
    Guest
    #3
    0
    31.05.2006 04:21:00
    Спасибо! Посмотрю.
     
     
     
    savage
    Guest
    #4
    0
    31.05.2006 05:55:00
    Продолжение, все упустил в спешке этим утром… Данные учета нужно обрабатывать. Сидеть с таблицей учета, содержащей миллионы и миллионы записей, крайне неэффективно, потому что Radius должен выполнять запросы к этим данным, которые могут занять очень много времени. Создай еще две таблицы для себя…

    ```mysql
    mysql> DESCRIBE RadiusAcctTotals;
    +-----------------+-------------+------+-----+------------+----------------+
    | Field           | Type        | Null | Key | Default    | Extra          |
    +-----------------+-------------+------+-----+------------+----------------+
    | TotAcctId       | bigint(21)  | NO   | PRI | NULL       | auto_increment |
    | UserName        | varchar(64) | NO   | MUL | NULL       |                |
    | AcctDate        | date        | NO   | MUL | 0000-00-00 |                |
    | ConnNum         | bigint(12)  | YES  |     | NULL       |                |
    | ConnTotDuration | bigint(12)  | YES  |     | NULL       |                |
    | ConnMaxDuration | bigint(12)  | YES  |     | NULL       |                |
    | ConnMinDuration | bigint(12)  | YES  |     | NULL       |                |
    | InputOctets     | bigint(12)  | YES  |     | NULL       |                |
    | OutputOctets    | bigint(12)  | YES  |     | NULL       |                |
    +-----------------+-------------+------+-----+------------+----------------+
    9 rows in set (0.02 sec)

    mysql> DESCRIBE RadiusAcctMonthlyTotals;
    +-----------------+-------------+------+-----+------------+----------------+
    | Field           | Type        | Null | Key | Default    | Extra          |
    +-----------------+-------------+------+-----+------------+----------------+
    | MTotAcctId      | bigint(21)  | NO   | PRI | NULL       | auto_increment |
    | UserName        | varchar(64) | NO   | MUL | NULL       |                |
    | AcctDate        | date        | NO   | MUL | 0000-00-00 |                |
    | ConnNum         | bigint(12)  | YES  |     | NULL       |                |
    | ConnTotDuration | bigint(12)  | YES  |     | NULL       |                |
    | ConnMaxDuration | bigint(12)  | YES  |     | NULL       |                |
    | ConnMinDuration | bigint(12)  | YES  |     | NULL       |                |
    | InputOctets     | bigint(12)  | YES  |     | NULL       |                |
    | OutputOctets    | bigint(12)  | YES  |     | NULL       |                |
    +-----------------+-------------+------+-----+------------+----------------+
    9 rows in set (0.01 sec)
    ```

    В рамках ежедневной процедуры обслуживания перемещай все данные учета из таблицы Radius Accounting, которые неактивны (имеют `acctstoptime`) и старше нескольких дней, в таблицы RadiusAcctTotals. Затем удаляй старые записи из таблицы Radius Accounting. Таким образом, основная таблица учета, используемая Radius, будет маленькой, компактной и не вызовет никаких проблем. Выполняются следующие шаги:

    1.  Удаление записей старше 90 дней, так как они уже находятся в таблице AcctMonthlyTotals.
       ```mysql
       DELETE FROM RadiusAcctTotals WHERE AcctDate = '" . $Date_Start . "'
       ```
    2.  Перемещение данных учета, закрытых за день, из таблиц Radius Accounting в обобщенную версию нашей собственной таблицы Accounting Data (мы делаем это на уровне пользователей, а не сессий, что уменьшает количество записей).
       ```mysql
       INSERT INTO RadiusAcctTotals (UserName, AcctDate, ConnNum, ConnTotDuration, ConnMaxDuration, ConnMinDuration, InputOctets, OutputOctets)
       SELECT UserName, '" . $Date_Small_Start . "', COUNT(RadAcctId), SUM(AcctSessionTime), MAX(AcctSessionTime), MIN(AcctSessionTime), SUM(AcctInputOctets), SUM(AcctOutputOctets)
       FROM RadiusAccounting
       WHERE AcctStopTime >= '" . $Date_Start . "' AND AcctStopTime < '" . $Date_End . "' AND UserName LIKE '%@%'
       GROUP BY UserName
       ```
    3.  Удаление данных учета из таблиц Radius Accounting, которые мы только что скопировали в нашу собственную обобщенную таблицу Accounting Data.
       ```mysql
       DELETE FROM RadiusAccounting
       WHERE AcctStopTime >= '" . $Date_Start . "' AND AcctStopTime < '" . $Date_End . "' AND UserName LIKE '%@%'
       ```

    В конце месяца я обычно выполняю запрос к моей ежедневной таблице учета и создаю ежемесячные итоги для моих пользователей в ежемесячной таблице учета. В конце дня я могу хранить 100 лет (если захочу) данных учета на основе ежемесячного использования с нулевым влиянием на сервер Radius… В конце месяца мы выполняем, среди прочего: перемещение обобщенных (мы теперь переходим с ежедневных на ежемесячные) данных учета из наших собственных таблиц учета в ежемесячные таблицы.
    ```mysql
    INSERT INTO RadiusAcctMonthlyTotals (UserName, AcctDate, ConnNum, ConnTotDuration, ConnMaxDuration, ConnMinDuration, InputOctets, OutputOctets)
    SELECT UserName, '" . $Date_Start . "', SUM(ConnNum), SUM(ConnTotDuration), MAX(ConnMaxDuration), MIN(ConnMinDuration), SUM(InputOctets), SUM(OutputOctets)
    FROM RadiusAcctTotals
    WHERE AcctDate >= '" . $Date_Start . "' AND AcctDate <= '" . $Date_End . "'
    GROUP BY UserName
    ```
    Удаление нашей ежедневной статистики из статистики, которые у нас есть в нашей ежемесячной таблице.
    ```mysql
    DELETE FROM RadiusAcctTotals
    WHERE AcctDate >= '" . $Date_Start . "' AND AcctDate <= '" . $Date_End . "'
    ```
    Конечно, ты можешь создать свою собственную систему по своему усмотрению, и тебе не удастся просто скопировать и вставить мою, но ты поймешь суть. Данные нужно обрабатывать, нельзя просто вываливать их в базу данных и ожидать, что они будут работать вечно. Базовая идея заключается в том, чтобы иметь как можно меньше записей в таблицах учета, используемых Radius, но то, как ты этого достигнешь, очевидно, можно сделать множеством разных способов — некоторые из которых могут тебе подойти, некоторые — нет. — C
     
     
     
    poinths
    Guest
    #5
    0
    31.05.2006 06:05:00
    Спасибо за очень подробное решение! Похоже, можно прекратить работу над этой проблемой, так как я уже начал её решать. Возьму ваш совет и интегрирую в нашу систему как можно скорее (pointHotspot.com). Удачи!
     
     
     
    savage
    Guest
    #6
    0
    31.05.2006 06:21:00
    Рад, что смог помочь. Ещё один момент, чтобы прояснить ваш первоначальный вопрос (жалобу?) по поводу SessionID… SessionID генерируется NAS, но NAS требуется иметь уникальный Session ID только для каждого активного подключённого сеанса. Как только пользователь отключается и подключается другой, NAS имеет полное право присвоить тот же SessionID другому пользователю. Когда два пользователя подключены одновременно и имеют один и тот же SessionID – ТОГДА NAS точно не прав, и производителям нужно бы пристрелить и выставить на всеобщее обозрение (Это, разумеется, не относится к MPPP – которая в любом случае не поддерживается MT, но которая, очевидно, будет иметь один и тот же SessionID). Чтобы обойти это, FreeRadius разработал модуль UniqueID для генерации уникального хеша на основе значений различных атрибутов. Это тоже не гарантирует уникальность, но вероятность получения дубликата намного ниже. Если вы действительно умны и объедините это с модулем rlm_exec, вы можете сгенерировать хеш на основе /dev/random или /bin/date +%s, что гарантированно всегда будет уникальным (я даже видел, как люди используют SELECT UUID() в MySQL). В некоторых более крупных установках приходилось использовать что-то подобное.

    Теперь у меня есть ещё одна тема, которую нужно обязательно внести в WIKI, когда у меня появится время... – C
     
     
     
    poinths
    Guest
    #7
    0
    31.05.2006 06:39:00
    Спасибо ещё раз! Я уже изменил обновление radacct, используя уникальный идентификатор сессии, просто не знал, что он был доступен в это время ('%{Acct-Unique-Session-Id}'). Да, я понимаю проблему с идентификатором сессии, генерируемым NAS. И с увеличением количества устройств на сервере RADIUS проблемы будут усиливаться. FreeRadius использует стандартный ключ = “User-Name, Acct-Session-Id, NAS-IP-Address, Client-IP-Address, NAS-Port” для создания уникального идентификатора сессии. Здесь ничего менять не нужно. Нашёл заметку в FR ./doc директории (tuning_guide): “Добавьте AcctUniqueId в запрос accounting_stop. Особенно, если у вас много серверов доступа или ваш NAS не генерирует очень случайные Session-Id. Тогда у вас всегда будет одна строка-кандидат для поиска, вместо всех строк с одинаковым AcctSessionId”. В общем, я добавил уникальный ID в ‘accounting_update_query’ и ‘accounting_start_query_alt’. Это должно помочь!
     
     
     
    Страницы: 1
    Читают тему
    +7 495 320-55-52
    info@mikrotik.moscow
    Электрозаводская, Бауманская
    Москва, ул. Бакунинская, 84с21
    Конфиденциальность Оферта
    © 2026 «Mikrotik.Moscow»
    Главная Каталог 0 Корзина 0 Избранные Кабинет 0 Сравнение Акции Контакты Услуги Бренды Отзывы Компания Лицензии Документы Реквизиты Поиск Блог Обзоры