Объяснение ошибки MORE_THEN_ALLOW_LOGIN при схеме авторизации USER_MAC,NAS_MAC,VLAN,PORT
1. Суть проблемы
Ошибка `MORE_THEN_ALLOW_LOGIN` возникает, когда система считает, что пользователь пытается установить **вторую** (или N+1) сессию, превышая лимит одновременных подключений (обычно 1), вместо того чтобы понять, что это **переподключение** той же самой сессии.
При данной схеме авторизации (`USER_MAC,NAS_MAC,VLAN,PORT`) система находит пользователя в базе данных по совокупности этих параметров и определяет его логин (например, `user1`). После этого включается механизм проверки одновременных сессий (`check_simultaneously`).
2. Технические детали (как работает Auth2.pm)
В файле `Auth2.pm` (строки ~394-436) происходит следующее:
1. Поиск активных сессий:
Система делает запрос в таблицу `internet_online`, выбирая все активные сессии для данного логина (`user_name`).
SELECT cid, ... FROM internet_online WHERE user_name='user1' ...
Допустим, в базе уже висит "зависшая" или просто активная сессия пользователя.
2. Попытка "склеить" сессии (Zap/Reassign):
Система пытается понять, является ли новая попытка подключения *тем же самым* устройством. Для этого она сравнивает идентификатор звонящего (`Calling-Station-Id` или `CID`) из новой попытки с `cid`, сохраненным в базе для старой сессии.
Код проверки (упрощенно):
if ($line->[0] eq $cid && $line->[2] eq $NAS->{NAS_ID}) {
# Это тот же самый CID и тот же NAS -> Считаем это переподключением
# "Убиваем" старую сессию (status=6)
$active_logins--; # Уменьшаем счетчик активных сессий
}
```
3. Сбой проверки:
При схеме `USER_MAC,NAS_MAC,VLAN,PORT` часто возникает ситуация, когда:
- В новой попытке подключения переменная `$cid` (берется из RADIUS-атрибута `Calling-Station-Id`) либо **пуста**, либо **отличается форматом** (например, `001122334455` без двоеточий), либо вообще не передается NAS-ом в том виде, в котором ожидается.
- А параметр `USER_MAC`, по которому шла авторизация (и который вытащили, например, из DHCP Option 82), **не попадает автоматически** в переменную `$cid`, используемую для сверки сессий.
В результате:
- `$line->[0] eq $cid` возвращает `false`.
- Система думает: "Ага, CID разные, значит это *другое* устройство пытается зайти под тем же логином".
- Счетчик `active_logins` не уменьшается.
- Итог: `active_logins >= LOGINS` -> Ошибка `MORE_THEN_ALLOW_LOGIN`.
3. Почему именно эта схема уязвима?
Схема `USER_MAC,NAS_MAC,VLAN,PORT` часто используется в IPoE (DHCP) сетях. В таких сетях `Calling-Station-Id` (стандартный RADIUS атрибут 31) может быть не заполнен коммутатором или сервером доступа, так как MAC-адрес передается внутри опций DHCP (Option 82) или в заголовке Ethernet пакета, который парсится отдельно в `USER_MAC`.
Если логика авторизации нашла пользователя по `USER_MAC`, но не обновила глобальный `$cid` (Calling-Station-Id) значением этого `USER_MAC`, то механизм контроля сессий сравнивает "пустое" или "неверное" значение с тем, что в базе, и не признает в новом подключении старого знакомого.
4. Рекомендация
Для исправления необходимо убедиться, что при авторизации IPoE значение `Calling-Station-Id` (CID) принудительно устанавливается равным `USER_MAC` (нормализованному, с двоеточиями), чтобы механизм проверки сессий (`check_simultaneously`) мог корректно идентифицировать и сбрасывать старые зависшие сессии того же абонента.