Freeradius Xlat: различия между версиями
Sirmax (обсуждение | вклад) (Новая: =FreeRadius Xlat= FreeRadius предоставляет интересные возможности для опереривания с данными. В моем случае мне н...) |
Sirmax (обсуждение | вклад) |
||
(не показано 13 промежуточных версий этого же участника) | |||
Строка 1: | Строка 1: | ||
+ | [[Категория:Linux]] |
||
+ | [[Категория:FreeRadius]] |
||
=FreeRadius Xlat= |
=FreeRadius Xlat= |
||
FreeRadius предоставляет интересные возможности для опереривания с данными. |
FreeRadius предоставляет интересные возможности для опереривания с данными. |
||
В моем случае мне не хотелось для каждого абонента делать дублирование данных из биллинга ( в моем случае таблица mtraf) в radcheck и radreply. |
В моем случае мне не хотелось для каждого абонента делать дублирование данных из биллинга ( в моем случае таблица mtraf) в radcheck и radreply. |
||
+ | Проверка Auth-Type - на основании данных из биллинга. |
||
− | |||
<PRE> |
<PRE> |
||
select * from radcheck; |
select * from radcheck; |
||
− | +----+----------+------------------+----+------------------------------------------------------------+ |
+ | +----+----------+------------------+----+---------------------------------------------------------------------------------------------------------------+ |
− | | id | username | attribute | op | value | |
+ | | id | username | attribute | op | value | |
− | +----+----------+------------------+----+------------------------------------------------------------+ |
+ | +----+----------+------------------+----+---------------------------------------------------------------------------------------------------------------+ |
− | | 4 | tan | Simultaneous-Use | := | 1 | |
+ | | 4 | tan | Simultaneous-Use | := | 1 | |
− | | 7 | tan | Password | := | `%{sql:SELECT pwd FROM mtraf WHERE domain='%{User-Name}'}` | |
+ | | 7 | tan | Password | := | `%{sql:SELECT pwd FROM mtraf WHERE domain='%{User-Name}'}` | |
+ | | 11 | tan | Auth-Type | := | `%{sql:SELECT IF (0n_a<0 OR (debt=0 AND 0n_a=0),'REJECT','MS-CHAP') from mtraf where domain='%{User-Name}'}` | |
||
− | +----+----------+------------------+----+------------------------------------------------------------+ |
||
+ | +----+----------+------------------+----+---------------------------------------------------------------------------------------------------------------+ |
||
</PRE> |
</PRE> |
||
− | (обратить внимание на обратные кавычки, в которые взят запрос) |
+ | (обратить внимание на обратные кавычки, в которые взят запрос) <BR> |
− | Аналогично, для передачи лимитов по скорости |
+ | Аналогично, для передачи лимитов по скорости (но вместо того что бы указать для каждого %{User-Name} можно указать значения по умолчани. |
<PRE> |
<PRE> |
||
# |
# |
||
Строка 25: | Строка 28: | ||
PPPD-Downstream-Speed-Limit := "%{sql:SELECT ul_out from mtraf where domain='%{User-Name}'} " |
PPPD-Downstream-Speed-Limit := "%{sql:SELECT ul_out from mtraf where domain='%{User-Name}'} " |
||
+ | </PRE> |
||
+ | Обратить внимание, что для cisco передается Cisco-AVPair, для VPN на базе Linux я использую атрибуты PPPD-Upstream-Speed-Limit / PPPD-Downstream-Speed-Limit со значением скорости в килобитах (а не в битах как для Cisco) в секунду. Т.к. радиус не знает этих атрибутов, то их следует вписать в словарь. |
||
+ | |||
+ | |||
+ | Но, как можно заметить, авторизация пользователя все равно требует наличия записей в таблице radcheck - хоть и одинаковых для всех. <BR> |
||
+ | Хотелось бы избежать ненужного дублирования информации, однако мне не удалось заставить работать конструкции вида '%{sql: SELECT ... }' для check атрибутов если проверка идет из файла users. |
||
+ | <BR> конструкция вида |
||
<PRE> |
<PRE> |
||
+ | DEFAULT Framed-Protocol == PPP, Password := "%{sql:SELECT pwd FROM mtraf WHERE domain='%{User-Name}'}" |
||
+ | ... |
||
+ | </PRE> |
||
+ | у меня не заработала. |
||
+ | |||
+ | <BR>Обходным решением является использование групп. Я создал "группу по-умолчанию", для которой один раз в таблице radgroupcheck указал атрибуты для проверки. (группа называется PPTP) |
||
+ | <PRE> |
||
+ | select * from radgroupcheck; |
||
+ | +----+-----------+-----------+----+--------------------------------------------------------------------------------------------------------------+ |
||
+ | | id | groupname | attribute | op | value | |
||
+ | +----+-----------+-----------+----+--------------------------------------------------------------------------------------------------------------+ |
||
+ | | 1 | PPTP | Auth-Type | := | `%{sql:SELECT IF (0n_a<0 OR (debt=0 AND 0n_a=0),'REJECT','MS-CHAP') FROM mtraf WHERE domain='%{User-Name}'}` | |
||
+ | | 2 | PPTP | Password | := | `%{sql:SELECT pwd FROM mtraf WHERE domain='%{User-Name}'}` | |
||
+ | | 3 | PPTP | Pool-Name | := | Test-Pool | |
||
+ | +----+-----------+-----------+----+--------------------------------------------------------------------------------------------------------------+ |
||
+ | </PRE> |
||
+ | и изменил запросы провеки групп, что бы для пользователя который не входит ни в одну группу использовались атрибуты группы "по-умолчанию" |
||
+ | в файле sql.conf: |
||
+ | <PRE> |
||
+ | default_group = "PPTP" |
||
+ | </PRE> |
||
+ | |||
+ | <PRE> |
||
+ | |||
+ | authorize_group_check_query = " SELECT \ |
||
+ | ${groupcheck_table}.id, \ |
||
+ | ${groupcheck_table}.GroupName, \ |
||
+ | ${groupcheck_table}.Attribute, \ |
||
+ | ${groupcheck_table}.Value,radgroupcheck.op \ |
||
+ | FROM \ |
||
+ | ${groupcheck_table} \ |
||
+ | LEFT JOIN ${usergroup_table}\ |
||
+ | USING (GroupName) \ |
||
+ | WHERE \ |
||
+ | ${groupcheck_table}.GroupName = '${default_group}' OR \ |
||
+ | ${usergroup_table}.Username = '%{SQL-User-Name}' \ |
||
+ | ORDER BY \ |
||
+ | ${groupcheck_table}.id" |
||
+ | |||
+ | |||
+ | |||
+ | authorize_group_reply_query = " SELECT \ |
||
+ | ${groupreply_table}.id, \ |
||
+ | ${groupreply_table}.GroupName, \ |
||
+ | ${groupreply_table}.Attribute, \ |
||
+ | ${groupreply_table}.Value,radgroupcheck.op \ |
||
+ | FROM \ |
||
+ | ${groupreply_table} \ |
||
+ | LEFT JOIN ${usergroup_table}\ |
||
+ | USING (GroupName) \ |
||
+ | WHERE \ |
||
+ | ${groupreply_table}.GroupName = '${default_group}' OR \ |
||
+ | ${usergroup_table}.Username = '%{SQL-User-Name}' \ |
||
+ | ORDER BY \ |
||
+ | ${groupreply_table}.id" |
||
+ | |||
+ | |||
+ | group_membership_query = "SELECT IFNULL((SELECT GroupName FROM radusergroup WHERE UserName='%{SQL-User-Name}'),'${default_group}')" |
||
+ | |||
+ | </PRE> |
||
+ | |||
+ | Для того что бы перекрыть адрес из пула, можно использовать атрибут Framed-IP-Address (и, вероятно, любые другие) из таблицы radreply. |
||
+ | После добавления записи: |
||
+ | <PRE> |
||
+ | select * from radreply; |
||
+ | +----+----------+-------------------+----+--------------+ |
||
+ | | id | username | attribute | op | value | |
||
+ | +----+----------+-------------------+----+--------------+ |
||
+ | | 27 | tan | Framed-IP-Address | := | XX.XX.128.11 | |
||
+ | +----+----------+-------------------+----+--------------+ |
||
+ | </PRE> |
||
+ | абонент получает, соответвенно, статический ip. Если в таблице radreply никаких записей для username=tan то будет выда адрес из пула. |
||
+ | |||
+ | ==Еще идеи и их реализация== |
||
+ | <PRE> |
||
+ | |||
+ | |||
+ | |||
+ | DROP PROCEDURE GetPool; |
||
+ | delimiter // |
||
+ | CREATE PROCEDURE GetPool(in SQLUserName varchar(64), OnetBorder INTEGER(11) ) |
||
+ | begin |
||
+ | DECLARE CurrentId INTEGER(11); |
||
+ | DECLARE CurrentId_Onet INTEGER(11); |
||
+ | DECLARE CurrentId_AB INTEGER(11); |
||
+ | |||
+ | SELECT id INTO CurrentId_Onet FROM mtraf WHERE domain=SQLUserName; |
||
+ | SELECT id INTO CurrentId_AB FROM mtraf WHERE domain=SUBSTRING(SQLUserName,3); |
||
+ | |||
+ | SELECT IFNULL(CurrentID_Onet,CurrentId_AB) INTO CurrentId; |
||
+ | |||
+ | if CurrentId < OnetBorder then |
||
+ | SELECT IF (0n_a<0 OR (debt=0 AND 0n_a=0),'NOPAY-Pool','Pool0') FROM mtraf WHERE domain=SUBSTRING(SQLUserName,3); |
||
+ | |||
+ | else |
||
+ | SELECT IF (0n_a<0 OR (debt=0 AND 0n_a=0),'NOPAY-Pool','Pool0') FROM mtraf WHERE domain=SQLUserName; |
||
+ | end if; |
||
+ | end; |
||
+ | // |
||
+ | delimiter ; |
||
+ | </PRE> |
Текущая версия на 10:35, 24 июня 2010
FreeRadius Xlat
FreeRadius предоставляет интересные возможности для опереривания с данными. В моем случае мне не хотелось для каждого абонента делать дублирование данных из биллинга ( в моем случае таблица mtraf) в radcheck и radreply. Проверка Auth-Type - на основании данных из биллинга.
select * from radcheck; +----+----------+------------------+----+---------------------------------------------------------------------------------------------------------------+ | id | username | attribute | op | value | +----+----------+------------------+----+---------------------------------------------------------------------------------------------------------------+ | 4 | tan | Simultaneous-Use | := | 1 | | 7 | tan | Password | := | `%{sql:SELECT pwd FROM mtraf WHERE domain='%{User-Name}'}` | | 11 | tan | Auth-Type | := | `%{sql:SELECT IF (0n_a<0 OR (debt=0 AND 0n_a=0),'REJECT','MS-CHAP') from mtraf where domain='%{User-Name}'}` | +----+----------+------------------+----+---------------------------------------------------------------------------------------------------------------+
(обратить внимание на обратные кавычки, в которые взят запрос)
Аналогично, для передачи лимитов по скорости (но вместо того что бы указать для каждого %{User-Name} можно указать значения по умолчани.
# DEFAULT Framed-Protocol == PPP Framed-Protocol = PPP, Service-Type = Framed-User, Cisco-AVPair += "%{sql:SELECT CONCAT('lcp:interface-config=rate-limit input ',ul_in*1024, ' ', ROUND(ul_in*1000/8), ' ', ROUND(ul_in*1000/8), ' conform-action transmit exceed-action drop') from mtraf where domain='%{User-Name}'}", Cisco-AVPair += "%{sql:SELECT CONCAT('lcp:interface-config=rate-limit output ',ul_in*1024, ' ', ROUND(ul_out*1000/8), ' ', ROUND(ul_out*1000/8), ' conform-action transmit exceed-action drop') from mtraf where domain='%{User-Name}'}", PPPD-Upstream-Speed-Limit := "%{sql:SELECT ul_in from mtraf where domain='%{User-Name}'} ", PPPD-Downstream-Speed-Limit := "%{sql:SELECT ul_out from mtraf where domain='%{User-Name}'} "
Обратить внимание, что для cisco передается Cisco-AVPair, для VPN на базе Linux я использую атрибуты PPPD-Upstream-Speed-Limit / PPPD-Downstream-Speed-Limit со значением скорости в килобитах (а не в битах как для Cisco) в секунду. Т.к. радиус не знает этих атрибутов, то их следует вписать в словарь.
Но, как можно заметить, авторизация пользователя все равно требует наличия записей в таблице radcheck - хоть и одинаковых для всех.
Хотелось бы избежать ненужного дублирования информации, однако мне не удалось заставить работать конструкции вида '%{sql: SELECT ... }' для check атрибутов если проверка идет из файла users.
конструкция вида
DEFAULT Framed-Protocol == PPP, Password := "%{sql:SELECT pwd FROM mtraf WHERE domain='%{User-Name}'}" ...
у меня не заработала.
Обходным решением является использование групп. Я создал "группу по-умолчанию", для которой один раз в таблице radgroupcheck указал атрибуты для проверки. (группа называется PPTP)
select * from radgroupcheck; +----+-----------+-----------+----+--------------------------------------------------------------------------------------------------------------+ | id | groupname | attribute | op | value | +----+-----------+-----------+----+--------------------------------------------------------------------------------------------------------------+ | 1 | PPTP | Auth-Type | := | `%{sql:SELECT IF (0n_a<0 OR (debt=0 AND 0n_a=0),'REJECT','MS-CHAP') FROM mtraf WHERE domain='%{User-Name}'}` | | 2 | PPTP | Password | := | `%{sql:SELECT pwd FROM mtraf WHERE domain='%{User-Name}'}` | | 3 | PPTP | Pool-Name | := | Test-Pool | +----+-----------+-----------+----+--------------------------------------------------------------------------------------------------------------+
и изменил запросы провеки групп, что бы для пользователя который не входит ни в одну группу использовались атрибуты группы "по-умолчанию" в файле sql.conf:
default_group = "PPTP"
authorize_group_check_query = " SELECT \ ${groupcheck_table}.id, \ ${groupcheck_table}.GroupName, \ ${groupcheck_table}.Attribute, \ ${groupcheck_table}.Value,radgroupcheck.op \ FROM \ ${groupcheck_table} \ LEFT JOIN ${usergroup_table}\ USING (GroupName) \ WHERE \ ${groupcheck_table}.GroupName = '${default_group}' OR \ ${usergroup_table}.Username = '%{SQL-User-Name}' \ ORDER BY \ ${groupcheck_table}.id" authorize_group_reply_query = " SELECT \ ${groupreply_table}.id, \ ${groupreply_table}.GroupName, \ ${groupreply_table}.Attribute, \ ${groupreply_table}.Value,radgroupcheck.op \ FROM \ ${groupreply_table} \ LEFT JOIN ${usergroup_table}\ USING (GroupName) \ WHERE \ ${groupreply_table}.GroupName = '${default_group}' OR \ ${usergroup_table}.Username = '%{SQL-User-Name}' \ ORDER BY \ ${groupreply_table}.id" group_membership_query = "SELECT IFNULL((SELECT GroupName FROM radusergroup WHERE UserName='%{SQL-User-Name}'),'${default_group}')"
Для того что бы перекрыть адрес из пула, можно использовать атрибут Framed-IP-Address (и, вероятно, любые другие) из таблицы radreply. После добавления записи:
select * from radreply; +----+----------+-------------------+----+--------------+ | id | username | attribute | op | value | +----+----------+-------------------+----+--------------+ | 27 | tan | Framed-IP-Address | := | XX.XX.128.11 | +----+----------+-------------------+----+--------------+
абонент получает, соответвенно, статический ip. Если в таблице radreply никаких записей для username=tan то будет выда адрес из пула.
Еще идеи и их реализация
DROP PROCEDURE GetPool; delimiter // CREATE PROCEDURE GetPool(in SQLUserName varchar(64), OnetBorder INTEGER(11) ) begin DECLARE CurrentId INTEGER(11); DECLARE CurrentId_Onet INTEGER(11); DECLARE CurrentId_AB INTEGER(11); SELECT id INTO CurrentId_Onet FROM mtraf WHERE domain=SQLUserName; SELECT id INTO CurrentId_AB FROM mtraf WHERE domain=SUBSTRING(SQLUserName,3); SELECT IFNULL(CurrentID_Onet,CurrentId_AB) INTO CurrentId; if CurrentId < OnetBorder then SELECT IF (0n_a<0 OR (debt=0 AND 0n_a=0),'NOPAY-Pool','Pool0') FROM mtraf WHERE domain=SUBSTRING(SQLUserName,3); else SELECT IF (0n_a<0 OR (debt=0 AND 0n_a=0),'NOPAY-Pool','Pool0') FROM mtraf WHERE domain=SQLUserName; end if; end; // delimiter ;