SERGO SIMONISHVILI

Инженерное решение · IPoE и LANBilling

Когда биллинг считает абонента подключённым

Как мы разобрались с зависшими IPoE-сессиями и автоматизировали восстановление доступа

Абонент звонит: интернета нет. Роутер перезагружали, кабель на месте, оптика в норме. А в журнале авторизации раз за разом одна и та же строка — AlreadyConnected. Биллинг уверен, что абонент и так подключён.

Где работает
Портал мониторинга сети провайдера
Проверка
Каждые 2 минуты
Режим
Автоматический, один сброс за цикл
Схема 1Как возникает проблема
  1. Обычная сессия

    • Сервер доступасессия есть
    • LANBillingсессия открыта

    Accounting-Update раз в несколько минут

  2. Accounting-Stop потерян

    Сбой, обрыв связи или перезапуск биллинга

  3. Состояния разошлись

    • Сервер доступасессии нет
    • LANBillingсессия всё ещё открыта
  4. Отказ AlreadyConnected

    Устройство просится в сеть снова, биллинг отвечает: этот абонент уже подключён

Почему так происходит

Одно подключение — две записи

В IPoE-сети логина и пароля в привычном смысле нет. Сервер доступа видит устройство, спрашивает биллинг по RADIUS и после Access-Accept открывает сессию. Раз в несколько минут он отправляет Accounting-Update, а при отключении — Accounting-Stop, и тогда LANBilling закрывает сессию у себя. Пока сообщения доходят, записи на сервере доступа и в биллинге совпадают.

Когда Accounting-Stop теряется

Биллинг перезапускался, пропала связь между серверами, сервер доступа потерял сессии после сбоя — и Accounting-Stop не дошёл. Сервер доступа о сессии уже забыл, LANBilling держит её открытой. Устройство абонента снова просится в сеть, а биллинг отказывает с причиной AlreadyConnected: по его данным абонент и так подключён.

Почему не помогают перезагрузка и ожидание

Перезагрузка роутера или ONU даёт новый запрос, но открытая сессия в биллинге остаётся, и отказ повторяется. Тайм-аут зависшей сессии в нашей настройке — сутки, и даже после него сессия сама не закрывается. Штатный Disconnect из биллинга тоже не помогает: сервер доступа такой сессии не знает и отвечает Disconnect-NAK, а биллинг оставляет запись открытой.

Пятнадцать сессий после обслуживания

Автоматика ходила по кругу

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

Закрыть запись в биллинге

Штатный Disconnect вернул Disconnect-NAK. Править таблицы базы напрямую я не стал: это обходит логику биллинга. В API LANBilling есть метод, который завершает RADIUS-сессию по её точным реквизитам. Первый вызов ответил «успешно», но сессия осталась: адрес сервера доступа при подготовке запроса превращался в пустое значение. С тех пор успехом считается только повторное чтение, в котором сессии нет. Исправленный вызов я сначала сделал для одного абонента, дождался полного интервала аккаунтинга и только потом — для остальных четырнадцати. Доступ вернулся всем.

Почему первой версии автоматики не хватило

Первая автоматическая версия брала кандидатов из сверки с сервером доступа. Вскоре нашёлся абонент, которого она не видела: запись о нём на сервере доступа жила несколько секунд, а сверка раз в две минуты учитывает только записи старше минуты. Человек больше суток оставался без доступа. Так появился второй источник — журнал отказов авторизации в биллинге. Заодно цикл стал запускаться не только после перезагрузки сервера биллинга, но и при перезапуске его служб и когда сверка несколько раз подряд находит одно и то же.

Как устроена автоматика

Каждые две минуты автоматика собирает данные из трёх мест и решает, есть ли сессия, которую можно безопасно закрыть.

1

LANBilling

Открытые RADIUS-сессии: учётная запись, MAC, сервер доступа, время последнего Accounting-Update. Через API — состояние учётной записи: тариф и блокировки.

2

Журнал авторизации

Отказы AlreadyConnected: когда был последний, сколько попыток, с какого MAC и через какой сервер доступа. Выгрузка раз в минуту, только чтение.

3

Сервер доступа

Есть ли у этого MAC активная сессия прямо сейчас. Снимок состояния не старше пяти минут.

Схема 2Как работает автоматика
  • LANBillingоткрытые сессии и аккаунтинг
  • Журнал RADIUSповторные AlreadyConnected
  • Сервер доступафактическое подключение

Проверка

  • аккаунтинг молчит ≥ 15 мин
  • у соседних сессий он идёт
  • ≥ 2 свежих отказа, тот же MAC
  • на сервере доступа сессии нет
  • без блокировок и новых авторизаций
  • перечитать всё перед вызовом

Хоть одно условие не выполнено — сессию не трогаем и записываем причину

Завершение сессии через API LANBilling

Контроль восстановления, до 30 минут

Новая сессия и аккаунтинг → сообщение «восстановлено»

Не подтвердилось → только наблюдение и сообщение инженеру

Что проверяется перед сбросом

  • Сессия молчит давно. Accounting-Update приходят примерно раз в пять минут. Зависшей сессия считается, если по ней нет данных хотя бы 15 минут — три пропущенных интервала подряд.
  • Аккаунтинг вообще работает. По тому же серверу доступа за последние 10 минут должны обновиться хотя бы три других сессии. Если тишина у всех, это авария биллинга или канала, а не зависшая сессия, и автоматика ничего не трогает.
  • Абонент действительно пытается подключиться. В журнале минимум два отказа AlreadyConnected не старше получаса и позже последнего аккаунтинга — с тем же MAC и через тот же сервер доступа.
  • Сервер доступа эту сессию не обслуживает. В свежем снимке нет активной сессии для этого MAC.
  • С учётной записью всё понятно. Ровно одна открытая сессия, все реквизиты на месте, нет блокировки и не было более новой успешной авторизации.
  • За это время ничего не изменилось. Прямо перед вызовом API всё перечитывается. Если сессия хоть немного изменилась, сброс откладывается.

Сброс и проверка

Если всё сошлось, автоматика вызывает в API LANBilling завершение RADIUS-сессии с только что прочитанными реквизитами и несколько раз перечитывает список: API иногда ещё пару секунд показывает удалённую сессию. Затем до получаса ждёт подтверждения: новая сессия с тем же MAC, аккаунтинг по ней, абонент активен на сервере доступа, тариф и блокировки прежние. Пока это не подтверждено, случай не закрывается.

Почему не закрыть всё подряд

Закрыть все сессии без свежего аккаунтинга — самый простой и самый опасный вариант: аккаунтинг может опаздывать и у живой сессии. Когда я проверял фильтр на живых данных, отказы AlreadyConnected за день были у нескольких десятков учётных записей, почти у всех безобидные: устройство повторно запрашивало доступ при работающей сессии. По-настоящему зависшей оказалась одна. Поэтому сессия со свежим аккаунтингом защищена, а если данных не хватает или они устарели, автоматика ничего не трогает и пишет в журнал причину.

Результат

Схема 3Последовательность событий
  1. каждые 2 минОбнаружениезависшая сессия и повторные отказы
  2. перед вызовомПроверка актуальностивсё перечитано, ничего не изменилось
  3. 0:00Сброссессия завершена через API, повторное чтение подтвердило
  4. +2:37Повторная авторизацияAccess-Accept, абонент получил IP-адрес
  5. +7:38Accounting-Updateпервые данные по новой сессии
  6. +9:41Подтверждение результатаабонент активен, тариф и доступ прежние
  7. MAXУведомление«восстановление завершено»

Время отсчитано от сброса — по контролируемому восстановлению.

Контролируемое восстановление

Перед включением автоматического режима я провёл одно контролируемое восстановление — на том самом абоненте, которого не видела первая версия. Предварительный прогон показал, что все проверки пройдены, и сброс выполнили только для него:

  • старая RADIUS-сессия в биллинге закрыта и больше не появилась;
  • абонент снова прошёл авторизацию;
  • получил IP-адрес;
  • по новой сессии пошёл аккаунтинг;
  • тариф, ограничение скорости и состояние блокировок остались прежними.

Этот прогон поймал последнюю ошибку. API ещё секунду после удаления показывал сессию в списке, и автоматика записала успешный сброс как неудачный. Проверку переделали на несколько повторных чтений.

Постоянный режим

После этого автоматический режим включён постоянно. Ограничения на первое время намеренно жёсткие: не больше одного сброса за цикл и не больше двух попыток на учётную запись. Если после сброса старая сессия вернулась, удаление не подтвердилось или у абонента изменились параметры доступа, автоматика сама переходит в режим наблюдения: продолжает находить зависшие сессии, но больше ничего не сбрасывает. Об этом сразу приходит сообщение в MAX. Включить автоматический режим обратно можно только вручную, разобравшись в причине.

Обещать, что теперь любой абонент восстановится за две минуты, я не буду. Две минуты — это периодичность проверки. Сессия должна сначала замолчать на 15 минут, абонент должен несколько раз попытаться подключиться, а при одном сбросе за цикл крупная авария разбирается по очереди. Зато зависшая сессия больше не ждёт, пока абонент дозвонится в поддержку, а инженер вручную полезет в биллинг.

Что приходит в MAX

О каждом сбросе и каждой неудаче автоматика пишет инженеру в MAX. В сообщениях нет MAC, имён и номеров договоров — только счётчики, режим и код причины. Подробности инженер смотрит в портале.

Демонстрационный пример. Время, счётчики и статусы вымышлены; формат и формулировки повторяют настоящие уведомления.

Демонстрационный примерУспешное автоматическое восстановление

Портал · уведомлениябот

Сегодня

IPoE: зависшая сессия завершена автоматически

Клиентов без активной сессии на сервере доступа: 1

Зависших сессий в биллинге: 1; восстановлено: 0; не восстановлено: 0

Автоматика: автоматическое снятие включено

Причина: none

IPoE: восстановление сессий завершено

Клиентов без активной сессии на сервере доступа: 0

Зависших сессий в биллинге: 1; восстановлено: 1; не восстановлено: 0

Автоматика: автоматическое снятие включено

Причина: none

Открыть фоновые задачи
Демонстрационный примерОшибка восстановления, нужен инженер

Портал · уведомлениябот

Сегодня

IPoE: попытка завершить зависшую сессию не удалась

Клиентов без активной сессии на сервере доступа: 1

Зависших сессий в биллинге: 1; восстановлено: 0; не восстановлено: 1

Автоматика: автоматическое снятие включено

Причина: delete_without_effect

Проверьте задачу «Восстановление IPoE после загрузки». Не сбрасывайте всех клиентов.

IPoE: автоматическое снятие остановлено, включено только обнаружение

Клиентов без активной сессии на сервере доступа: 1

Зависших сессий в биллинге: 1; восстановлено: 0; не восстановлено: 1

Автоматика: только обнаружение

Причина: delete_without_effect

Открыть фоновые задачи

Что изменилось

  • Зависшая сессия находится сама — по повторным отказам AlreadyConnected и состоянию сервера доступа, а не по звонку в поддержку.
  • Сессия закрывается штатным API LANBilling и считается восстановленной только после новой авторизации и аккаунтинга.
  • Любая неудача или цикл без прогресса доходят до инженера в MAX, а автоматика сама переходит в режим наблюдения.

Это первый материал из серии об устройстве портала. Следующие будут появляться в разделе «Инженерные решения» основного кейса.