Какой должен быть конфиг?

May 17, 2011 19:25

lionet считает тут и тут, что конфиг должен задаваться на декларативном, не тьюринг-полном зяыке.

Как мне кажется, это слишком сильное ограничение для реальных задач. Например, для написания конфигурации radius-сервера. После некоторой дискурсии в каментах он попросил написать меня расширенный пост на эту тему, что я и делаю.

Да, почему конфиг радиус-сервера? Разумеется не потому, что freeradius конфиг идеальный, он скорее ужасный, как и у других радиусов, с которыми я сталкивался (например ACS или встроенный в WLSE Express). Но на этом примере, как мне кажется, можно лучше всего увидеть проблемы, которые не будут решены конфигурацией в декларативном стиле.

Маленькое историческое отступление: за последние 15 лет к конфигурации радиус-серверов значительно усложнились и теперь классической (декларативной, заметим) схемы с clients.conf (список ip и secret) и users.conf (chek pairs & repla pairs) категорически не хватает, причем во всех местах.

Предположим, что у нас есть radius-сервер, который мы хотим использовать для всего, т.е. и для аутентификации юзверей и для аутентификации администраторов. Это означает, что с какого-нибудь мультисервисного маршрутизатора Cisco 3845 с двумя PRI платами, Voice DSP, Modem DSP, VPN Module, EtherSwitch Module, и Access Point Card с одного и того же IP будут приходить запросы, обрабатывать который надо совершенно различным образом:

- админисраторы аутентифицироваться должны по локальной базе
- VPN (EasyVPN и PPTP), WiFi и 802.1x аутентифицироваться должны в AD
- VoIP продается за деньги
- PPP продается за деньги и для своих по AD.

Как предлагается сейчас это все настраивать? да в общем-то левой пяткой через правую подмышку.
Т.е. для какого-то метода аутентификации (например LEAP) указывается, что база пользователей находится в AD. для EAP-FAST мы это укажем еще раз, отдельно. Где логика? Что, тыкая в настройки коммуникатора и меня LEAP на EAP-FAST я ожидаю смены места аутентификации? Бред ведь полный.

Ну или вот для MS-CHAP просто (для VPN) и MS-CHAP внутри EAP -- настройки указываются отдельно и даже модули, их выполнящие -- разные. Тоже никакой логики.

Да, разумеется различать все эти сценарии (т.е. что именно у нас сейчас происходит -- VPN или административный логин) -- можно только на основе эмпирик, которые меняются в зависимости от модели устройства и версии софта на нем.

Единственным вариантом, позволяющим как-то выбраться из такой западни представляется расширение синтаксиса конфига с декларативного до функционального. Возможно, что не тьюринг-полного. И с предметно-ориентированным синтаксисом. Тогда запрос конфигурационного параметра в радиус-сервере будет эквивалентен вызову функции, описанной в конфиге. Разумеется, нет никакой необходимости явно оформлять конфиг как программу на каком-либо известном ФП языке. Нужны ли функциям параметры - мне пока не ясно, вроде как все без них пишется.

Примерно так:

Log {
Dir = '/var/log/radiusd/'
File ($nas_ip == '1.2.3.4') = LogDir..'log-1.2.3.4.log'
File ($auth_type == 'request') = LogDir..'auth.log'
}
Client {
secret ($nas_ip == '1.2.3.4') = 'secret123'
client_name ($nas_ip == '1.2.3.4') = 'cisco_3845'
}
Service ($RadReq{NAS-Port-Type} == 'Virtual' && $RadReq{NAS-Port-Id} =~ /tty.+/) = 'admin' # telnet
Service ($RadReq{NAS-Port-Type} == 'Virtual' && !$RadReq{NAS-Port-Id}) = 'admin' # ssh
Service ($RadReq{NAS-Port-Type} == 'Virtual' && $RadReq{NAS-Port-Id} =~ /[0-9.]+/) = 'vpn' # easyvpn, NAS-Port-Id = "194.26.4.74"
Service ($RadReq{Service-Type} == Framed-User && $RadReq{Framed-Protocol} == 'PPP') = 'vpn' # PPTP
Service ($RadReq{Service-Type} == Framed-User && $RadReq{NAS-Port-Type} == Wireless-802.11) = 'WiFi'
Service ($RadReq{Service-Type} == Framed-User && $RadReq{NAS-Port-Type} == Async) = 'DialUp'
MsChap (Service == 'DialUp') {
Backend = 'Postgres';
}
MsChap (Service == 'vpn') {
Backend = 'AD'
}
Postgres (Service == 'DialUp') {
Table = 'DialUpAuth'
}
AD {
Domain = 'WORK'
PDC = '10.0.0.1'
}
Auth (Service == 'vpn') {
Metods = MS-CHAPv2, NTLM
}
Auth (Service == 'admin') {
Metods = Login-User
}
Auth (Service == 'WiFi') {
Metods = EAP
}
EAP (Service == 'WiFi') {
Metods = LEAP, PEAP, EAP-FAST
}

Критика, замечания?
Previous post
Up