inet_contract_templates= Слушатель InetRadiusListener
Слушатель предназначен для обработки RADIUS-пакетов. Общие сведения о протоколе RADIUS доступны здесь.
Добавляется в контейнер следующим образом.
<context name="radius">
<!-- Cоздание процессора RADIUS-пакетов -->
<bean name="radiusProcessor" class="ru.avantis.abilling.modules.inet.radius.InetRadiusProcessor"/>
<!-- Служебный ScheduledExecutorService, необходимый для dataLogger -->
<scheduledExecutorService name="hrlydtlggr" corePoolSize="1" />
<!-- Cоздание dataLogger, сохраняющего RADIUS-пакеты на диск (только один экземпляр) -->
<bean name="radiusDataLogger" class="ru.avantis.abilling.modules.inet.radius.RadiusHourlyDataLogger">
<param name="scheduledExecutor">hrlydtlggr</param>
</bean>
<!-- Cоздание слушателя RADIUS-пакетов на порту с передачей ему процессора и dataLogger -->
<bean name="radiusListener" class="ru.avantis.abilling.modules.inet.radius.InetRadiusListener">
<constructor>
<!-- Хост (интерфейс), на котором будет открыт сокет. Если пусто - на всех -->
<param name="host" value=""/>
<!-- Порт, на котором будет открыт сокет -->
<param name="port" value="1812"/>
<!-- Размер буфера приема слушателя -->
<param name="recvBufferSize">512 * 1024</param>
<!-- Рекомендуемый SO_RCVBUF-сокета -->
<param name="soRCVBUF"></param>
<!-- Количество потоков-обработчиков -->
<param name="threadCount">10</param>
<!-- Максимальное количество пакетов в очереди на обработку -->
<param name="maxQueueSize">200</param>
<!-- Передача процессора -->
<param name="processor">radiusProcessor</param>
<!-- Режим работы, RadiusListener.Mode.authentication -->
<param name="mode">RadiusListener.Mode.authentication</param>
<!-- Передача dataLogger -->
<param name="dataLogger">radiusDataLogger</param>
</constructor>
</bean>
</context>
Параметры:
-
radiusProcessor - класс процессора, реализующий логику обработки пакетов;
-
radiusDataLogger - объект, осуществляющий запись бинарных логов, по умолчанию это объект типа ru.avantis.abilling.modules.inet.radius.RadiusHourlyDataLogger (сохранение бинарных логов с разбивкой по источникам и часам);
-
host - IP-адрес, на котором слушатель, пустое значение - прослушивать любой IP-адрес;
-
port - прослушиваемый UDP-порт;
-
soRCVBUF - рекомендуемый SO_RCVBUF (socket recieve buffer) для сокета. На FreeBSD большие значения могут вызвать ошибку и сервер не запустится;
-
byteBufferCapacity - размер буфера для приёма пакетов;
-
threadCount - число потоков-обработчиков пакетов, рекомендуемые значения 10-30, не рекомендуется указывать более 100;
-
maxQueueSize - максимальный размер очереди пакетов, при превышении размера очереди пакеты начинают отбрасываться и высылается аларм, рекомендуемые значения 200-1000. Следует учитывать, что если по какой-то причине сервер не успевает обрабатывать пакеты, очередь растет, то какие-то пакеты из очереди могут быть обработаны с опозданием и NAS уже выслал повторный запрос, который опять попадет в очередь и опять может быть обработан с опозданием. Поэтому большое значение вместо распределения нагрузки может вызвать ее увеличение;
-
mode - режим работы, может принимать значения RadiusListener.Mode.authentication для обработки Access-Request-пакетов в InetAccess и RadiusListener.Mode.accounting для обработки Accounting-пакетов в InetAccounting.
Процессор ru.avantis.abilling.modules.inet.radius.InetRadiusProcessor
Предназначен для авторизации и аккаунтинга по протоколу RADIUS большинства типов коммутируемых соединений.
Загружает список NAS’ов из дочерних узлов корневого узла сервера, начиная с самого корневого узла. Если нужно фильтовать по типам устройств (т.е. какие-то дочерние узлы не учитывать как NAS’ы), то в конфигурации корневого устройства в параметре radius.deviceTypeIds необходимо указать id типов устройств-NAS’ов через запятую. У устройства-NAS’а поле Идентификатор должно быть заполнено.
Поиск NAS’а для пришедшего пакета производится сначала по атрибуту NAS-Identifier с поиском по идентификатору устройства, затем, если устройство не найдено, по NAS-IP-Address с поиском по хостам устройств. Сессия сервиса привязывается к устройству, представляющему NAS.
Поиск сервиса/логина
При авторизации поиск сервиса Inet может осуществляться как по логину, так и по интерфейсу или VLAN’у. Для указания режима поиска необходимо прописать в конфигурации устройства-NAS’а или в конфиге любого его устройства-предка параметр:
# Режим поиска сервиса: 0 (по умолчанию) - по логину, 1 - по интерфейсу на устройстве (в предобработке должны быть
# проставлены опции AGENT_REMOTE_ID и AGENT_CIRCUIT_ID или INTERFACE_ID), 2 - по VLAN на устройстве (в предобработке
# должны быть проставлены опции AGENT_REMOTE_ID и AGENT_CIRCUIT_ID или VLAN_ID), 4 - по VLAN на устройстве или
# дочернем устройстве (в предобработке должны быть проставлены опции AGENT_REMOTE_ID и AGENT_CIRCUIT_ID или VLAN_ID),
# 5 - по MAC-адресу на устройстве (в предобработке должна быть проставлена опция MAC_ADDRESS), 6 - по MAC-адресу на
# устройстве или дочернем устройстве (в предобработке должна быть проставлена опция MAC_ADDRESS).
radius.servSearchMode=0
radius.servSearchMode может принимать значения:
-
0 - поиск по логину из атрибута User-Name;
-
1 - поиск по интерфейсу на (найденном) устройстве;
-
2 - поиск по VLAN’у на устройстве (в предобработке должны быть проставлены опции AGENT_REMOTE_ID и AGENT_CIRCUIT_ID или VLAN_ID);
-
4 - поиск по VLAN’у на устройстве и его дочерних устройствах (в предобработке должны быть проставлены опции AGENT_REMOTE_ID и AGENT_CIRCUIT_ID или VLAN_ID);
-
5 - поиск по MAC-адресу на устройстве (в предобработке должна быть проставлена опция MAC_ADDRESS);
-
6 - поиск по MAC-адресу на устройстве и дочерних устройствах (в предобработке должна быть проставлена опция MAC_ADDRESS);
-
7 - поиск по адресу, указанному в User-Name, из диапазона адресов сервиса (в типе сервиса должно быть указано serv.search.address=1);
-
9 - поиск по адресу, указанному в User-Name, из диапазона адресов сервиса (в типе сервиса должно быть указано serv.search.address=1) на агентских (дочерних) устройствах;
-
10 - поиск по MAC-адресу на всех устройствах.
Также возможен дополнительный поиск дочернего сервиса:
radius.servSearchMode=<servSearchMode>-<subServSearchMode>
<subServSearchMode> может принимать значения:
-
0 или отсутсвует - нет поиска дочернего сервиса;
-
1 - поиск дочернего сервиса по MAC-адресу, если такого дочернего сервиса нет - ошибка авторизации;
-
2 - поиск дочернего сервиса по MAC-адресу, если такого дочернего сервиса нет - сессия будет привязана к родительскому сервису;
-
5 - поиск дочернего сервиса по IP-адресу из поля User-Name, если такого дочернего сервиса нет - ошибка авторизации;
-
6 - поиск дочернего сервиса по IP-адресу из поля User-Name, если такого дочернего сервиса нет - сессия будет привязана к родительскому сервису;
-
7 - проверка IP-адреса из поля User-Name на совпадение с IP-адресом сервиса или поиск дочернего сервиса по IP-адресу, если не совпадает и такого дочернего сервиса нет - ошибка авторизации;
-
8 - проверка IP-адреса из поля User-Name на совпадение с IP-адресом сервиса или поиск дочернего сервиса по IP-адресу, если не совпадает и такого дочернего сервиса нет - сессия будет привязана к родительскому сервису.
Например, radius.servSearchMode=1 - поиск по порту, radius.servSearchMode=2-1 - поиск по VLAN с проверкой MAC-адреса, radius.servSearchMode=2-7 - поиск по VLAN с проверкой IP-адреса.
Возможен последовательный поиск c разными режимами (если по первому режиму сервис не был найден - применяется следующий), для этого режимы нужно указать через запятую:
radius.servSearchMode=7,2
При поиске по логину поиск сервиса происходит по значению атрибута User-Name, по его совпадению с логином сервиса. После логина в атрибуте User-Name может быть указан реалм c разделителем @, например "vasya@local". Если реалм не указан, то предполагается, что пользователь использует реалм default. При этом принудительное указание реалма default (например, "vasya@default") не допускается.
По умолчанию перед поиском сервиса по логину из User-Name удаляется значение домена и не удаляются пробелы в начале и в конце. Также поиск идет с учетом регистра. Изменить поведение можно в конфигурации устройства (см. Пример конфигурации устройства-NAS’а). |
Список допустимых реалмов указывается в параметре устройства/типа сервиса radius.realm через запятую, например:
#radius.realm=default
radius.realm=default, local
Параметр может быть указан как в конфигурации устройства (или типа устройтва), так и в конфигурации типа сервиса - в последнем случае значение будет главнее, чем тот же параметр в конфигурации устройства. По умолчанию допускается только реалм default.
При поиске по интерфейсу или VLAN’у, сервис может быть привязан к дочернему для NAS’а устройству - например, в случае Cisco ISG или Redback CLIPS - сервис привязан к коммутатору, NAS’ом выступает маршрутизатор. В этом случае необходимо в предобработке RADIUS-запроса установить опцию AGENT_REMOTE_ID со значением идентификатора дочернего коммутатора. Если опция будет присутствовать и такое дочернее устройство существует, то поиск сервиса будет идти относительно этого агентского устройства, иначе, по умолчанию, поиск идет относительно устройства-NAS’а.
request.setOption( InetRadiusProcessor.AGENT_REMOTE_ID, "1CBDB9E64878" );
Данную опцию необходимо устанавливать как в preprocessAccessRequest, так и в preprocessAccountingRequest. Значение обычно извлекается из RADIUS-атрибутов запроса, содержащих, например, значение субопций DHCP option 82. Значение можно установить как строкой, так и массивом байт (byte[]). В случае, если опция установлена в предобработке запроса, будет произведен поиск агентского устройства на совпадение с полем Идентификатор.
Также возможна схема с несколькими NAS’ами, работающими параллельно, в этом случае ветку с устройствами коммутаторами нужно завести отдельно (не делать ее дочерней по отношению к одному из устройств-NAS’ов), а в конфигурации устройств-NAS’ов указать параметр device.agentDeviceRootId=<x>, где <x> - ID устройства-папки, в котором находится подветка с коммутаторами:
Для определения интерфейса или VLAN возможны два способа: установка опции AGENT_CIRCUIT_ID или установка напрямую опции INTERFACE_ID/VLAN_ID. В первом случае значение номера интерфейся или VLAN из опции будет извлечено по параметрам конфигурации агентского устройства dhcp.option82.interfaceId.position, dhcp.82.interfaceId.length, dhcp.option82.vlanId.position, dhcp.option82.vlanId.length. Во втором - значение должно быть равно интерфейсу или порту.
Пример (установка опций из атрибутов-значений субоций DHCP option 82, данный код есть в обработчиках, которые входят в дистрибутив модуля):
RadiusAttribute<?> agentRemoteId = request.getAttribute( 2352, 96 );
if( agentRemoteId != null )
{
ByteBuffer data = agentRemoteId.getData();
data.position( 2 );
data = data.slice();
request.setOption( InetRadiusProcessor.AGENT_REMOTE_ID, data );
}
RadiusAttribute<?> agentCircuitId = request.getAttribute( 2352, 97 );
if( agentCircuitId != null )
{
ByteBuffer data = agentCircuitId.getData();
data.position( 2 );
data = data.slice();
// значение интерфейса или VLAN'а будет извлечено из этого параметра
request.setOption( InetRadiusProcessor.AGENT_CIRCUIT_ID, data );
}
Пример (vlan per user - поиск по vlan):
/*
// Если агентское устройство всегда известно - раскомментарить, режим поиска 2;
// иначе - режим поиска 4 (по vlan с учетом всех дочерних устройств)
RadiusAttribute<?> agentRemoteId = request.getAttribute( 2352, 96 );
if( agentRemoteId != null )
{
ByteBuffer data = agentRemoteId.getData();
data.position( 2 );
data = data.slice();
request.setOption( InetRadiusProcessor.AGENT_REMOTE_ID, data );
}*/
Pattern vlanPattern = Pattern.compile( "(.+) vlan-id (\\d+)" );
String nasPortId = request.getStringAttribute( -1, 87, null );
if( nasPortId != null )
{
Matcher m = vlanPattern.matcher( nasPortId );
if( m.find() )
{
String vlanId = m.group( 2 );
request.setOption( InetRadiusProcessor.VLAN_ID, vlanId );
}
}
Таким образом для поиск сервиса возможен:
-
по атрибуту User-Name (по умолчанию);
-
по опциям AGENT_REMOTE_ID (идентификатор агентского устройства - устройства, на котором, собственно, интерфейс) и INTERFACE_ID (или AGENT_CIRCUIT_ID, содержащий номер интерфейса);
-
по опциям AGENT_REMOTE_ID (не обязательна, если в пределах NAS’а VLAN уникальны) и VLAN_ID (или AGENT_CIRCUIT_ID, содержащий номер VLAN'а).
При аутентификации во всех случаях происходит проверка пароля, поэтому в некоторых случаях пароль нужно устанавливать на NAS’е, в коде preprocessAccessRequest или, при необходимости, отключить проверку пароля для NAS’а:
# Включение (1, по умолчанию) или отключение (0) проверки пароля для NAS'а
#radius.password.verification=1
RADIUS-атрибуты
Когда сервис определён, определяется набор атрибутов сессии, последовательным добавлением:
-
атрибутов, определённых для реалма;
-
атрибутов, определенных для сервиса(логина);
-
атрибутов, определённых для опций.
Атрибуты задаются перечислением <имя атрибута>=<значение> через точку с запятой, если в значении атрибута должна присутствовать точка с запятой (т.е. это не разделение двух разных атрибутов), то её нужно указать два раза: ";;".
Атрибуты реалма
Атрибуты реалма определяются в конфигурации устройства-NASа следующим образом:
radius.realm.<realm>.attributes=<attributes>
Где:
-
<realm> - реалм;
-
<attributes> - атрибуты.
Пример:
radius.realm.default.attributes=Acct-Interim-Interval=300;Session-Timeout=604800
Есть возможность добавлять динамические атрибуты, с помощью макросов:
radius.realm.<realm>.attributes.macros=<attributes>
radius.realm.default.attributes.macros=Interface-Name=$ipParam(ifaceName)
Запись атрибутов производится в таком же виде, как и в параметрах radius.realm.<realm>.attributes, однако здесь поддерживаются макросы вида $имя или $имя(параметр1,параметр2), например:
radius.realm.default.attributes.macros=Interface-Name=$ipParam(ifaceName)
Поддерживаются следующие макросы:
-
$ipGate - значение поля "Роутер" IP-ресурса, из которого выдан IP-адрес;
-
$ipDns - значение поля "DNS" IP-ресурса, из которого выдан IP-адрес;
-
$ipSubnetMask - значение поля "Маска подсети" IP-ресурса, из которого выдан IP-адрес;
-
$ipParam(name) - значение параметра конфигурации IP-ресурса, из которого выдан IP-адрес, аргумент макроса - имя параметра, например $ipParam(ifaceName) вернет значение параметра ifaceName= конфигурации IP-ресурса;
-
$param($device,name,default) - значение параметра конфигурации устройства-NAS’а или агентского устройства (коммутатора), указывается так: $param($device,myParam,myDefault) или $param($agentDevice,myParam,myDefault);
-
$requestAttribute(vendor,type) или $requestAttribute(name) - значение атрибута из запроса, например $requestAttribute(User-Name).
Атрибуты опций
Полный набор опций сессии определяется объединением опций, указанных в самом сервисе и опций из тарифного плана. Соответствие кодов опций атрибутам определяется в конфигурации устройства-NASа следующим образом:
radius.inetOption.<option_id>.attributes=<attributes>
Где:
-
<option_id> - числовой код опции;
-
<attributes> - RADIUS атрибуты.
Пример конфигурации, где определены атрибуты для реалмов и опций:
radius.realm.default.attributes=Service-Name:1=RSE-SVC-EXT;Service-Options:1=1
radius.inetOption.1.attributes=Service-Parameter:1=Rate=100000 Burst=12500000
radius.inetOption.2.attributes=Service-Parameter:1=Rate=100000 Burst=12500000
Для удобства указания однотипных наборов атрибутов, например, для указания атрибутов скорости можно использовать шаблоны. Для этого опции скорости должны находиться в одной родительской опции (которую можно назвать, например, "Скорость"). В конфигурации устройства нужно будет указать:
radius.inetOption.<parent_option_id>.template=Service-Parameter:1=Rate=$rate Burst=$burst
где <parent_option_id> - ID родительской опции ("Скорость").
В конфигурации опций-скоростей необходимо указать необходимые значения rate= и burst=. Таким образом отпадает необходимость указания практически одинакового набора атрибутов для каждой опции-скорости в конфигурации устройства, достаточно лишь прописать один раз шаблон. Также значения параметров можно прописать в конфигурации родительской опции, для того чтобы использовать как значения по умолчанию (если значение не переопределено в дочерней опции) или просто как самостоятельную переменную шаблона.
Атрибуты сервиса/логина
Атрибуты специфичные для типа сервиса можно прописать в конфигурации типа сервиса:
serv.radius.realm.default.attributes=
При необходимости выдавать специфичные атрибуты (значения) индивидуально для сервиса, в конфигурации типа сервиса укажите
param.myParam.title=Мой параметр
Теперь на вкладке "Дополнительно" в редакторе сервиса на договоре можно будет добавить данный параметр, указав его значение. Теперь этот параметр можно использовать при выдаче RADIUS-атрибутов, прописав в конфигурации типа сервиса, в том же параметре serv.radius.<realm>.default.attributes атрибут с помощью макроса:
serv.radius.realm.default.attributes=My-Attribute=$myParam
Выдача IP-адреса
Выдача IP-адреса производится через атрибут Framed-IP-Address из диапазона (адреса), указанного в самом сервисе на договоре (т.е. выдача статического IP-адреса), либо, если адрес в сервисе не указан или занят другой сессий этого же сервиса - из пула, определённого в конфигурации устройства параметром radius.realm.<realm>.ipCategories=<cat_codes>, где:
-
<realm> - реалм;
-
<cat_codes> - id коды категорий ресурсов IP-адресов через запятую.
Например, выдача динамических адресов из категории IP-ресурсов с кодом 4:
radius.realm.default.ipCategories=4
Вы также можете выдавать адреса из разных пулов в зависимости от активной опции Inet, указав опцию в тарифе или статически в сервисе на договоре. Таким образом, можно в зависимости от различных условий выдавать адреса из разных подсетей (для ситуации, когда баланс меньше лимита смотрите ниже Reject-To-Accept). Благодаря гибкости тарифа можно выдавать адреса из разных пулов в зависимости от баланса, активных тарифных опций, групп договоров, времени, периода и других условий.
Для этого в конфигурации устройства-NAS’а или корневого устройства укажите именованный пул адресов. Пул состоит из имени и перечисления id категорий ресурсов IP-адресов через запятую: resource.ip.pool.<name>.ipCategories=<cat_codes>
resource.ip.pool.whitePool.ipCategories=5
Далее создайте опции Inet, например, создав опцию-ветку "Пулы IP-адресов" и внутри нее опцию "Белый пул IP-адресов". В конфигурации устройства или типа устройства-NAS’а или же корневого устройства укажите привязку данной опции к пулу IP-адресов, например, если у созданной опции "Белый пул IP-адресов" ID=72:
radius.inetOption.72.ipPool=whitePool
Теперь, если в сервисе договора будет активна (с помощью тарифа или указана статически в сервисе) опция "Белый пул IP-адресов", то адрес будет выдаваться из пула whitePool, который состоит из IP-адресов категорий, указанных в параметре resource.ip.pool.whitePool=, т.е. в данном примере - из категории IP-ресурсов с ID=5. Если же опция будет не активна - то адрес будет выдан из параметра radius.realm.<realm>.ipCategories=<cat_codes>, если он указан.
Также вместо указания списка IP-категорий для реалма можно воспользоваться указанием имени пула, т.е. вместо radius.realm.default.ipCategories=4 указать, например:
resource.ip.pool.greyPool.ipCategories=4
radius.realm.default.ipPool=greyPool
При использовании схем IPoE возможна ситуация, когда с Cisco/SE приходит подряд несколько Access-Request’ов. Например, абонентский DHCP-клиент шлет сразу несколько DHCP-Discover-пакетов, или в Cisco инициация сессии срабатывает не только на DHCP-Discover, но и на DHCP-Request. По умолчанию для динамической выдачи IP-адресов InetAccess на каждый Access-Request выдает Access-Accept с новым IP-адресом, что может быть проблемой для связки DHCP-клиент+Cisco/SE. В этом случае можно использовать параметр radius.address.authReserveTimeout. При выдаче адреса он будет запоминаться по ключу сервис+устройство-NAS+(агентское_устройство)User-Name(MAC-address)(CallingStationId)(identifier) и в течении указанного времени (в миллисекундах) на очередной Access-Request с таким же ключом будет предлагать тот же адрес.
# Кэширование выданного абоненту IP-адреса по ключу (для IPoE), по умолчанию - 0 (выкл)
radius.address.authReserveTimeout=3000
Выдача статической подсети
Для того, чтобы в Access-Accept биллинг выдавал подсеть в виде атрибутов Framed-IP-Address и Framed-IP-Netmask, то в типе сервиса нужно указать "Тип адреса": "статическая сеть", а также добавить в конфигурации типа сервиса:
# Выдаем в Access-Accept всю подсеть сервиса в виде Framed-IP-Address=<net> и Framed-IP-Netmask=<mask>
serv.radius.staticSubnet=1
Не выдавать адрес из диапазона сервиса
Возможен случай, когда в сервисе или дочернем сервисе нужно указать IP-адрес, диапазон или подсеть, которые будут нужны только для управления. Т.е. задача в том, чтобы из данного сервиса IP-адрес не выдавать. Например, в родительском сервисе мы указываем подсеть, а в дочерних сервисах - разрешенные абоненту IP-адреса из этой подсети (т.е. абонент должен получать адрес из дочерних сервисов, а не из родительского). Для того, чтобы адрес из сервиса не выдавался, в конфигурации типа сервиса нужно указать:
# Не выдаем IP-адреса из диапазона этого сервиса
serv.radius.skipStaticAddress=1
Не добавлять Framed-IP-Address в Access-Accept
В некоторых схемах, например, IP Subscriber, не требуется выдача IP-адреса в Access-Accept, т.к. IP-адрес у абонента уже есть, и адрес в сервисе указан только для того, чтобы найти абонента по нему при запросе Access-Request. В этом случае в конфигурации типа сервиса нужно указать:
# Не добавляем Framed-IP-Address в Access-Accept
serv.radius.noAddress=1
Выдача Framed-Route
Для того, чтобы выдавать в Access-Accept абоненту атрибут Framed-Route нужно создать тип сервиса, который будет дочерним, в поле "Тип адреса" выбрать значение "статическая сеть", указать в конфигурации типа сервиса:
# Данный сервис используется для указания Framed-Route
serv.radius.framedRoute=1
Reject-To-Accept
В случае ошибки авторизации высылается пакет AUTHENTICATION_REJECT с отображением ошибки и её кода в мониторе модуля. Допустимые коды ошибок данного процессора.
Вместо AUTHENTICATION_REJECT может быть выслан AUTHENTICATION_ACCEPT-пакет с дополнительными атрибутами. Перечень кодов ошибок, для которых производится подмена Reject-To-Accept определяется переменной конфигурации NAS’а radius.disable.accessCodes=<codes>, где <codes> - перечень кодов ошибок авторизации через запятую. Например:
radius.disable.accessCodes=1,2,3,4,10,11,12
Соответственно, для Reject-To-Accept могут быть собственные диапазоны IP-адресов, например:
radius.disable.ipCategories=3
Если же нужно выдавать статический IP-адрес такой же, как при обычном доступе (также, как когда не возникает ошибок авторизации), нужно указать режим:
# Режим выдачи статического адреса при ошибке авторизации:
# 0 (по умолчанию) - выдавать динамический адрес из категорий radius.disable.ipCategories,
# 1 - выдавать статический адрес как при удачной авторизации
radius.disable.mode=1
Если нужно выдавать динамический IP-адрес такой же, как при обычном доступе - то нужно прописать в radius.disable.ipCategories те же самые пулы.
При ошибке авторизации, атрибуты выдаются из параметра radius.disable.attributes:
# Атрибуты, выдаваемые при ошибке авторизации
radius.disable.attributes=
# атрибуты, выдаваемые при ошибке авторизации с кодом 1 (сервис/логин не найден), 2 или 3
#radius.disable.1,2,3.attributes=
# атрибуты с использованием макросов
#radius.disable.attribute.macros=
Атрибуты из опций Inet в данном режиме не выдаются.
Для поддержки Reject-To-Accept при ошибке с кодом 1 (Логин не найден), т.е. для предоставления гостевого доступа, необходимо создать договор с балансом меньше лимита и сервисом модуля Inet со статусом закрыт, а id сервиса прописать в конфигурации устройства:
radius.disable.servId=<inetServId>
Таким образом, сессии с ненайденным сервисом будут привязываться к указанному сервису.
При превышении числа сессий над ограничением, установленным для сервиса, генерируется ошибка авторизации. Данная ошибка также может быть обработана механизмом Reject-To-Accept с выдачей адреса из пула фиктивных адресов.
MAC-адрес и идентификатор
При RADIUS Access-Request можно также использовать MAC-адрес, чтобы авторизовывать запросы только с определенным MAC-адресом. MAC-адрес из Access-Request пакета устанавливается в Обработчике процессора протокола, в методе preprocessAccessRequest: request.setOption( InetRadiusProcessor.MAC_ADDRESS, macAddress ). Стандартные обработчики процессора протокола, поставляемые с модулем уже реализуют этот функционал, нужно только прописать в конфигурации устройства или типа устройства:
# Вендор атрибута, где хранится MAC-адрес
radius.macAddress.vendor=-1
# Код атрибута, где хранится MAC-адрес
radius.macAddress.type=31
# Префикс атрибута (если есть), где хранится MAC-адрес. Например, для cisco avpair
#radius.macAddress.prefix=client-mac-address=
Или:
# Вендор атрибута, где хранится MAC-адрес
radius.macAddress.vendor=9
# Код атрибута, где хранится MAC-адрес
radius.macAddress.type=1
# Префикс атрибута (если есть), где хранится MAC-адрес. Например, для cisco avpair
radius.macAddress.prefix=client-mac-address=
Таким образом, при извлечении MAC-адреса из RADIUS-пакета, он будет сравнен с MAC-адресом из аутентифицированного сервиса при условии, что в этом сервисе заведен MAC-адрес.
Для автоматического привязывания MAC-адреса к сервису в конфигурации модуля/типа сервиса/устройства/типа устройства можно прописать:
# Нужно ли автоматически проставлять в сервис MAC-адрес, если его еще нет.
# Можно указать в конфигурации модуля, конфигурации устройства, конфигурации типа сервиса.
# 0 - не привязывать, 1 - привязывать, если поле сервиса пустое, 2 - перетирать новым значением, 3 - добавлять
# (в последних двух случаях отказа в авторизации по MAC-адресу не будет)
serv.macAddress.auto=1
Таким образом при первой удачной авторизации MAC-адрес будет привязан к сервису и с другим MAC-адресом клиент уже не сможет авторизоваться.
Аналогично MAC-адресу можно использовать поле Идентификатор сервиса. Например, в качестве идентификатора использовать значение атрибута Calling-Station-Id, устанавливая в Обработчике процессора протокола, в методе preprocessAccessRequest: request.setOption( InetRadiusProcessor.IDENTIFIER, callingStationId ).
Для автоматического привязывания идентификатора к сервису в конфигурации модуля/типа сервиса/устройства/типа устройства можно прописать:
# Нужно ли автоматически проставлять в сервис идентификатор, если его еще нет.
# Можно указать в конфигурации модуля, конфигурации устройства, конфигурации типа сервиса.
# 0 - не привязывать, 1 - привязывать, если поле сервиса пустое, 2 - перетирать новым значением, 3 - добавлять
# (в последних двух случаях отказа в авторизации по идентификатору не будет)
serv.identifier.auto=1
Calling-Station-Id
Атрибут Calling-Station-Id используется для подстановки в поле сессии "С номера". При отсутствии данного атрибута можно настроить, чтобы обработчик процессора протокола (CoAProtocolHandler, SmartEdgeProtocolHandler, ISGProtocolHandler и другие) при предобработке RADIUS-запроса устанавливал значение в данный атрибут из другого, например, из атрибутра Mac-Address Redback (ID вендора 2352, ID типа атрибута 145):
# Копирование значения в атрибут Calling-Station-Id.
# ID вендора RADIUS-атрибута
radius.callingStationId.vendor=2352
# Тип RADIUS-атрибута
radius.callingStationId.type=145
# Префикс RADIUS-атрибута, если присутствует (будет удален из строки)
#radius.callingStationId.prefix=
Привязка сервиса к NAS’у или ветке NAS’ов
Для привязки сервиса к устройству - т.е. для того, чтобы клиент мог авторизоваться только на устройстве (NAS’е), привязанному к сервису, или являющимся дочерним по отношению к нему (устройству), необходимо указать в конфигурации устройства/типа устройства/типа сервиса:
# Привязка авторизации сервиса к устройству, указанному в сервисе договора
# 0 - клиент может авторизоваться на любом устройстве (NAS'е), 1 - клиент может авторизоваться только на прописанном в сервисе устройстве,
# 2 - клиент может авторизоваться только на прописанном в сервисе устройстве или являющимся дочерним по отношению к нему
serv.device.link=2
Действие при получении Access-Request при наличии активной сессии
При подключении абонента может быть ситуация, когда в биллинге сессия еще активна, а клиент на самом деле уже отключился и пытается подключиться заново. Это может произойти при потере связи с NAS’ом (т.е. STOP-пакет не пришел, но connection.close.timeout еще не произошел), или, например, при использовании IPoE с Cisco/Redback (когда абонент подключил другое устройство, а Cisco/Redback по таймауту DHCP-lease еще не поняли, что старое соединение можно закрывать). Для обработки такой ситуации можно использовать параметр конфигурации radius.connection.checkDuplicate. Он работает в связке с Calling-Station-Id - если происходит попытка авторизации, а количество активных соединений превышено и среди активных соединений есть соединение с таким же Calling-Station-Id, то при указании radius.connection.checkDuplicate:
-
Происходит попытка сброса старого соединения (например, отправка PoD-пакета), абонента на этой авторизации не пускаем;
-
Происходит попытка сброса старого соединения, его завершение в биллинге, абонента на этой авторизации не пускаем, должно пустить при следующей попытке, т.к. старой сессии уже не будет;
-
Происходит завершение старого соединения в биллинге, абонента на этой авторизации не пускаем, должно пустить при следующей попытке, т.к. старой сессии уже не будет;
-
Происходит попытка сброса старого соединения, затем через 5 секунд завершение в биллинге, абонента на этой авторизации не пускаем;
-
Попытка сброса старого соединения в биллинге, завершение и пускаем немедленно (т.е. игнорируется ошибка );
-
Завершение старого соединения в биллинге, пускаем абонента немедленно;
-
Попытка в течении 5 секунд сбросить соединение, затем закрытие сессии в биллинге с ожиданием полного выполнения закрытия (т.е. IP-адрес станет свободным), пускаем абонента
-
Попытка сброса и сразу закрытие в биллинге с ожиданием полного выполнения закрытия (т.е. IP-адрес станет свободным), пускаем абонента;
-
Закрытие старого соединения в биллинге с ожиданием полного выполнения закрытия (т.е. IP-адрес станет свободным), пускаем абонента.
Для более быстрого подключения абонента при использовании и динамическим адресом рекомендуем использовать 4, 5, 6. Для статических адресов (чтобы абонент мог получить свой адрес) - 8,9.
Для обработки ситуации, когда количество активных соединений превышено, но соединения с таким Calling-Station-Id не найдено, и нужно отключить просто самое старое соединение, нужно указать цифру во втором разряде, например: 88.
Для сброса соединения с таким же Calling-Station-Id, даже если количество соединений не превышено, нужно указать цифру в третьем разряде, например, 808, 909, 888 или 818.
Этот параметр можно указать для типа сервиса, в конфигурации типа сервиса: serv.radius.connection.checkDuplicate.
В некоторых IPoE-схемах для обработки этого событие требуется использовать не Calling-Station-Id, а User-Name. Для этого нужно указать параметр radius.connection.checkDuplicate.type=1. В этом режиме будет проверяться User-Name из Access-Request с полем username сессии. Этот параметр можно указать для типа сервиса, в конфигурации типа сервиса: serv.radius.connection.checkDuplicate.type.
Т.к. параметр 8 и 9 (закрытие в биллинге с ожиданием полного выполнения закрытия, т.е. IP-адрес станет свободным) ожидает полного завершения соединения в биллинге, а необходимо такое ожидание только для некоторых схем, например, статических адресов, то рекомендуется задавать этот параметр в типе сервиса. Например, в конфигурации NAS’а radius.connection.checkDuplicate=5, в конфигурации типа сервиса для статических адресов radius.connection.checkDuplicate=8. |
Без атрибута Calling-Station-Id в Access-Request-пакете данная функция работать не будет. При невозможности присылать Calling-Station-Id в Access-Request можно настроить подмену в обработчике процессора протокола (в предобработке RADIUS-запросов). |
Блокировка частых Access-Request → Access-Reject
Спам-запросы на авторизацию порождаются, обычно, забытым оборудованием, самостоятельно предпринимающем попытки авторизации на RADIUS. Постоянные обращения при таких запросах могут существенно повышать загрузку. Признаком спам-запроса являются несколько Reject-ответов на одинаковые запросы авторизации в течение определённого интервала времени. В этом случае подобные запросы попадают в спам-кэш на определённое время и по ним автоматически выдаётся Reject-ответ без полных проверок, производимых при авторизации. Для включения антиспам-системы в конфигурации модуля добавьте (требуется перезапуск InetAccess):
antispam.key.attributes=<key_attributes>
antispam.reject.count=<reject_count>
antispam.reject.per.time=<per_time>
antispam.ban.time=<ban_time>
Где:
-
<key_attributes> - RADIUS-атрибуты, идентифицирующие запрос, через запятую;
-
<reject_count> - количество Reject, возвращённых на запрос с одинаковыми идентифицирующими атрибутами;
-
<per_time> - за какое количество секунд выдано указанное в <reject_count> количество Reject-ответов;
-
<ban_time> - время в секундах, на которое данный запрос попадает в спам-базу.
Например, запрос идентифицируется атрибутами User-Name и Calling-Station-Id. При десяти Reject-ответах в течении минуты запрос попадает в спам-базу на полчаса.
antispam.key.attributes=User-Name,Calling-Station-Id
antispam.reject.count=10
antispam.reject.per.time=60
antispam.ban.time=900
Посервисный аккаунтинг
Посервисный аккаунтинг
Для поддержки посервисного аккаунтинга (например, при использовании Cisco ISG или Redback CLIPS) в обработчике процессора протокола необходимо указывать AcctSessionId родительского соединения (аккаунтинга) и имя сервиса (ServiceName), по которому пришел аккаунтинг-пакет: request.setOption( InetRadiusProcessor.PARENT_ACCT_SESSION_ID, parentAcctSessionId ); и request.setOption( InetRadiusProcessor.SERVICE_NAME, serviceName );
Пример для Redback SmartEdge 100:
@Override
public void preprocessAccountingRequest( RadiusPacket request, RadiusPacket response, ConnectionSet connectionSet )
throws Exception
{
int acctStatusType = request.getIntAttribute( -1, RadiusDictionary.Acct_Status_Type, -1 );
switch( acctStatusType )
{
// если сервисный аккаунтинг
case 101:
case 102:
case 103:
{
// получаем id родительского соединения
final String parentAcctSessionId = request.getStringAttribute( -1, parentAcctSessionIdType, null );
// получаем имя сервиса, по которому идет аккаунтинг
final String serviceName = request.getStringAttribute( radiusVendor, serviceNameType, null );
// подменяем Acct-Status-Type, чтобы биллинг понял типы пакетов
request.setIntAttribute( -1, RadiusDictionary.Acct_Status_Type, acctStatusType - 100 );
// устанавливаем id родительской сессии
request.setOption( InetRadiusProcessor.PARENT_ACCT_SESSION_ID, parentAcctSessionId );
// устанавливаем имя сервиса текущего аккаунтинга
request.setOption( InetRadiusProcessor.SERVICE_NAME, serviceName );
}
break;
default:
{
}
break;
}
}
Тогда Accounting считает данное соединение как дочернее родительскому, а в поле username соединения (в базе) устанавливается ServiceName.
При обработке трафиков используется ServiceName - он может выступать в качестве фильтра правила привязки трафиков: если указано ServiceName, то данное правило будет отрабатывать только для сервисной сессии с таким ServiceName, и наоборот, если поле ServiceName в правиле пусто, то данное правило не будет отрабатывать ни для какой сервисной сессии.
В поле ServiceName можно указать несколько сервисов через запятую (RSE-SVC-EXT, RSE-SVC-EXT1024) или же указать REGEXP внутри двух слешей (/^RSE-SVC-EXT.*$/).
Например, если у вас внешний трафик идет посервисным аккаунтингом с ServiceName=RSE-SVC-EXT, то нужно назначить такую привязку:
Пример конфигурации устройства-NAS’а
# Используемый secret для общения по RADIUS-протоколу (по умолчанию - значение из поля Community/secret параметров устройства)
#radius.secret=<sercret устройства>
# Порт для отправки PoD и CoA-запросов (по умолчанию - порт, заданный в параметрах устройства Хост/порт)
#radius.port=<порт устройства>
# При выдаче Access-Accept добавлять запись в базу.
# Hеобходимо, если используется Reject-To-Accept и по Start-пакету нельзя определить в каком состоянии соединение
connection.start.fromAccept=1
# Бывают ситуации, когда Start-пакет не дошел до Accounting-сервера. В этом случае, при
# 1 (значение по умолчанию) - сессия создастся от текущего момента,
# 2 - Accounting проверит, что время сессии из Update/Stop пакета не больше, чем значение connection.close.timeout и создаст сессию от ее начала, иначе,
# если время сессии больше чем connection.close.timeout, сессия создастся от текущего момента,
# 0 - сессия без Start-пакета создана не будет.
#connection.start.fromUpdate=1
# При создании сессии по Update-пакету нужно ли игнорировать отсутствие IP-адреса сессии (Framed-Ip-Address). По умолчанию сессия
# по Update-пакету без адреса не создается (0).
#connection.start.fromUpdate.ignoreFramedIpLack=0
# Таймаут перевода соединения в статус suspended при остутствии радиус пакетов
connection.suspend.timeout=900
# Таймаут закрытия соединения при остутствии радиус пакетов (не складывается с connection.suspend.timeout)
connection.close.timeout=900
# При закрытии соединения по таймауту, 0 (по умолчанию) - просто закрыть,
# 1 - попытаться сбросить также на NAS'е (вызвать connectionClose у обработчика активации сервисов)
#connection.close.timeout.forceClose=1
# Атрибуты, выдаваемые при авторизации по реалму default (default - реалм по умолчанию)
radius.realm.default.attributes=
# Коды ошибок, при которых отвечать Access-Accept в состоянии disable (rejectToAccept)
radius.disable.accessCodes=
# Какие адреса выдавать при ответе Access-Accept в состоянии disable:
# 0 (по умолчанию) - из radius.disable.ipCategories, 1 - так же, как если бы не было ошибки (в том числе привязанные к сервису в договоре)
#radius.disable.mode=0
# Атрибуты, выдаваемые при ответе Access-Accept в состоянии disable
radius.disable.attributes=
# Id фиктивного сервиса, к которому будут привязываться сессии, по которым нормальный сервис не был найден (код ошибки: 1, логин не найден).
# Необходим, если в radius.disable.accessCodes присутствует код 1
#radius.disable.servId=
# Атрибуты, при наличии которых соединение должно считаться в состоянии DISABLE (т.е. с ограниченным доступом)
#radius.disable.pattern.attributes=
# Вендор атрибута, где хранится MAC-адрес
#radius.macAddress.vendor=9
# Код атрибута, где хранится MAC-адрес
#radius.macAddress.type=1
# Префикс атрибута (если есть), где хранится MAC-адрес. Например, для cisco avpair
#radius.macAddress.prefix=client-mac-address=
# Режим поиска сервиса: 0 (по умолчанию) - по логину, 1 - по интерфейсу на устройстве (в предобработке должны быть
# проставлены опции AGENT_REMOTE_ID и AGENT_CIRCUIT_ID или INTERFACE_ID), 2 - по VLAN на устройстве (в предобработке
# должны быть проставлены опции AGENT_REMOTE_ID и AGENT_CIRCUIT_ID или VLAN_ID), 4 - по VLAN на устройстве или
# дочернем устройстве (в предобработке должны быть проставлены опции AGENT_REMOTE_ID и AGENT_CIRCUIT_ID или VLAN_ID),
# 5 - по MAC-адресу на устройстве (в предобработке должна быть проставлена опция MAC_ADDRESS), 6 - по MAC-адресу на
# устройстве или дочернем устройстве (в предобработке должна быть проставлена опция MAC_ADDRESS).
#radius.servSearchMode=0
# Нужно ли проверять пароль: 0 - нет, 1 (по умолчанию) - да.
#radius.password.verification=1
# Проверка на повторную аутентификацию при Access-Request. Бывает нужна в случаях, когда NAS сбрасывает (теряет) сессию, но
# Stop-пакет не присылает и клиент пытается подключиться повторно, но у него стоит ограничение на максимум одну сессию. При совпадении
# callingStationId с одной из активных сессий и установленным параметром: 1 - осуществляется попытка закрытия старой сессии (connectionClose),
# 2 - попытка закрытия сессии (connectionClose) и завершение ее в базе, не дожидаясь стоп пакета, 3 - завершение в базе.
#radius.connection.checkDuplicate=0
# Нужно ли убирать домен перед поиском сервиса по логину из поля User-Name. По умолчанию - да (1).
# Следует отключить, если при посылке CoA и PoD пакетов NAS'у необходим атрибут User-Name.
radius.username.removeDomain=1
# Нужно ли убирать пробелы из поля User-Name перед поиском логина. По умолчанию - нет (0).
# Следует отключить, если при посылке CoA и PoD пакетов NAS'у необходим атрибут User-Name.
#radius.username.removeWhitespace=0
# Должен ли поиск по логину идти без учета регистра. По умолчанию - нет (0).
#radius.username.ignoreCase=0
# Включение (1, по умолчанию) или отключение (0) проверки пароля для NAS'а
#radius.password.verification=1
# Шаблон вывода ошибки в мониторе с использованием атрибутов из RADIUS-пакета
#radius.accessError.infoPattern=LOGIN:$User-Name
# Привязка кодов опций модуля к атрибутам
# данные атрибуты будут выдаваться в AccessAccept при удачной авторизации и при наличии активных опций в тарифе или сервисе
radius.inetOption.1.attributes=
radius.inetOption.2.attributes=
radius.inetOption.3.attributes=
# Параметры активации сервисов
# длина паузы, если возникла ошибка
#sa.error.pause=60
# количество заданий за раз
#sa.batch.size=20
# время (сек) ожидания завершения всех заданий (при асинхронной работе)
#sa.batch.wait=5
# пауза (сек) после обработки заданий
#sa.batch.pause=0
# время (сек) ожидания новой задачи перед вызовом disconnect.
#sa.batch.waitNext=5
# Параметры обработчика активации сервисов
# откуда при отправке CoA брать атрибуты опций (по умолчанию - те же атрибуты, что выдаются при удачной авторизации)
#sa.radius.option.attributesPrefix=nas.radius.inetOption.
#sa.radius.connection.attributes=NAS-Port, Acct-Session-Id, User-Name, Framed-IP-Address, NAS-IP-Address, NAS-Identifier
# атрибуты CoA-запроса для прекращения доступа (используется при sa.radius.connection.withoutBreak=1)
#sa.radius.disable.attributes={@radius.disable.attributes}
# фиксированные атрибуты, добавляемые в запрос перед отправкой CoA
#sa.radius.coa.attributes=
# добавлять ли при отправке CoA-атрибуты реалма (для default - из radius.realm.default.attributes)
#sa.radius.realm.addAttributes=0
# фиксированные атрибуты, добавляемые в запрос перед отправкой PoD
#sa.radius.pod.attributes=
Пересылка RADIUS-запросов
Иногда есть необходимость пересылать RADIUS Access/Accounting пакеты на сторонний сервер - например, на устройство СОРМ, для корректной его работы. Для дублирования полученных RADIUS-запросов на сторонний сервер в конфигурации устройства или типа устройства-NAS’а следует указать (также можно указать в конфигурации корневого устройства):
# хост, на который будут ретранслироваться пакеты-запросы, единственный обязательный параметр для включения функционала
radius.forward.host=<host>
# хост, на который будут ретранслироваться пакеты-ответы
radius.answer.forward.host=<host>
# порт, на который будут ретранслироваться пакеты-запросы, по умолчанию равен 1813
radius.forward.port=<port>
# порт, на который будут ретранслироваться пакеты-ответы
radius.answer.forward.port=<port>
# RADIUS-секрет, которым будет подписан пакет, по умолчанию берётся секрет NASа
radius.forward.secret=<secret>
# префикс к значению атрибута User-Name из accounting-пакета, если не указан - префикс не добавляется
radius.forward.user.name.prefix=<prefix>
# суффикс к значению атрибута User-Name из accounting-пакета, если не указан - суффикс не добавляется
radius.forward.user.name.suffix=<suffix>
# шаблон значения атрибута User-Name. Возможные значения:
# 1) $contractTitle - User-Name будет заменен на номер договора
# 2) $contractId - User-Name будет заменен на id договора из таблицы contract
# Для корректной работы данного механизма должен быть указан параметр radius.forward.after.process=1, т.к. номер договора будет известен только после обработки
#radius.forward.user.name.pattern=$contractTitle
# Размер очереди radius-пакетов для пересылки. По умолчанию равно 500. В случае переполнения данной очереди пакет будет проигнорирован.
#radius.forward.maxQueueSize=500
Данные параметры (если необходимы) нужно указывать в конфигурации модуля:
# если указано, отправка происходит после предобработки (по умолчанию - перед предобработкой)
#radius.forward.after.preprocess=0
# если указано, отправка происходит после обработки
#radius.forward.after.process=0
# если указано, то будут отправляться access-запросы после их обработки приложением.
#radius.forward.access.request=0
Где:
-
<host> - хост, на который будут ретранслироваться пакеты, единственный обязательный параметр для включения функционала;
-
<port> - порт, на который будут ретранслироваться пакеты, по умолчанию равен 1813;
-
<secret> - RADIUS-секрет, которым будет подписан пакет, по умолчанию берётся секрет NASа;
-
<prefix> - префикс к значению атрибута User-Name из аккаунтинг пакета, если не указан - префикс не добавляется;
-
<suffix> - суффикс к значению атрибута User-Name из аккаунтинг пакет, если не указан - суффикс не добавляется.
Суффикс и префикс могут быть полезны при необходимости ретранслирования пакетов с нескольких InetAccounting с пересекающимися логинами на единый сервер.
Например:
radius.forward.host=avantis.ru
radius.forward.port=4444
radius.forward.secret=4343
radius.forward.user.name.prefix=test_
radius.forward.user.name.suffix=_forv
Пример с подстановкой номера договора в атрибут User-Name, в конфигурации модуля:
radius.forward.after.process=1
В конфигурации типа устройства-NAS’а:
radius.forward.host=avantis.ru
radius.forward.port=4444
radius.forward.secret=4343
radius.forward.user.name.prefix=test_
radius.forward.user.name.suffix=_forv
radius.forward.user.name.pattern=$contractTitle