ISG: различия между версиями
Sirmax (обсуждение | вклад) |
Sirmax (обсуждение | вклад) |
||
Строка 318: | Строка 318: | ||
</PRE> |
</PRE> |
||
+ | Запрос в Cisco-Control-Info возвращает квоту клиента в виде QV:<Чисто в Байтах>. Запрос слега замысловатый для обработки ситуации когда radacct пустой. |
||
− | |||
− | |||
Версия 17:29, 9 января 2009
Cisco ISG
Постановка задачи
В небольшом интернет-провайдере отказаться от использования VPN (pptp) для контроля сессий.
Траффик контролировать непосредсвенно на уровне IP. Контроль валидность src-IP осуществляется на уровне сети доступа (DHCP-snooping + ACL),
любой клиент который попадает на роутер с ISG имеет верефицированный src-IP.
Требуется поддреживать следующие тарифы:
- Volume-Based Prepaid (помегабайтный тариф)
- Безлимитные тарифы с ограничением по траффику.
- (опционально) Тарифы с ограничением по скорости и времени. (Lagacy-тариы, который был предназначен для создания альтернативы диал-ап, пока не реализовано.)
- Внимание: Volume-monitor работает только с суммарным траффиком. Возможно, это ограничение можно обойти созданием 2-х сервисов на входящий и исходящий траффик, однако я не вижу в этом смысла для себя на данный момент.
Вот цитата с cisco.com
Restrictions for ISG Prepaid Billing Support
- ISG volume-based prepaid billing is not supported on the Cisco 10000-PRE2. не важно для меня
- ISG prepaid billing support can only be applied to traffic flows that have been defined by an ISG traffic class.
- Quotas are measured in seconds for time and in bytes for volume. There is no way to change the unit of measure. не важно для меня, непонятно кому может быть нужно что то другое
- The volume quota is for combined upstream and downstream traffic.
Общяя схема работы такова: Биллинг (оригинальная разработка) управляет RADIUS-сервером (FreeRadius), который в свою очередь хранит информацию о пользователях и сервисах в "понятном" для ISG виде.
При необходимости что-либо изменить непосредсвенно на маршрутизаторе с ISG (например, изменить текущий тариф, если пользователь поменял себе тариф и хочет наблюдать изменение скорости) биллинг посылает
CoA-пакет который вызывает деавторизацию пользователя и потом - повторную авторизацию с новыми параметрами.
Пользователи Volume-Based тарифов перенаправляются на "портал" при исчерпании лимита траффика.
Для управления пользователями используются полиси-мап (policy-map) которые применяются на интерфейсы маршрутизатора.
policy-map type control ISG-CUSTOMERS-POLICY class type control ISG-IP-UNAUTH event timed-policy-expiry 1 service disconnect ! class type control always event quota-depleted 1 set-param drop-traffic FALSE ! class type control always event credit-exhausted 1 service-policy type service name LOCAL_L4R ! class type control always event session-start 10 authorize aaa list ISG-AUTH-1 password ISG identifier source-ip-address 20 set-timer UNAUTH-TIMER 1 30 service-policy type service name SERVICE_L4R ! !
Этот policy-map означает
- Для сессий (или пакетов?) удовлетворяющих условию ISG-CUSTOMERS-POLICY выполнить действие 1 service disconnect.
- Для ВСЕХ (control always) событий quota-depleted установить параметр drop-traffic.
Это значит что между событиями quota-depleted (по предыдущему ответу от ААА-сервера лимит исчерпан) и credit-exhausted (ответ от ААА-сервера со значением квоты равной 0) траффик будет продолжать форвардиться.
Отмечу, что теоретически возможна ситуация когда счет будет поплнен после окончания предыдущего лимита и до того как будет произведен перезапрос, событие credit-exhausted никогда не наступит. - При инициации сесии (control always event session-start) будет произведена попытка авторизации (authorize aaa list ISG-AUTH-1 password ISG identifier source-ip-address) и в случае неуспеха (unauth) будет установлен сервис перенаправления (service-policy type service name SERVICE_L4R)
Траффик классифицируется с помощью конструкций class-map
Например:
CLASS-TO-REDIRECT - определяет какой траффик следует редиректить (см. L4 REDIRECT)
Траффик будет классифицирован как соответвующий CLASS-TO-REDIRECT если ИЛИ входящий ИЛИ исхлодящий траффик попадет под ACL 197
class-map type traffic match-any CLASS-TO-REDIRECT match access-group output 197 match access-group input 197
sh access-lists 197 Extended IP access list 197 (Compiled) 10 permit tcp any any eq www (17990 matches) 20 permit tcp any eq www any (4584 matches) 100 deny ip any any (792518 matches)
class-map которому соответвуют unauth-клиенты (назначение таймера мне не ясно на 100%, но он присутвует во всех примерах.)
class-map type control match-all ISG-IP-UNAUTH match timer UNAUTH-TIMER match authen-status unauthenticated
Далее policy-map применяется на интерфейс
sh run int gigabitEthernet 0/1.613 ! interface GigabitEthernet0/1.613 encapsulation dot1Q 613 ip address 123.123.244.193 255.255.255.248 service-policy type control ISG-CUSTOMERS-POLICY ip subscriber routed initiator unclassified ip-address end
ip subscriber routed означает что пользователи не подключены непосредсвенно к интерфейсу (т.е. их МАК-адреса использовать нельзя). initiator unclassified ip-address означает что сессия инициируется при появлении пакета с src- или dst-ip который не может быть отнесен ни к одной из существующих сессий.
На каждого пользователя в процессе работы применяется один или несколько сервисов.
Траффик, который не принадлежит ни одному сервису будет dropped.
Далее, для работы следует определить RADIUS-server который будет хранить информацию о пользователях и (опционально) сервисах.
Делается это следующим образом:
- Описать сервер, егго имя, адресс и порт.
! aaa group server radius ISG-RADIUS server 172.16.30.144 auth-port 1812 acct-port 1813 !
Собственно, более-менее "классическое" описание AAA
aaa authentication login ISG-AUTH-1 group ISG-RADIUS aaa authorization network ISG-AUTH-1 group ISG-RADIUS aaa accounting network ISG-AUTH-1 start-stop group ISG-RADIUS
radius-server attribute 44 include-in-access-req radius-server attribute 44 extend-with-addr radius-server attribute 8 include-in-access-req radius-server attribute 32 include-in-accounting-req radius-server attribute 55 include-in-acct-req radius-server attribute 31 mac format unformatted radius-server host 172.16.30.144 auth-port 1812 acct-port 1813 key 7 0100110D4F080E radius-server vsa send cisco-nas-port radius-server vsa send accounting radius-server vsa send authentication !
Ключевой момент - указать default local, в противном случае нельзя будет использовать локально созданные сервисы.
aaa authorization subscriber-service default local group ISG-RADIUS
Конфигурация RADIUS-сервера
В качестве радиус-сервера традиционно предпочитаю FreeRadius как наиболее гибкий из безплатных.
- Прописываем роутер с ISG как клиента с верным secret
- Создаем сервисы
- Создаем пользователей
Я решил пойти по комбинированому пути - сервисы, которых немного я решил хранить в конфигурационных файлах (что повышает наглядность). Кроме того, один сервис создан непосредсвенно на роутере (с целью демонстрации и такой возможности) Пользователей хранить в БД (mySQL по той причине что биллинг работает с этой БД)
На первой стадии я создаю следующие сервисы
Предоплаченный тариф:
PREPAID_INTERNET Password == "cisco" Cisco-AVPair += "ip:traffic-class=in access-group 196 priority 6", Cisco-AVPair += "ip:traffic-class=out access-group 196 priority 6", Cisco-AVPair += "ip:traffic-class=out default drop", Cisco-AVPair += "ip:traffic-class=in default drop", Cisco-AVPair += "prepaid-config=TRAFFIC_PREPAID"
Обратить внимание - сеть 99.99.99.0/24 исключена из сервиса PREPAID_INTERNET. Это сделано для того что бы траффик на сервер биллинга ("портал") не учитвался и не обрабатывался этим сервисом
access-list 196 deny ip 99.99.99.0 0.0.0.255 any access-list 196 deny ip any 99.99.99.0 0.0.0.255 access-list 196 permit ip any any
Тариф "доступ только на сервер биллинга" ("портал")
BILLING_ACCESS Password == "cisco" Cisco-AVPair += "ip:traffic-class=in access-group 195 priority 4", Cisco-AVPair += "ip:traffic-class=out access-group 195 priority 4", Cisco-Account-Info += "QU;512000;256000;D;512000;256000",
Обратно предыдущему - в ACL сервиса включены только сеть сервера биллинга ("портала")
access-list 195 permit ip 99.99.99.0 0.0.0.255 any access-list 195 permit ip any 99.99.99.0 0.0.0.255 access-list 195 deny ip any any
Сервис редиректа (осуществляет редирект на "портал" для всего траффика попавшего под ACL 197
SERVICE_L4R Password == "cisco" Cisco-AVPair += "ip:l4redirect=redirect list 197 to group REDIRECT_NOPAY", Cisco-AVpair += "traffic-class=input access-group 197", Cisco-AVpair += "traffic-class=output access-group 197", Cisco-AVPair += "ip:traffic-class=out default drop", Cisco-AVPair += "ip:traffic-class=in default drop" Idle-Timeout = "600"
Под редирект должен попадать только www (80 порт), что и отражено в ACL
access-list 197 permit tcp any any eq www access-list 197 permit tcp any eq www any access-list 197 deny ip any any
таблицы в mysql
Некоторые таблицы в БД radius немного модифицированы, некоторые - добавены.
В таблицу radacct добавлено поле AcctUpdateTime.
mysql> describe radacct; +----------------------+-------------+------+-----+---------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------------+-------------+------+-----+---------------------+----------------+ | RadAcctId | bigint(21) | NO | PRI | NULL | auto_increment | | AcctSessionId | varchar(32) | NO | MUL | | | | AcctUniqueId | varchar(32) | NO | MUL | | | | UserName | varchar(64) | NO | MUL | | | | Realm | varchar(64) | YES | | | | | NASIPAddress | varchar(15) | NO | MUL | | | | NASPortId | varchar(15) | YES | | NULL | | | NASPortType | varchar(32) | YES | | NULL | | | AcctStartTime | datetime | NO | MUL | 0000-00-00 00:00:00 | | | AcctStopTime | datetime | NO | MUL | 0000-00-00 00:00:00 | | | AcctUpdateTime | timestamp | NO | | CURRENT_TIMESTAMP | | | AcctSessionTime | int(12) | YES | | NULL | | | AcctAuthentic | varchar(32) | YES | | NULL | | | ConnectInfo_start | varchar(50) | YES | | NULL | | | ConnectInfo_stop | varchar(50) | YES | | NULL | | | AcctInputOctets | bigint(20) | YES | | NULL | | | AcctOutputOctets | bigint(20) | YES | | NULL | | | CalledStationId | varchar(50) | NO | | | | | CallingStationId | varchar(50) | NO | | | | | AcctTerminateCause | varchar(32) | NO | | | | | ServiceType | varchar(32) | YES | | NULL | | | FramedProtocol | varchar(32) | YES | | NULL | | | FramedIPAddress | varchar(15) | NO | MUL | | | | AcctStartDelay | int(12) | YES | | NULL | | | AcctStopDelay | int(12) | YES | | NULL | | | XAscendSessionSvrKey | varchar(10) | YES | | NULL | | +----------------------+-------------+------+-----+---------------------+----------------+
Для базового взаимодействия с биллингом добавлена таблица billing_info куда биллинг записывает информацию о лимитах.
CREATE TABLE `billing_info` ( `ip` varchar(255) default NULL, `traffic` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Для тестов внесу лимит в таблицу для определенного IP
mysql> select * from billing_info; +----------------+---------+ | ip | traffic | +----------------+---------+ | 123.123.244.194 | 1000000 | +----------------+---------+ 1 rows in set (0.00 sec)
Далее добавляю пользователя в таблицу radcheck
mysql> select * from radcheck; +----+----------------+---------------+----+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | id | UserName | Attribute | op | Value | +----+----------------+---------------+----+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | 3 | 123.123.244.194 | Auth-Type | := | `%{sql:SELECT IF((IF(traffic-(SUM(AcctInputOctets)+SUM(AcctOutputOctets))<=0,0,1)=0)And '%{Cisco-Account-Info}'='S%{User-Name}','Reject','Accept') FROM radacct right join billing_info on ip=username where ip='%{User-Name}'}` | | 2 | 123.123.244.194 | User-Password | == | ISG | +----+----------------+---------------+----+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec)
На этом моменте стоит оостановиться немного подробнее - во freeradius есть интересная возможность которая позволяет делать вычисляемые поля (модуль xlat).
Это реализуется с помощью конструкции
`%{sql:SELECT ....}` <PRE> В этой конструкции можно использовать переменные вид %{Attribute} - т.е. ссылаться на атрибуты содержащиеся в полученном пакете. Соответвенно, запрос <PRE> SELECT IF((IF(traffic-(SUM(AcctInputOctets)+SUM(AcctOutputOctets))<=0,0,1)=0)And '%{Cisco-Account-Info}'='S%{User-Name}','Reject','Accept') FROM radacct right join billing_info on ip=username where ip='%{User-Name}'}` <PRE> Проверяем баланс траффика, если баланс положительный то сразу Accept, если нет то проверяем есть ли в запросе '%{Cisco-Account-Info}'='S%{User-Name и Reject или Accept по этому признаку. Нужно для того, что б пользователь с балансом траффка меньше 0 не мог воспользоваться никакими сервисами, но при этом возвращать Accept + лимит равный 0 для запросов переавторизации (см. ниже) или сразу Reject для запросов авторизации. А эти запросы отличать по значению поля '%{Cisco-Account-Info}' В случае если этот запрос вернул Accept то в Auth-Accept из таблицы radreply возвращаем атрибуты пользователя. <PRE> mysql> select * from radreply; +----+----------------+--------------------+----+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | id | UserName | Attribute | op | Value | +----+----------------+--------------------+----+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | 1 | 123.123.244.194 | Cisco-Service-Info | = | NPREPAID_INTERNET | | 2 | 123.123.244.194 | Cisco-Control-Info | += | `%{sql:SELECT IFNULL(CONCAT("QV", GREATEST(0,billing_info.traffic-(IFNULL(SUM(radacct.AcctInputOctets),0)+IFNULL(SUM(radacct.AcctOutputOctets),0)))),"QV0") FROM radacct right join billing_info on billing_info.ip=radacct.username where ip='%{User-Name}'}` | | 3 | 123.123.244.194 | Service-Type | = | Outbound-User | | 4 | 123.123.244.194 | Cisco-Account-Info | += | APREPAID_INTERNET | | 5 | 123.123.244.194 | Cisco-Account-Info | += | NPREPAID_INTERNET | | 6 | 123.123.244.194 | Idle-Timeout | = | 120 | | 7 | 123.123.244.194 | Cisco-Account-Info | += | ABILLING_ACCESS | +----+----------------+--------------------+----+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Запрос в Cisco-Control-Info возвращает квоту клиента в виде QV:<Чисто в Байтах>. Запрос слега замысловатый для обработки ситуации когда radacct пустой.
Для дебага мне понадобилось:
#sh debugging SSS: SSS Manager events debugging is on SSS Manager errors debugging is on SSS policy events debugging is on SSS policy state machine debugging is on SSS policy all debugs debugging is on SSS policy detailed events debugging is on SSS policy error debugging is on Subscriber Service Switch/Policy condition map: Subscriber policy condition map events debugging is on Subscriber Service Switch/Policy rules: Subscriber Service Switch policy rules events debugging is on Subscriber Service Switch/Policy service: Subscriber service events debugging is on SSF/Access-list: ACL feature packets debugging is on ACL feature events debugging is on SSF/L4R: L4 Redirect feature events debugging is on L4 Redirect feature errors debugging is on L4 Redirect feature packets debugging is on SSF/Volume-Monitor: Prepaid volume monitor feature errors debugging is on Prepaid volume monitor feature events debugging is on
http://forum.nag.ru/forum/index.php?showtopic=45688
http://forum.nag.ru/forum/index.php?showtopic=41243
http://forum.nag.ru/forum/index.php?showtopic=42945
http://www.opennet.ru/openforum/vsluhforumID6/17551.html
http://www.opennet.ru/openforum/vsluhforumID6/15205.html
http://www.opennet.ru/openforum/vsluhforumID6/14964.html
http://www.ciscosystems.com/en/US/docs/ios/12_2sb/isg/coa/guide/isg_ig.html
http://www.cisco.com/en/US/docs/ios/12_2sb/isg/configuration/guide/isg_c.html
http://www.cisco.com/en/US/docs/ios/12_3t/12_3t11/feature/guide/gtssgdfq.html
http://www.cisco.com/en/US/docs/ios/isg/configuration/guide/isg_tshoot_sa_dcd.html
http://www.ciscosystems.cd/en/US/docs/ios/isg/configuration/guide/isg_subscriber_svcs.html
http://www.cisco.com/en/US/docs/ios/solutions_docs/edge_ios/ge_rls4.html
Очень интресная статья
http://www.cisco.com/en/US/docs/ios/solutions_docs/edge_ios_migration/migv2.html#wp1246871
Ссылки http://www.cisco.com/univercd/cc/td/doc/product/software/ios122sb/cg/isg_lib/index.htm