Ключевые слова:auth, aaa, radius, cisco, (найти похожие документы)
From: Vsevolod Stakhov <cebka[at]jet[dot]msk[dot]su>
Date: Mon, 3 Jan 2006 14:31:37 +0000 (UTC)
Subject: Обзор протокола Radius и настройка пакетов Radiusd-livingston и Freeradius
Оригинал: http://cebka.pp.ru/my/radius.txt
Статья впервые опубликована в журнале "Системный Администратор".
Протокол radius(Remote Authentication Dial In User Service) служит для
аутентификации dialup пользователей. Обычно radius
используется маршрутизаторами CISCO для организации модемных линий, но возможны
и варианты связки radius и pppd. В дальнейшем любого клиента radius я буду называть
NAS(network access server - сервер, предоставляющий доступ в сеть). Если
кто интересуется, чем же таким примечателен radius, то отвечу: данный протокол,
с моей точки зрения, является логическим продолжением традиций
tacacs сервера, но он поддерживает больше возможностей и организован IMHO
намного лучше. Особенно мне понравилась возможность проверки различных NAS
по ключу и IP адресу. Огорчает только относительная молодость
протокола, отсутствие качественной документации по бесплатным серверам,
отсутствие поддержки протокола старыми NAS. Последний пункт меня особенно
опечалил: мои любимые коммутаторы Cisco Catalyst, что прекрасно работали с
tacacs сервером, наотрез отказались от работы с радиусом. Но в последних
моделях Cisco и многие другие производители NAS поддерживают
этот протокол.
Для начала определюсь с терминологией:
AV пара - пара атрибут=значение
авторизация - процесс проверки AV пар пользователя. В ходе
авторизации могут также устанавливаться определённые AV пары(для сервера
freeradius), смысл авторизации заключается в проверке достаточности
информации, предоставленной пользователем, для того, чтобы пользователь мог
пройти аутентификацию.
аутентификация - процесс опроса внешних источников данных radius сервером
для сравнения AV пар, предоставленных пользователем, и пар, хранящихся во
внешнем источнике; выбор метода аутентификации определяется AV парой Auth-Type.
аккаунтинг(или учёт) - процесс посылки NAS пакетов на radius-сервер,
которые содержат информацию о текущем соединении(время, количество
переданного трафика и.т.д.), на основании этой информации скрипты
счетчиков или биллинговой системы могут выполнять различные действия по
ограничению доступа пользователей на NAS.
Из серверов, доступных в сети я выбрал freeradius (http://www.freeradius.org) -
новая версия популярного cistron radius-a, который особенно меня порадовал тем, что он
содержит значительное количество модулей аутентификации(например, sql,
ldap, unix-passwd, samba-passwd) и стандартный(обладающий меньшими возможностями)
radiusd-livingston (ftp://ftp.livingston.com/pub/le/radius/radius21.tar.Z),
Эти два сервера распространяются бесплатно, и их компиляция не вызывает затруднений:
$./configure
$make
#make install
Теперь самое время рассказать поподробнее о самом протоколе radius.
Сервер radius использует протокол UDP для работы. Стандартно radius сервер
прослушивает 1812 порт. Для аккаунтинга используется другой порт - 1813(radius-acct).
Рассмотрим как отреагирует NAS при поступлении запроса пользователя на аутентификацию:
* пользователь пытается пройти аутентификацию на NAS
* NAS смотрит в первый попавшийся radius сервер и посылает пакет для
установки связи(запрос на доступ)
* если ответ не получен в течение определённого тайм-аута, то NAS либо
опрашивает radius сервер ещё раз, либо ищет альтернативный сервер
* radius сервер смотрит ip адрес NAS и проверяет ключ симметричного шифрования, если
ip адрес и ключ соответствуют тому, что написано в конфигурационном файле, то
связь продолжается, иначе клиенту посылается пакет Invalid Key.
Проверка осуществляется генерацией и шифрацией случайной строки. Далее передаваемые
между клиентом и сервером radius данные шифруются данным ключом.
* сервер radius проверяет пароль пользователя(по сети передается md5 хеш пароля),
помимо пароля сервер может также проверить ip адрес и порт NAS,
если эти данные неверны, то сервер посылает NAS пакет "Доступ запрещён",
содержащий код ошибки, который также может содержать текстовое описание ошибки,
отображаемое для пользователя
* если же данные пользователя верны, то сервер посылает NAS пакет "Доступ
разрешён", содержащий данные о сервисе(PPP, SLIP, login) и некоторые
специфические параметры сервиса, например, ip адрес, номер подсети, MTU для
PPP сервиса в виде пар параметр=значение(AV пар).
Radiusd-livingston
После краткого теоретического отступления перейду к описанию настройки
серверов. Для начала сразу же определюсь: я не ставлю своей целью
рассказать о каждой опции и извращённой возможности, я просто описываю, как
оно работает у меня. В принципе, настройка livingston-a и freeradius
достаточно сильно различается, поэтому рассматривать я их буду
по-отдельности. Radiusd-livingston является более ранним сервером и проще в
настройке, чем freeradius, поэтому его настройку я опишу в первую очередь.
Конфигурация сервера хранится в каталоге /etc/raddb(или в
$PREFIX/etc/raddb) и представляет собой несколько файлов, отвечающих за
работу отдельных механизмов сервера: clients - определения NAS(ключ и ip адрес) для проверки
подлинности клиента, users - файл, описывающий dial-in пользователей, proxy -
настройки перенапарвления запросов клиентов другим radius серверам, если
аутентификация на данном прошла неудачно(возможность роуминга или
распределения пользователей), dictionary - словарь
определений AV пар для работы с клиентом. Далее я просто приведу примеры
конфигурационных файлов с комментариями:
clients:
# В данном файле находится список клиентов(NAS), которые могут проходить
# аутентификацию. Клиент проходит проверку имени и ключа. Файл имеет
# соответствующую структуру: поле имени и поле ключа:
#Имя клиента Ключ
#---------------- -------------------
NAS1 123456789cba
NAS2:call 987654321abc
proxy:
# В данном файле описываются radius серверы, на которые данный может
# перенаправлять запросы NAS. Такое поведение, например, полезно для
# организации роуминга. Представим ситуацию: существуют 2 провайдера А и Б,
# они хотят, чтобы клиент, заключивший договор с одним из них, мог
# беспрепятственно заходить и на другой. В данном случае в данном файле
# прописывается radius сервер второго провайдера, на который будет
# осцществляться перенаправление. Наличие ключей позволяет защитить сервера
# доступа от подмены данных. Данный файл содержит четыре поля: имя
# сервера,ключ доступа к серверу(на удалённом сервере необходимо внести
# запись в clients, соответствующую серверу, осуществившему перенаправление),
# область действия сервера(т.е. каких клиентов следует перенаправлять на
# данный сервер, определяется именем клиента после знака @, например,
# [email protected]), необязательные опции и номера портов. Доступные опции выглядят следующим
# образом: old - удаление области действия и состояния прокси из заголовка
# сообщения от NAS, secure - возможность пересылки запросов на доступ с
# привиллегиями администратора, ipass - использование протокола
# ipass(непереводимое слово).
rad.test.ru somekey test.ru
radius.ru.net papakeyyer com.net 1645 1646 secure
users:
# Это основной файл, где хранятся данные о пользователях. Описание идёт
# так: вначале идёт без отступа имя пользователя, затем, отступая на
# табуляцию, идут AV пары(первой парой идёт пароль). AV пары должны
# описываться в файле словаря dictionary. Существует также специальный
# пользователь по умолчанию, который имеет специальное имя DEFAULT. Обычно
# пользователь по умолчанию используется, когда описания пользователей
# находятся не в данном файле, а в /etc/passwd, но об этом я расскажу
# далее. Для начала приведу несколько примеров описания пользователей(для
# получения полного списка AV пар смотрите файл словаря). Ещё учтите, что
# имя пользователя может иметь максимум 8 символов в длину, пароль в
# принципе до 254 символов, но я часто слышал про ограничение в 31
# символ(честно говоря, представить себе не могу когда может понадобиться
# пароль длиннее 31 символа!)
user1 Password = "testing", Expiration = "Dec 24 1995"
Service-Type = Framed-User,
Framed-Protocol = PPP,
Framed-IP-Address = 255.255.255.254,
Framed-Routing = None,
Filter-Id = "std.ppp",
Framed-MTU = 1500,
Framed-Compression = Van-Jacobson-TCP-IP
user2 Password = "moretest"
Service-Type = Login-User,
Login-IP-Host = 192.168.2.7,
Login-Service = PortMaster
user3 Password = "callme"
Service-Type = Callback-Login-User,
Login-IP-Host = timeshare1,
Login-Service = PortMaster,
Callback-Number = "1231234"
# В конце файла может быть описание пользователя по умолчанию DEFAULT. В
# данном случае используется аутентификация через пароли в /etc/passwd, для
# этого используется директива Auth-Type = System. Значение префикса или
# суффикса для имени пользователя означает, что производится поиск данного
# префикса или суффикса, а остальная часть имени используется
# непосредственно как имя пользователя. Это удобно для добавления
# различных типов доступа для пользователя в зависимости от префикса или
# суффикса. Такое поведение показано ниже:
# Для пользователей, начинающихся с буквы P(Pusername) используется сервис
# PPP
DEFAULT Auth-Type = System, Prefix = "P"
Service-Type = Framed-User,
Framed-Protocol = PPP,
Framed-IP-Address = 255.255.255.254,
Framed-MTU = 1500
# Для префикса S - SLIP
DEFAULT Auth-Type = System, Prefix = "S"
Service-Type = Framed-User,
Framed-Protocol = SLIP,
Framed-IP-Address = 255.255.255.254,
Framed-Compression = None
# Компрессия трафика - префикс C
DEFAULT Auth-Type = System, Prefix = "C"
Service-Type = Framed-User,
Framed-Protocol = SLIP,
Framed-IP-Address = 255.255.255.254,
Framed-Compression = Van-Jacobson-TCP-IP
# Здесь используется суффикс %ppp, сигнализирущий использование протокола
# PPP
DEFAULT Auth-Type = System, Suffix = "%ppp"
Service-Type = Framed-User,
Framed-Protocol = PPP,
Framed-IP-Address = 255.255.255.254,
Framed-MTU = 1500
# Для пользователя, не соответствующего другим определениям запускаем
# протокол PPP
DEFAULT Auth-Type = System, Framed-Protocol = PPP
Service-Type = Framed-User,
Framed-Protocol = PPP,
Framed-IP-Address = 255.255.255.254,
Framed-MTU = 1500
dictionary:
# Данный файл содержит описания атрибутов и значений. Конечно же, я не
# буду приводить его целиком, приведу пример только основных AV.
# Описания атрибутов: ATTRIBUTE имя_атрибута число_соответствующее_атрибуту
# тип_атрибута. Число для атрибута используется как синоним текста, можно
# написать Password="text", что идентично 2="text". Тип атрибута может
# принимать следующие значения:
# string - строка длиной от 0 до 253 символов
# ipaddr - ip адрес, 4 байта в сетевом порядке
# integer - 32-х битное целое в интеловском порядке байт
# date - 32-х битное число, означающее текущую дату и время
ATTRIBUTE User-Name 1 string
ATTRIBUTE Password 2 string
ATTRIBUTE Framed-IP-Address 8 ipaddr
ATTRIBUTE Expiration 21 date
# Описания значений: VALUE имя_значения имя_атрибута номер. Обычно описания
# значений служат для установления соответствия строка-номер. Так,
# например, значение протокола имеет числовой вид, но для упрощения
# составления файла конфигурации некоторым числам сопоставлены числовые
# константы(можно привести аналогию #define MACRO 1 в си):
VALUE Service-Type Login-User 1
VALUE Service-Type Framed-User 2
VALUE Service-Type Callback-Login-User 3
VALUE Service-Type Callback-Framed-User 4
VALUE Service-Type Outbound-User 5
VALUE Service-Type Administrative-User 6
VALUE Framed-Protocol PPP 1
VALUE Framed-Protocol SLIP 2
VALUE Framed-Protocol ARAP 3
VALUE Login-Service Telnet 0
VALUE Login-Service Rlogin 1
VALUE Login-Service TCP-Clear 2
VALUE Login-Service PortMaster 3
Для проверки работы radius-сервера используется специальная программа -
rad_test, но о ней я расскажу далее при описании сервера freeradius(в
livingston-е она точно такая же).
Freeradius.
Данный сервер отличается исключительной функциональностью. Он может
работать с SQL серверами(в настоящее время поддерживаются mysql,
postgresql, oracle), LDAP сервером, содержит в себе достаточно много AV
словарей, отличается весьма комплексной настройкой, поддерживает
дополнительные модули, имеет веб-интерфейс для настройки и несколько весьма
полезных скриптов. Конфигурация freeradius несколько похожа на настройку
livingston-a, поэтому я буду рассказывать преимущественно о работе
аутентификации пользователей radius через mysql.
Общие настройки сервера размещаются в файле radiusd.conf. Я приведу здесь
несколько опций, показавшихся мне полезными:
radiusd.conf
# Общая схема файлов конфигурации freeradius позволяет использовать
# специальную директива $INCLUDE для включения конфигурационных файлов в
# данный(формат .conf)
$INCLUDE ${confdir}/proxy.conf
$INCLUDE ${confdir}/clients.conf
# Полезно будет указать пользователя и группу, под которыми будет работать
# сервер. В принципе лучше, чтобы привеллегий было поменьше.
# Если же использовать аутентификацию mysql,
# то выбор nobody:nobody IMHO является наилучшим.
user = nobody
group = nobody
# Максимальное время обработки запроса(в секундах), по истечение которого
# клиенту будет послан пакет, сигнализирующий разрыв соединения.
max_request_time = 30
# Максимальное количество соединений для данного сервера. Обычно число
# получается умножением числа NAS в сети на 256. Например, для 4 клиентов,
# значение будет 4*256=1024
max_requests = 1024
# Заносить в лог данные о полном имени пользователя
log_stripped_names = yes
# Заносить ли в лог инфу о запросах на аутентификацию
log_auth = no
# Заносить ли в лог данные о переданных паролях(неправильных и правильных
# соответственно)
log_auth_badpass = yes
log_auth_goodpass = no
# Приводить ли к нижнему регистру все имена пользователей и пароли(весьма
# полезно для некоторых пользователей). Возможные значения no -
# чувствительные к регистру пароль/имя, before - вначале приводим к нижнему
# регистру, потом проводим аутентификацию, after - вначале проверяем
# аутентификацию как есть, если не получилось, то приводим к нижнему
# регистру и повторяем попытку.
lower_user = no
lower_pass = no
# Убираем пробелы из имени пользователя и пароля. Полезно для имён и
# паролей, содержащих пробелы, т.к. проверка такой гадости может быть
# неверна. Возможные значения аналогичны предыдущему случаю.
nospace_user = no
nospace_pass = no
# Весьма полезные параметры модуля безопасности сервера:
security {
# Максимальное число AV пар в пакете. Если число пар больше, то
# пакет не обрабатывается. Если указать данный параметр равным
# нулю, то будут обрабатываться любые пакеты.
max_attributes = 200
# Пакет отказа доступа может быть отправлен с некоторой задержкой(в
# секундах). Такое поведение предотвращает применение DoS атаки.
# Если же указать значение, равное нулю, то отказ будет
# посылаться без задержки.
reject_delay = 1
# Посылать ответ на запрос NAS о статусе сервера. Такое поведение
# не описано в rfc, поэтому по умолчанию no(как написано в
# комментариях "может пригодиться для некоторых особых NAS")
status_server = no
}
# Обрабатывать перенаправление запросов. Если перенаправление отключено, то
# необходимо отключить файл proxy.conf, дабы избежать ошибок
# конфигурации(закомментарить директиву $INCLUDE ${confdir}/proxy.conf).
proxy_requests = yes
# Далее следует описания многочисленных модулей freeradius, позволяющие
# настроить, кпримеру, методы шифрации паролей или работу различных
# аутентификационных протоколов(PAP, CHAP, MS-CHAP), но описывать здесь всё
# я не намерен: думаю, что в примерах все и так очень подробно
# комментировано и разобраться там не будет составлять труда.
Настройка клиентов производится в файле clients.conf:
clients.conf
# В данном файле описываются клиенты aka NAS. Формат файла напоминает файл
# настройки tacacs+. Вначале идёт определение клиента: client
# имя_или_ip_адрес, затем идёт список AV пар для данного клиента,
# заключённый в фигурные скобки. Приведу несколько примеров:
client 127.0.0.1 {
# Пароль для идентификации клиента и обмена с ним данными. Данным
# ключом также осуществляется проверка неизменности передаваемых
# пакетов(подпись).
secret = some_strange_secret
# Краткое имя для клиента.
shortname = localhost
# Следующие три поля необязательны, но они полезны для работы
# скрипта checkrad.pl(проверка работы процессов
# сервера)
# Поле типа NAS, может принимать следующие значения:
# Хотя, за каким эта дурь нужна я так и не понял :)
# cisco
# computone
# livingston
# max40xx
# multitech
# netserver
# pathras
# patton
# portslave
# tc
# usrhiper
# other
nastype = other # localhost обычно не является NAS
# Две следующие строчки зарезервированы на будущее. Вообще-то они
# использоваться должны для проверки имени пользователя и пароля
# для данного NAS
# login = !root
# password = someadminpas
}
client some.test.ru {
secret = some_host_secret
shortname = somenas
}
# Также можно определять пароль для всех клиентов для некоторой подсети(чем
# меньше подсеть, тем лучше, а вообще IMHO это не есть хорошо из
# соображений безопасности)
client 192.168.0.0/24 {
secret = a_very_long_passwd
shortname = private-network
}
Далее я кратко остановлюсь на особенностях настройки файла proxy.conf. В
отличие от сервера livingston во freeradius опять же используется
собственный конфигурационный формат. Из нововведений особенно бросается в
глаза новая директива - realm, определяющая область перенаправления. Дабы
не быть голословным опять же приведу несложный пример:
proxy.conf
# Данный файл состоит из двух разделов: описание настроек самого
# прокси-сервера и описание областей перенаправления. На конфигурации
# работы самого прокси-сервера я останавливаться не буду, а сразу же прейду
# к описанию директивы определения области realm. Она выглядит следующим
# образом: realm имя_области. Имя области должно являться именем домена,
# который этой областью описывается. Если вместо имени области
# употребляется слово DEFAULT, то в данную область будут перенаправляться
# запросы, не соответствующие ни одному параметру. Поясню это на примерах:
realm isp2.ru {
# Тип сервера
type = radius
# Сервер радиуса для аутентификации
authhost = radius.isp2.com:1645
# Сервер радиуса для аутентификации(обычно другой порт)
accthost = radius.isp2.com:1646
# Секрет для связи
secret = our_concurents_key
# Не убирать суффикс или префикс области из имени пользователя
nostrip
}
# Если перенаправить запрос на данный сервер не удалось, то происходит
# выборка другого сервера для данной области или сервера по умолчанию.
# Также существует специальная область NULL для клиентов, которые не
# определили область действия, например, просто user(сравните [email protected])
realm NULL {
type = radius
authhost = radius.test.ru
accthost = radius.test.ru
secret = our_secret_key
}
# Ну а для тех пользователей, чья область не определена, используется сервер
# по умолчанию:
realm DEFAULT {
type = radius
authhost = radius.test.ru
accthost = radius.test.ru
secret = our_secret_key
}
# Учтите в двух последних примерах при перенаправлении запроса к вторичным
# серверам radius из имени пользователя вырезается имя области, т.к. не
# определена опция nostrip.
Теперь для любопытствующих кратко опишу назначение остальных
конфигурационных файлов freeradius:
acct_users - содержит установки учёта(аккаунтинга).
Обычно используется для задания начальных и конечных
скриптов для пользователя и областей репликации(см. пример). В скрипты
можно передавать специальные переменные:
* %a Protocol (SLIP/PPP)
* %c Callback-Number
* %d request day (DD)
* %f Framed IP address
* %i Calling Station ID
* %l request timestamp
* %m request month (MM)
* %n NAS IP address
* %p Port number
* %s Speed (PW_CONNECT_INFO)
* %t request in ctime format
* %u User name
* %A radacct_dir
* %C clientname
* %D request date (YYYYMMDD)
* %H request hour
* %L radlog_dir
* %M MTU
* %R radius_dir
* %S request timestamp in SQL format
* %T request timestamp in database format
* %U Stripped User name
* %V Request-Authenticator(Verified/None)
* %Y request year (YYYY)
Пример:
DEFAULT Acct-Status-Type == Start
Exec-Program = "/path/to/exec/acct/start %U"
DEFAULT Acct-Status-Type == Stop
Exec-Program = "/path/to/exec/acct/stop %U %n %a"
attrs - информация об AV парах по умолчанию для каждой области действия.
clients.conf - настройки NAS.
dictionary - данные об известных AV парах.
hints - информация о суффиксах и префиксах имён пользователей
Пример:
# Здесь директива Strip-User-Name определяет удалять ли префикс или суффикс
# из имени
DEFAULT Suffix = ".ppp", Strip-User-Name = Yes
Hint = "PPP",
Service-Type = Framed-User,
Framed-Protocol = PPP
DEFAULT Prefix = "P", Strip-User-Name = Yes
Hint = "PPP",
Service-Type = Framed-User,
Framed-Protocol = PPP
proxy.conf - информация об областях
sql.conf - настройки работы с mysql(к этому файлу я вернусь далее)
users - а вот этот файл очень важен для последующего изложения, он
описывает пользователей. Описание пользователей похоже на аналогичное в
livingston-radius:
user Auth-Type := Local, User-Password == "testing"
Service-Type = Framed-User,
Framed-Protocol = PPP,
Framed-IP-Address = 172.16.3.33,
Framed-IP-Netmask = 255.255.255.0,
Framed-Routing = Broadcast-Listen,
Framed-MTU = 1500,
Framed-Compression = Van-Jacobsen-TCP-IP
но сразу бросается в глаза отличие: использование специальных операторов
присваивания и сравнения(в linvingston был только один - "="). Приведу
список "новых" операторов:
* "Attribute = Value"
Атрибут посылается NAS, его значение равно Value
* "Attribute := Value"
Если данный атрибут не определён, то он принимает указанное значение
* "Attribute == Value"
Используется ТОЛЬКО для проверки значения атрибута
* "Attribute += Value"
Добавление нового значения атрибуту
* "Attribute != Value"
* "Attribute > Value"
* "Attribute >= Value"
* "Attribute < Value"
* "Attribute <= Value"
Различные операции сравнения
* "Attribute =~ Expression"
* "Attribute !~ Expression"
Проверка соответствия значения атрибута определённому регулярному выражению
* "Attribute =* Value"
Проверка, содержит ли запрос данный атрибут, значение не играет роли
* "Attribute !* Value"
Однако если вы намереваетесь использовать radius для работы с большим
числом пользователей, то использование файла users не подходит(он целиком
помещается в память). В качестве альтернативы используются сервера LDAP или
MySQL(PostgreSQL, Oracle). Использование LDAP IMHO несколько практичнее, но
я прекрасно понимаю, что MySQL распространён намного больше, поэтому о его
использовании я и поведу речь...
Для начала добываем и устанавливаем mysql(этот процесс я не описываю).
Обязательно устанавливаем(если работаем с пакетами) пакет mysql-dev. После
этого перекомпилируем radius(configure скрипт сам обнаружит mysql и включит
в makefile нужный модуль). После этого создаём базу в mysql:
$mysql -uroot -proot_passwd
mysql> create database radius;
После этого выполняем mysql сценарий для создания таблиц в базе. Для этого
заходим в каталог модуля mysql:
$cd {PATH_TO_RADIUS_SRC}/src/modules/rlm_sql/drivers/rlm_sql_mysql
и передаём mysql сценарий:
$mysql -uroot -proot_passwd radius < db_mysql.sql
База состоит из 5-и таблиц:
Usergroup - данные о группах пользователей, например
mysql> select * from usergroup;
+----+---------------+-----------+
| id | UserName | GroupName |
+----+---------------+-----------+
| 1 | steve | dynamic |
| 2 | barney | static |
+----+---------------+-----------+
2 rows in set (0.00 sec)
Radcheck - AV пары для проверки пользователя(обычно пароль), например
+----+----------------+----------------+--+--------------------+
| id | UserName | Attribute |op| Value |
+----+----------------+----------------+--+--------------------+
| 1 | steve | User-Password |==| testing123 |
| 2 | steve | Auth-Type |:=| Accept |
| 3 | barney | Chap-Password |==| test |
+----+----------------+----------------+--+--------------------+
2 rows in set (0.02 sec)
Radgroupcheck - проверка атрибутов для группы(не знаю, зачем это нужно)
Radreply - таблица, содержащая AV пары, передающиеся клиенту сервером при
прохождении аутентификации, например
mysql> select * from radreply;
+----+------------+-------------------+--+---------------------------------+
| id | UserName | Attribute |op| Value |
+----+------------+-------------------+--+---------------------------------+
| 1 | barney | Framed-IP-Address | =| 1.2.3.4 |
| 2 | setve | Framed-IP-Address | =| 2.3.4.1 |
| 3 | steve | Framed-IP-Netmask | =| 255.255.255.255 |
| 4 | steve | Framed-Routing | =| Broadcast-Listen |
| 5 | steve | Framed-Route | =| 2.3.4.0 255.255.255.248 |
| 6 | steve | Idle-Timeout | =| 900 |
+----+------------+-------------------+--+---------------------------------+
6 rows in set (0.01 sec)
Radgroupreply - AV пары, содержащиеся в ответе сервера для данной группы,
например:
mysql> select * from radgroupreply;
+----+-----------+--------------------+--+---------------------+
| id | GroupName | Attribute |op| Value |
+----+-----------+--------------------+--+---------------------+
| 34 | dynamic | Framed-Compression | =| Van-Jacobsen-TCP-IP |
| 33 | dynamic | Framed-Protocol | =| PPP |
| 32 | dynamic | Service-Type | =| Framed-User |
| 31 | dynamic | Auth-Type | =| Local |
| 35 | dynamic | Framed-MTU | =| 1500 |
| 36 | static | Auth-Type | =| Local |
| 37 | static | Framed-Protocol | =| PPP |
| 38 | static | Service-Type | =| Framed-User |
| 39 | static | Framed-Compression | =| Van-Jacobsen-TCP-IP |
| 40 | netdial | Auth-Type | =| Local |
| 41 | netdial | Service-Type | =| Framed-User |
| 42 | netdial | Framed-Protocol | =| PPP |
+----+-----------+--------------------+--+---------------------+
12 rows in set (0.01 sec)
Учтите тот факт, что mysql используется для авторизации пользователя,
парольная аутентификация осуществляется модулем, который определён в AV
паре Auth-Type(в таблице radcheck можно присвоить пользователю это поле по
умолчанию с помощью оператора ':='). Существует много типов
аутентификации(см. соответствующие значения атрибутов в словаре
dictionary), большинство из них определяют пароль из mysql. В данном
примере для простоты приведён пример типа аутентификации Accept, который
сразу же возвращает пакет разрешения доступа, применять этот тип следует
лишь в тестирующих целях. Другие распространённые методы аутентификации:
System - системная аутентификация(для pap протокола), обычно нужна запись в
/etc/passwd для проверки пароля, друго вариант - использование файла users.
Chap - аутентификация протокола chap(пароль передаётся в открытом виде)
Reject - отклонение доступа пользователя.
Ms-Chap
Ldap - проверка пароля через службу каталогов ldap(необходимо поправить
подсекцию ldap в секции modules файла radiusd.conf)
Важно знать, что для некоторых типов аутентификации(system) можно использовать
зашифрованные пароли - Crypt-Password в формате Unix crypt. Для Ms-Chap
необходимо использовать параметры LM-Password и NT-Password. Для изучения других
параметров полезно почитать файл словаря dictionary.
И ещё один хинт: иногда очень полезно использовать пользователя по
умолчанию DEFAULT для сообщения некоторых AV пар, общих для всех пользователей.
Для настройки radiusd необходимо проверить следующие пункты radiusd.conf:
секция modules, дабы убедиться, что файл конфигурации mysql включен:
modules {
# Включение файла для работы с mysql, для работы с другими СУБД
# используются файлы
# Postgresql: ${confdir}/postgresql.conf
# MS-SQL: ${confdir}/mssql.conf
$INCLUDE ${confdir}/sql.conf
}
секция авторизации, настроенная для использования ldap и mysql:
authorize {
preprocess
chap
mschap
suffix
files
sql
ldap
}
Настройка данных методов проводится в соответствующих подсекциях секции
modules. В разделе аутентификации можно также объявлять собственные методы,
например:
authenticate {
authtype my_dialup {
pap
chap
ldap
}
}
и использовать их в поле Auth-Type.
В файле sql.conf также делаются некоторые изменения для указания сереверу radius
информации о поиске данных в mysql:
sql {
# Тип базы данных
driver = "rlm_sql_mysql"
# Параметры соединения
server = "localhost"
login = "root"
password = "mysql_passwd"
# База данных, используемая радиусом
radius_db = "radius"
# Первая таблица хранит записи начала соединения(start), 2-я -
# записи окончания соединения(stop). Если они совпадают, то эти записи
# хранятся в одной таблице.
acct_table1 = "radacct"
acct_table2 = "radacct"
# Таблица авторизации и установки типа аутентификации
authcheck_table = "radcheck"
authreply_table = "radreply"
# Групповые таблицы
groupcheck_table = "radgroupcheck"
groupreply_table = "radgroupreply"
# Соответствие пользователей группам
usergroup_table = "usergroup"
# Remove stale session if checkrad does not see a double login
deletestalesessions = yes
# Все sql запросы выводятся в режиме отладки radiusd -x
sqltrace = yes
sqltracefile = /usr/local/var/log/radius/sqltrace.sql
# Количество соединений с сервером. При большой загрузке
# рекоммендуется увеличить.
num_sql_socks = 5
# Число секунд, перед тем как сервер предпринимает повторную
# попытку соединения, если произошёл сбой соединения с mysql.
connect_failure_retry_delay = 60
Начало работы
Для проверки сервера используется утилита radtest(она присутствует во всех,
проверенных мною серверах). Формат её использования таков:
radtest user_name password radius_server nas_port secret
Например, если существует пользователь testuser с
паролем testing, то формат команды будет таков:
$radtest testuser testing radius.test.ru 1 radius_secret
Если же у вас что-то не работает(знаю по опыту - так бывает часто, даже
если всё вроде правильно сделал, напишешь что-нибудь вроде dev/null, вместо
/dev/null, а потом паришься и ищешь недостающий файл) то
очень может помочь опция отладки radiusd -x. При этом радиус не вызывает
fork и все отладочные данные выводятся на терминал, в таком режиме как
сервер он работать практически не может, зато разжуёт, какие файлы он
прочитал и что он делает. Вкупе с утилитой radtest это может помочь решить
любые проблемы. Ещё советую включить в файле radiusd.conf запись в логи, это
поможет выявить проблемы безопасности. Иногда более целесообразно применять
совместно с radius ldap, т.к. при большом количестве пользователей использование
единого источника данных о пользователях и паролях будет намного удобнее и
эффективнее. Для этого правим файл radiusd.conf:
ldap {
server = "ldap.test.ru"
# Этот юзер должен иметь право читать пароли, поэтому
# необходимо добавить соответствующий acl в файл
# конфигурации ldap сервера(об этом рассказано в статье об
# ldap)
identity = "cn=proxy,dc=test,dc=ru"
password = mypass
basedn = "o=test,c=ru"
filter = "(uid=%{Stripped-User-Name:-%{User-Name}})"
# Включаем безопасное соединение, не меняя порт
start_tls = yes
# Фиг знает что, но вроде это заставляет шифровать данные
# при запросе к серверу
tls_mode = yes
# В данной ветви хранятся профили пользователей
default_profile = "cn=radprofile,ou=dialup,dc=test,dc=ru"
# profile_attribute = "radiusProfileDn"
access_attr = "dialupAccess"
# В данном атрибуте предполагается хранение пароля пользователя
password_attribute = "userPassword"
# Атрибуты для перевода формата значений ldap => radius
dictionary_mapping = ${raddbdir}/ldap.attrmap
# Остальная часть убрана, т.к. не заслуживает отдельного
# внимания
}
Учтите ещё, что при компиляции радиуса с ldap-ом надо иметь нужные
библиотеки и хедеры, иначе модуль не скомпилится. Ну и конечно же нужно
включить аутентификацию через ldap. Делается это стандартным
раскомментированием строк ldap в секциях authorize и authenticate(см.
описание работы через sql). Для указания того, использования аутентификации
через ldap данного пользователя необходимо устанавливать AV пару Auth-Type
= ldap. В частности, можно для этого использовать оператор Auth-Type :=
ldap. Заметьте также, что ldap не различает регистр символов, поэтому
возможно возникновение проблем. Для этого в radius.conf надо включить
lower_user = yes" и "lower_time = before" в основной секции(см. выше).
Кроме этого в сервер ldap необходимо включить файл схемы
RADIUS-LDAPv3.schema(находится в исходниках в подкаталоге doc).
Отдельного разговора заслуживает тема учёта или аккаунтинга. Фактически
сервер radius состоит из двух частей: сервера авторизации и аутентификации
и сервера учёта. Учёт может выполняться через различные источники,
например, через sql или простые файлы. Единственное условие для работы
аккаунтинга - правильная настройка NAS(далее приведён пример конфигурации
маршрутизатора CISCO). Аккаунтинг может выполняться либо через внешние
скрипты(файл acct_users, для livingston-radius этот метод является
единственным), либо через внутренние настройки. Далее будет рассматриватся
лишь второй способ, т.к. о структуре файла acct_users я уже говорил выше. В
файле radiusd.conf существует секция accounting, у меня она выглядит так:
accounting {
# Данный модуль используется для создания уникального идентификатора пакета
# аккаунтинга, т.к. это требуют многие NAS, поэтому этот модуль обычно
# необходимо включать
acct_unique
# Данный модуль позволяет создавать каждый час файл с информацией о
# пользователе. Файлы создаются по умолчанию в формате
# detailfile = ${radacctdir}/%{Client-IP-Address}/detail-%Y%m%d
# detail
# Модуль счетчика - заслуживает отдельного разговора
# counter
# Стандартный wtmp формат
# unix
# utmp файл, содержащий имена пользователей и порты NAS
# radutmp
# utmp файл, не содержащий имён пользователей, поэтому доступный всем для
# чтения
# sradutmp
# Модуль аккаунтинга через sql
sql
}
Чтобы разобраться подробнее необходимо выяснить, что же содержится в
пакетах аккаунтинга(взято из документации к серверу radacct, о котором
будет рассказано далее).
Следующие атрибуты пакета Accounting-Request считаются обязательными:
* Acct-Status-Type - подтип пакета: Start(начало сессии), Stop(конец сессии) или Alive;
* NAS-IP-Address - IP-адрес NAS;
* Acct-Session-Id - идентификатор сессии NAS;
* User-Name - идентификатор пользователя (с возможным префиксом или суффиксом);
* NAS-Port - номер порта NAS.
Используются также следующие опциональные атрибуты, динамически изменяемые
в процессе сессии:
* NAS-Port-Type - тип порта NAS, по умолчанию Async;
* Service-Type - тип сервиса, по умолчанию Login;
* Framed-Protocol - протокол, по умолчанию PPP (Service-Type=Framed);
* Framed-IP-Address - IP-адрес клиента (Service-Type=Framed);
* Login-IP-Host - IP-адрес сервера (Service-Type=Login);
* Acct-Delay-Time - задержка в предоставлении сервиса;
* Called-Station-Id - идентификатор вызываемой стороны (номер телефона?);
* Calling-Station-Id - идентификатор вызывающей стороны (номер телефона?).
Следующие атрибуты определяются по окончании сессии:
* Acct-Session-Time - время занятия в текущей сессии;
* Acct-Input-Octets - количество принятых байт;
* Acct-Output-Octets - количество отосланных байт;
* Acct-Input-Packets - количество принятых пакетов;
* Acct-Output-Packets - количество отосланных пакетов.
После этого можно понять общие принципы работы системы учёта - при успешной
аутентификации пользователя на radius сервере NAS инициирует сессию
аккаунтинга, по завершении которой выдаются итоговые данные. Данные учёта
могут анализироваться внешними системами или самим radius сервером. Приведу
простой пример - организацию учёта через mysql:
в секции аккаунтинга файла radiusd.conf должен быть модуль sql;
в настройках mysql(sql.conf) должна быть определена таблица для учёта:
# Для записей о начале сессии
acct _table1 = "radacct"
# Для записей о конце сессии
acct _table2 = "radacct"
таблица учёта создаётся автоматически при создании структуры базы данных
radius(описано выше).
После настройки собственно учёта необходимо продумать политику ограничения
доступа. Для этого существуют счётчики. Здесь я приведу пример счётчика
sql. Счётчик работает по принципу переодической проверки данных учёта и на
основании этого принимается решение о дальнейшей работе пользователя. Для
этого счётчик должен быть добавлен в секцию authorize файла radiusd.conf.
Конфигурацию счётчика будем хранить в файле sqlcounter.conf, имеющим
приблизительно такой формат(взято из документации к серверу freeradius):
# Счётчик общего времени
sqlcounter noresetcounter {
counter-name = Max-All-Session-Time
# Проверка определённого атрибута в таблице radcheck
check-name = Max-All-Session
# Используемый процесс sql
sqlmod-inst = sql
# Поле, по которому происходит расчёт времени
key = User-Name
# Сброс счётчика, в данном случае счётчик не сбрасывается
reset = never
# SQL запрос, выполняемый счётчиком
query = "SELECT SUM(AcctSessionTime) FROM radacct
WHERE UserName='%{%k}'"
}
# Счетчик сбрасывается ежедневно
sqlcounter dailycounter {
driver = "rlm_sqlcounter"
counter-name = Daily-Session-Time
check-name = Max-Daily-Session
sqlmod-inst = sql
key = User-Name
# Сброс счётчика ежедневно
reset = daily
query = "SELECT SUM(AcctSessionTime - GREATEST
((%b - UNIX_TIMESTAMP(AcctStartTime)), 0))
FROM radacct WHERE UserName='%{%k}' AND
UNIX_TIMESTAMP(AcctStartTime) + AcctSessionTime > '%b'"
}
sqlcounter monthlycounter {
counter-name = Monthly-Session-Time
check-name = Max-Monthly-Session
sqlmod-inst = sql
key = User-Name
reset = monthly
query = "SELECT SUM(AcctSessionTime - GREATEST
((%b - UNIX_TIMESTAMP(AcctStartTime)), 0))
FROM radacct WHERE UserName='%{%k}' AND
UNIX_TIMESTAMP(AcctStartTime) + AcctSessionTime > '%b'"
}
После этого в radiusd.conf включаем файл sqlcounter.conf в секции modules:
modules {
$INCLUDE ${confdir}/sqlcounter.conf
и включаем счётчик в секцию авторизации:
authorize {
...
noresetcounter
dailycounter
monthlycounter
}
После этого счётчик не будет давать проходить авторизацию пользователям,
исчерпавшим свой лимит времени. Для установления граничных значений
счётчиков используется таблица radcheck. Приведу некотрые примеры
использования этой таблицы:
1. Пользователь test1 может пользоваться нашими услугами 15 часов(54000 секунд),
тогда запись проверки данного пользователя должны выглядеть примерно так:
test1 Max-All-Session := 54000, User-Password == "<cut>"
Service-Type = Framed-User,
Framed-Protocol = PPP
Вносим AV пару Max-All-Session для пользователя так:
> INSERT into radcheck VALUES ('','test1','Max-All-Session',':=','54000');
Отметьте использование оператора :=. Таким образом атрибут Max-All-Session
будет приобретать значение по умолчанию 54000. Можно также устанавливать
пороги счетчика не для одного пользователя, а для группы - для этого
используется таблица radgroupcheck. В общем, основной смысл записей в
таблицах - установка значения атрибута, заданного в параметре счётчика
check-name. Ещё учтите, что модуль sqlcounter работает, только если данные
аккаунтинга направляются в sql.
Кроме sqlcounter есть ещё обыкновенный счётчик - counter. Его использование
очень похоже на sqlcounter, за исключением того, что обыкновенный счётчик
выполняет функции модуля аккаунтинга и авторизации одновременно. Я не буду
подробно останавливаться на этой теме по ряду причин. Желающие могут
прочитать в конфигурационном файле radiusd.conf подробные комментарии к
этому модулю.
Очень важным недостатком вышеописанных счётчиков является отсутствие
возможности кинуть пользователя о время сессии при исчерпании его активов.
Как было отмечено счётчики работают на этапе авторизации, но никто не
помешает пользователю, допустим, начать сессию и просидеть в день 24 часа
из положенных 3-х. На следующий день счётчик может сброситься, и
пользователь опять может пользоваться нашими услугами. Не думаю, что это
есть хорошо. Для решения этой проблемы используются различные биллинговые
системы, основанные на управлении NAS при помощи SNMP. Одним из решений
является использование отдельного сервера аккаунтинга(а затем настроить
соответствующим образом перенаправление пакетов аккаунтинга в файле
proxy.conf с помощью директивы accthost). Одним из таких серверов является
radacct (http://soft.risp.ru/index.html). Отличительной особенностью
является возможность работы с любым radius сервером(учтите, что radacct
не должен использовать тот же порт, что и radius сервер) и замечательная
документация на русском языке (http://soft.risp.ru/radacct/docs.shtml).
Сервер действительно рабочий и компилируется без проблем после ручной
правки Makefile(нужно раскомментировать строки, касающиеся вашей системы).
Т.к. radacct написан нашими программистами и имеет рускую документацию, то
описывать его в данной статье я не буду.
На этом можно было бы и завершить, но... Некоторые зададут совершенно
закономерный вопрос: "А что нам с этого, у меня вон
маршрутизатор в коробке лежит, а как его заставить с радиусом этим работать ?"
Что ж, вопрос закономерный, но это как раз одна из самых тривиальных частей
настройки. Для начала добавляем запись в clients.conf, соответствующую ip
адресу данного маршрутизатора и на последнем указываем параметры
радиус-сервера(учтите, что ключ симметрического шифрования aka secret
должны совпадать на маршрутизаторе и в файле clients.conf):
# configure terminal
# aaa new-model
# ip radius source-interface Ethernet0
# radius-server host {hostname | ip-address} [auth-port port-number]
[acct-port port-number] [timeout seconds] [retransmit retries] [key string]
# aaa authorization network radius
# aaa authorization exec radius
# aaa authentication login radius_auth local radius
# aaa authentication ppp ppp_auth radius
# line [console | tty | vty] line-number [ending-line-number]
(line)# login authentication radius_auth
(line)# exit
# interface async 6
(interface)# ppp authentication {chap | pap} ppp_auth
(interface)# exit
# aaa accounting network start-stop radius
# aaa accounting connection start-stop radius
# aaa accounting update periodic 1
Последняя директива определяет переодичность посылки пакетов аккаунтинга в
минутах.
Ну вот, собственно, и всё. Приведу список полезных сайтов:
http://www.freeradius.org - сайт одноимённого радиус-сервера, есть
интересные ссылки на другие ресурсы и списки рассылок.
http://www.cisco.com - поиск слова radius выдаёт жидковатенький список,
где, впрочем, есть весьма полезный документ "Configuring RADIUS Servers".
Здесь данная уважаемая фирма даёт свои рекоммендации по настройке своих
железок для работы с радиусом, а также свои соображения о применимости
радиуса в той или иной ситуации. Советую почитать всем сомневающимся.
http://soft.risp.ru/index.html - radacct сервер + много дополнительных
утилит для ISP.
ftp://ftp.inep.net/pub/unix/radpppd.tgz - pppd для FreeBSD с поддержкой radius.
http://sply.piter.net - ещё один патч для pppd для поддержки radius(в том
числе системы учёта).
http://www.google.com - STFW! Протокол молодой, поэтому инфу приходится
собирать с миру по нитке. Если вы ищете качественный коммерческий сервер,
то вам прямой путь сюда.
Всем, кто решил работать с радиусом, советую подписаться на рассылки (см.
http://www.freeradius.org), где очень много отзывчивых людей и, что меня удивило,
довольно много русских(хотя это не повод писать в рассылку по-русски :)
P.S. Данная статья написана в стиле HOWTO. Я не привожу готовых примеров
работы и не даю шаблонов для действия. Моя статья - попытка соединить
разрозненную документацию и собственный опыт. Искренне надеюсь, что мой
HOWTO поможет кому-нибудь в настройке своего radius сервера. Ещё
надеюсь, что кто-нибудь из администраторов ISP поделится готовым примером
работы radius.
Статья действительно хороша. Без воды! Но я ищу детали именно по аутентификации и авторизации с применением MS-CHAP2, о чем здесь проехали мимо. Проблема: получаю Request-пакеты с AV UserName(Code=1), MS-CHAP-Challenge (Code=26 Vendor=311 Type=11), MS-CHAP2-Response (Code=26 Vendor=311 Type=25). Известен UserPassword ClearText. Надо авторизовать user-а. Понимаю так: атрибут MS-CHAP-Challenge рассматривается в соответствии с RFC2759 как AuhtenticatorChallenge. PeerChallenge берем из AV MS_CHAP2-Response, имя и пароль юзера известны. Получаем свой NTResponse и сверяем его с NTResponse из AV MS_CHAP2-Rsponse. НЕ СХО-ДИТ-СЯ!!! Буду обязан каждому, кто скажет чего я не понимаю!
Удалось прикрутить аутентификацию по файлу shadow. Но не могу понять как настроить так, чтобы при входе по vty на Cisco выдавалось сообщение с просьбой сменить пароль. Может быть есть у кого-нибудь мысли?