Ключевые слова:aaa, auth, tacacs, cisco, (найти похожие документы)
From: Vsevolod Stakhov <cebka[at]jet[dot]msk[dot]su>
Date: Mon, 3 Jan 2006 14:31:37 +0000 (UTC)
Subject: Протокол аутентификации Tacacs
Оригинал: http://cebka.pp.ru/my/tacacs.txt
Статья впервые опубликована в журнале "Системный Администратор".
TACACS - это протокол аутентификации маршрутизаторов Cisco(далее я буду
называть эти приборы кисками, см. терминологию) на сервере.
В данной статье я опишу основные принципы настройки сервера и клиента TACACS+(плюс
указывает на версию протокола, которая используется в настоящее время).
TACACS имеет очень широкое применение, т.к. может обеспечивать работу всех
кисок с единым сервером авторизации, который также
позволяет устанавливать привилегии различных пользователей в широких
пределах, например, давать определённым пользователям доступ только к
определённым командам, давать пользователям пользоваться
определёнными сервисами только с заданных адресов, организовывать группы
пользователей, вести лог-файл доступа пользователей (это особенно важно для
маршрутизаторов, т.к. позволяет определить, какие пользователи и сколько
пользовались определёнными сетевыми службами: ppp, slip и.т.д.), выполнять
для пользователей определённые команды ОС. Но прежде чем начинать разговор
о настройке TACACS, я бы хотел определиться с терминологией:
"Киска" - продукт компании Cisco (http://www.cisco.com), в данном контексте
рассматриваются только маршрутизаторы (часть пунктов применима и для
коммутаторов)
TACACS (terminal access controller access control system) - собственно
система управления авторизацией и аутентификацией.
NAS (network access server) - клиент tacacs/radius - киска или иное
устройство, ведущее себя как NAS.
AV (attribute=value) - пары аттрибут=значение, которые передаются между
клиентом и сервером tacacs.
Теперь необходимо скачать сам сервер для *nix. Обитает он здесь:
ftp://ftpeng.cisco.com/pub/tacacs, к сожалению, только альфа-версия, но,
похоже, из состояния альфа он не выберется никогда, т.к. сама Cisco его не
поддерживает(что весьма странно) и отказывается от "любой ответственности".
Альфанутость tacacs_plus сервера мне довелось прочувствовать на собственной
шкуре: пришлось его маленько доработать для того, чтобы он начал выполнять
свою работу. Итак, вначале правим Makefile: по умолчанию раскомментированы
настройки для Solaris.
# For Solaris (SUNOS 5.3, 5.4, 5.5, 5.6) uncomment the following two lines
OS=-DSOLARIS
OSLIBS=-lsocket -lnsl
Выбираем нужную ОС и раскомментируем нужные строчки.
# For LINUX
OS=-DLINUX
#
# On REDHAT 5.0 systems, or systems that use the new glibc,
# you might instead need the following:
OS=-DLINUX -DGLIBC
OSLIBS=-lcrypt
Можно скомпилировать сервер с поддержкой ms-chap протокола. Если у вас есть
библиотека des, поддерживающая вызовы (у меня сработало с openssl):
int des_init();
void des_setkey();
void des_endes();
void des_done();
Для работы библиотеки необходимо соответствующим образом поправить
makefile. Если des библиотека не определена, то все вычисления проводятся
на NAS. Также в случае ms-chap вам потребуется какой-то непонятный ключ от
Microsoft, который я получать не стал.
# Microsoft CHAP extension support. See the user's guide for more
# information.
# MSCHAP = -DMSCHAP
# MSCHAP_DES = -DMSCHAP_DES
# MSCHAP_MD4_SRC = md4.c
Включаем поддержку возможности ограничения количества соединений на
пользователя
# Enforce a limit on maximum sessions per user. See the user's guide
# for more information.
MAXSESS = -DMAXSESS
Добавляем пользователя и группу для сервера, пишем в Makefile UID и GID(по
умолчанию эти строки закомментированы, запуск идёт от рута, что не есть
хорошо, особенно для альфа-версии):
USERID = 1500
GROUPID = 25
FLAGS = -DTAC_PLUS_USERID=$(USERID) -DTAC_PLUS_GROUPID=$(GROUPID)
Указываем pid файл:
# On startup, tac_plus creates the file /etc/tac_plus.pid (if
# possible), containing its process id. Uncomment and modify the
# following line to change this filename
PIDFILE = -DTAC_PLUS_PIDFILE=\"/var/run/tac_plus.pid\"
При компиляции у меня возникли ещё две проблемы:
* все сырцы были записаны в формате DOS, поэтому пришлось вначале написать
простенький скрипт:
#!/bin/sh
for i in *
do
tr -d "\r" < $i > .tmp
mv -f .tmp $i
rm -f .tmp
done
* возникли некоторые проблемы с описанием syserrorlist, которые, впрочем,
решаются просто удалением соответствующих строчек.
Решив эти две проблемы, я спокойно скомпилировал tacacs+ в NetBSD 1.5.2
компилятором egcc 1.1.2. Под Linux&gcc 2.96 всё также прошло нормально,
поэтому я не вижу причин, чтобы на других машинах возникали ошибки
компиляции(если возникли, то прежде всего проверьте Makefile).
Естественно, что после компиляции необходимо запустить и настроить сервер.
Запускается он так:
tac_plus
* -C имя конфигурационного файла(обязательный параметр)
* -t не использовать log файл, а писать в stderr
* -P проверка синтаксиса конфигурационного файла
* -g режим отладки, не происходит создания дочерних процессов
* -p port_number задание номера порта(по умолчанию tacacs+ использует 49 TCP)
* -d уровень вывода отладочных сообщений в /var/tmp/tac_plus.log
* -v вывести версию и выйти
* -L (получать имена по DNS)
* -l файл для ведения лога
* -w файл для записи журнала доступа (при включенной опции maxsess, по умолчанию
- /var/tmp/tac.who_log)
* -i запуск через inetd
Пример:
tac_plus -C /etc/tacacs.config
После пробного запуска заносим нужные строчки в системные rc файлы (хотя я
бы посоветовал для начала использовать режим inetd).
Но без конфигурационного файла сервер не работает, поэтому настало самое
время описать его синтаксис. Все значения записываются в формате
атрибут=значение (AV пары), если прописываются дополнительные параметры
атрибутов, то они заключаются в фигурные скобки {}, символы # считаются
началом однострочного комментария. Принцип построения конфигурационного
файла таков: вначале задаётся ключ симметрического шифрования,
осуществляемого между киской и tacacs сервером. Этот ключ имеет аналогичное
паролю значение (берётся его md5 хеш), поэтому он может содержать нормальные
символы (символ " употреблять нельзя, т.к. это приведёт к ошибке работы
шифрации, а экранировать его нет возможности). После определения ключа
описываются группы, в которых можно определить общие права и параметры
доступа всех пользователей в группе. Также обычно определяют пользователей,
входящих в определённые группы (пользователь может принадлежать только
одной группе). Для указания того, что пользователь или группа входят в
определённую группу в их описании необходимо использовать
member=group_name. Приведу всё это на примере:
# Ключ для шифрования
key = a very secret password
group users{
# Задание пароля для всех пользователей группы пользователей в
# открытом виде. Можно использовать DES шифрование, например,
# login = DES F5qT7Ha7AflP0 или указать файл в формате passwd:
# login = file /etc/tacacs_passwd, но учтите, что пока tac_plus не
# работает с md5 паролями, так что в этом файле все пароли должны
# быть зашифрованы методом DES
login = cleartext users_password
}
user user1{
# Пользователь принадлежит группе и наследует все параметры из
# определения группы, включая пароль
member = users
}
user power_user{
# Переопределение атрибута группы
login = des F5qT7Ha7AflP0
member = users
}
user lamer{
# А этот, видимо, и пароль ввести сам не может :)
login = nopassword
member = users
}
Важное замечание: если пароль указывается из файла(file path_to_file), то
необходимо преобразовать стандартный файл формата passwd в формат
tacacs(tacacs считает номер группы номером списка прав доступа - acl). Для
этого используется поставляемая утилита convert.pl -g <passwdfile>.
Группы tacacs могут являться членами других групп, наследуя все атрибуты
контейнера. Учтите что файл конфигурации tacacs содержит некоторые пароли в незашифрованном
виде, поэтому надо обязательно выполнить правильный chmod 0400 для пользователя, под
которым работает tacacs. Кроме этого, для аутентификации можно использовать несколько
дополнительных весьма полезных параметров:
* expires = "Month_short DD YYYY" - конец работы данной учётной записи.
Пользователь получает предупреждение за 14 дней до этой даты, например:
expires = "JAN 12 2003" (регистр не имеет значения, не забудьте про кавычки)
* maxsess - максимальное количество соединений для данного
пользователя(работает, если включена соответствующая опция Makefile).
* arap = cleartext arap_pass - пароль для arap
* chap = cleartext chap_pass - пароль для chap соединений(нельзя использовать шифрование)
* ms-chap = cleartext ms-chap_pass - пароль для ms-chap(если tacacs был
собран с поддержкой этого протокола), если не был "получен ms-chap ключ от
Microsoft", то работать можно только с cleartext паролями.
* pap = cleartext pap_pass - пароль для входящих pap
соединений, его можно шифровать DESom
* opap = cleartext opap_pass - пароль для исходящих pap соединений(работает
аналогично предыдущему).
В Cisco IOS также предусмотрен ряд специальных пользователей,
соответствующих уровням доступа к системе(enable), их имена выглядят
следующим образом: $enab<n>$, где <n> - требуемый уровень доступа к
системе(имеется также пользователь $enable$ для старых версий IOS).
Приведу простой пример всему вышесказанному(комментарии, думаю,
будут излишни):
user admin{
login = des FgZq2fY7ZKP0l
pap = des FgZq2fY7ZKP0l
opap = des FgZq2fY7ZKP0l
expires = "JAN 01 2010"
maxsess = 1
}
user user1{
login = cleartext user_pass
pap = pap_user_pass
expires = "JAN 01 2003"
}
user $enab15${
login = des Y7jk9zAd5F7Ix
}
user $enab1${
login = cleartext level1secret
}
Сродни процессу аутентификации на сервере tac_plus можно управлять
процессом авторизации, т.е. предоставления пользователям определённых прав
и запретов на использование команд или протоколов. Для определения прав
авторизации используются регулярные выражения стиля grep (точнее, egerp, что
позволяет использовать логические операции) и ключевые слова
permit(разрешить) и deny(запретить). По умолчанию всё, что не разрешено -
запрешено. Это можно изменить, указав разрешения по умолчанию:
* default authorization = permit - на глобальном уровне, разрешить все по умолчанию
* default service = permit - на уровне пользователя, разрешить все по умолчанию для данного пользователя
* default attribute = permit - на уровне описания сервиса разрешить всё по умолчанию
В процессе авторизации ключевыми являются три понятия: сервис(например,
сервисы exec, slip, ppp, arap, shell, tty-daemon, connection, system),
команда(например, telnet) и протокол. Приведу пример с комментариями:
user=admin {
login = des 3EdghJk8acVB6
member = administrators
# Разрешаем всё на уровне пользователя
default service = permit
# Описание сервиса выполнения команд exec
service = exec {
# Устанавливаем список прав доступа для данного пользователя
acl = 4
# Выполняем команду при авторизации(автокоманда)
autocmd = "telnet 192.168.1.2"
}
cmd = telnet {
# Разрешаем все telnet соединения, кроме адреса 131.108.13.*
deny 131\.108\.13\.[0-9]+
permit .*
}
}
user=alex {
login = des 6EX027bHtSTlz
name = "Alex"
member = administrators
expires = "May 23 2005"
arap = cleartext "arap secret"
chap = cleartext "chap secret"
service = exec {
# Список привеллегий по умолчанию
acl = 5
# Автопинг
autocmd = "ping 192.168.1.2"
}
}
В качестве команд могут использоваться любые команды ios обычного
режима(т.е. до enable). Список параметров, которые могут использоваться
внутри определений авторизации весьма широк:
* acl - список прав доступа(только при service=shell или service=exec)
* addr - сетевой адрес для service=ppp и protocol=ip
* autocmd - только при service=shell или service=exec - автоматическое
выполнение определённой команды ios
* callback-dialstring - номер телефона для service=ppp или shell
* callback-line - номер линии
* dns-server - IP-адреса серверов DNS через пробел, передаваемых клиентам PPP (service=ppp, protocol=ip)
* idletime (11.1) - время в минутах до завершения неактивной сессии (не применимо к PPP)
* inacl<n> - определяется входной уровень доступа и применяется к интерфейсу на время сеанса (service=ppp, protocol=ip)
* interface-config - значением является любая команда конфигурации интерфейса
* ip-addresses - возможные значения IP-адресов для конца тунеля (service=ppp and protocol=vpdn)
* link-compression - использовать ли алгоритм сжатия STAC
* 0 - нет
* 1 - Stac
* 2 - Stac-Draft-9
* 3 - MS-Stac
* load-threshold - порог нагрузки (от 1 до 255), после которого
добавляются/удаляются дополнительные линки в multilink bundle (service=ppp and protocol=multilink)
* max-links - максимальное число линков, которые пользовател может иметь в
multilink bundle (service=ppp and protocol=multilink)
* nas-password - пароль для NAS при аутентификации для L2F тунеля (service=ppp and protocol=vpdn)
* nocallback-verify - (всегда = 1). означает, что не требуется верификации при callback (service=arap, service=slip, service=ppp, service=shell)
* noescape - (true или false), запретить использовать символ прерывания ввода (service=shell.)
* nohangup - (true или false), запретить отключение пользователя по завершению
сеанса EXEC(service=shell).
* outacl<n> - определяется уровень доступа для исходящего соединения и применяется
к интерфейсу на время сеанса (service=ppp, protocol=ip)
* pool-def<n> - определить пул IP адресов
* pool-timeout - время на проверку существования указанного адресного пула на NAS
* ppp-vj-slot-compression - указание маршрутизатоту не использовать сжатие слотов
при посылке VJ-сжатых пакетов.
* priv-lvl - уровень привилегий, назначаемый процессу EXEC (0-15, 15 - наивысший)
* protocol - подмножество сервиса (в основном для ppp)
* lcp
* ip
* ipx
* atalk
* vines
* lat
* xremote
* tn3270
* telnet
* rlogin
* pad
* vpdn
* deccp
* osicp
* ccp (compression control protocol)
* cdp (cisco discovery protocol)
* bridging
* xns
* nbf
* bap
* multilink
* unknown
* route - определяет статический маршрут, применяемый к интерфейсу (service=ppp, protocol=ip).
Указывается в виде адреса назначения, маски подсети и (возможно) шлюза. Если шлюз опущен, то
через соседа (peer). По завершению сеанса маршрут удаляется.
* route<n> - аналогично route, но позволяет нумеровать маршруты и стало быть иметь их много.
* routing - (true или false) обрабатывать ли информацию о маршрутизации
* source-ip - задает исходный IP адрес VPDN пакетов (эквивалент команды: vpdn outgoing).
* timeout - максимальное время сессии в минутах (начиная с 11.3.8 - работает и для
service=ppp protocol=lcp, но выражается в секундах).
* tunnel-id - идентификатор туннеля vpdn (service=ppp and protocol=vpdn).
* wins-servers - IP-адреса серверов WINS (NetBIOS Name Service) через пробел, передаваемых
клиентам MS PPP (service=ppp, protocol=ip)
Здесь, думаю, какие-либо комментарии будут излишни, поэтому я перейду к
описанию скриптов авторизации. Tacacs может выполнять некоторые скрипты
shell до или после авторизации пользователя, для этого
используются директивы before authorization "/path/script paramlist" и
after authorization "..." соответственно(обратите внимание на наличие
кавычек и отсутствие знака "="). Скриптам инициализации могут быть переданы
любые параметры командной строки, но некоторые из них имеют специальное
назначение:
* $user - Имя пользователя
* $name - Имя клиента(NAS)
* $port - Порт клиента
* $address - Адрес клиента
* $priv - Уровень привеллегий(0 - 15)
* $method - Каким способом была пройдена аутентификация
* 1 - none
* 2 - KRB5 (kerberos, version 5)
* 3 - line (пароль, привязанный к линии)
* 4 - enable (команда изменения привилегий)
* 5 - local (в соответствии с локальной базой данных NAS)
* 6 - tacacs+
* 8 - guest (например, guest в ARAP)
* 16 - RADIUS
* 17 - KRB4 (kerberos, version 4)
* $type - Тип соединения
* 1 - ASCII
* 2 - PAP
* 3 - CHAP
* 4 - ARAP
* 5 - MS CHAP
* $service - Номер сервиса
* 1 - login
* 2 - enable
* 3 - ppp
* 4 - arap
* 5 - pt
* 6 - rcmd
* 7 - X25
* 8 - NASI
* 9 - FWPROXY
* $status - строка статуса работы соединения
* pass - успешное прохождение авторизации
* fail - провал соединения
* error- ошибка работы
* unknown
Указанный скрипт выполняется /bin/sh -c и должен быть составлен
соответствующим образом. При создании подобных скриптов учтите, что они
будут выполняться много раз для каждого пользователя, например, прохождение
авторизации ppp, lcp, ip и так далее. Скрипт авторизации может сообщать о
статусе работы через код завершения:
* 0 - всё нормально, авторизация разрешена
* 1 - произошла ошибка, авторизация запрещена
* 2 - авторизация разрешена, но на stdout скрипт кидает AV пары, которые
используются для дальнейшей авторизации(в обход настройкам tacacs), причём
если в выводе содержатся пробелы их необходимо экранировать кавычками.
* 3 - аналогично предыдущему, но авторизация запрещена.
Авторизационные скрипты - довольно полезная вещь, я, например, сделал
скрипт, работающий с mysql и исследующий пользователей, которые могут
заходить на определённый свитч. Скрипты выполняются под тем же
пользователем, что и tacacs сервер, поэтому запускать его от рута не
рекоммендуется(см. настройки Makefile). Приведу простой пример конфигурации
сервера с использованием скриптов:
group users{
# Путь к скрипту, выполняющемуся до авторизации на сервере
before authorization "/usr/libexec/tacacs/users_auth $user $name $address"
# Разрешаем сервисы по умолчанию
default service = permit
service = exec {
# Выполняем автопинг
autocmd = "ping 192.168.2.1"
}
}
Последняя вещь, которую бы я хотел рассказать о настройке сервера tacacs,
является установка учёта работы (accounting). Для начала работы системы учёта
достаточно добавить строку accounting file = "path_to_file" на глобальном
уровне:
accounting file = "/var/log/tacacs/accounting"
Формат данного файла различается от версии к версии, поэтому я не буду на
этом останавливаться подробно(думаю, понять что к чему будет нетрудно).
Состоит файл учёта из 5 полей(поля разделяются символами табуляции)
времени, имени NAS, имени пользователя, ключевого слова assync, признак
начала или окончания сессии - start и stop соответственно(особенно
интересна для учёта директива stop, на основании которой можно выполнять
учёт и контроль ошибок, иногда, в случае ошибки авторизации или
аутентификации, директива stop может не иметь пары start) и дополнительных
AV строк(для оценки PPP трафика интересны пары service=PPP
elapsed_time={время в секундах} а также bytes_in= и bytes_out=)
Теперь позвольте перейти к описанию настройки киски. Для начала стразу же
хочу предупредить, что к этому моменту необходимо иметь нормально
работающий tacacs сервер, иначе может случиться так, что вы не сможете
зайти на киску(при настройке tacacs сервера учтите тот факт, что по
умолчанию всё запрещено, поэтому не забудьте корректно настроить
авторизацию).
Заходим в CLI киски в режим EXEC(привеллигированный режим):
Устанавливаем сервер tacacs+ в name(имя или ip адрес)
# tacacs-server host {name}
Установка тайм-аута поиска сервера(по умолчанию 5 секунд)
# tacacs-server timeout {seconds}
Количество попыток логина на сервер
# tacacs-server attempts {count}
Ключ для шифрации трафика, должен совпадать со значением на сервере
# tacacs-server key {key}
Смотрим информацию о tacacs
# show tacacs
Далее настраиваем три а: аутентификацию, авторизацию и аккаунтинг.
# configure terminal
Включаем новую модель aaa
# aaa new-model
Глобальные настройки логина(список методов по степени возрастания, в моём
примере вначале ходим на tacacs сервер, а затем смотрим в локальные пароли)
# aaa authentication login default line
Настройка ppp логина
# aaa authentication ppp default tacacs+
Выбираем линию для настройки(список линий, могут быть специальные линии или
номера стандартных линий маршрутизатора)
# line {[aux, console, tty, vty]| line-numbers}
Список методов логина для линии
# login authentication tacacs+
# exit
Смотрим сделанные изменения
# show running-config
Настраиваем аутентификацию:
# configure terminal
Авторизация через tacacs всех сетевых служб(SLIP, PPP, NCP, ARA)
# aaa authorization network tacacs+
Авторизация через tacacs сервиса exec
# aaa authorization exec tacacs+
# exit
Настраиваем аккаунтинг:
# configure terminal
Запускаем аккаунтинг событий начала и конца для сервиса exec и сетевых
сервисов
# aaa accounting exec start-stop tacacs+
# aaa accounting network start-stop tacacs+
# exit
Можно также создать обратную связь(callback) между сервером и киской(это
полезно для получения некоторых параметров ppp). Для этого добавляем в
настройки aaa такие строчки:
# aaa authentication ppp pppcheck tacacs+
# int async {number_of_line}
# ppp authentication {chap | pap} pppcheck
# ppp callback accept
На сервере есть также дополнительные callback av пары, например:
user = foo{
login = cleartext login
chap = cleartext xfgb
pap = des qQkpO0AMIp7RL
opap = cleartext outgoing_pap
service = ppp protocol = lcp {
# Строка дозвона для расширений ppp lcp
callback-dialstring=123456
}
}
Но мне callback показался не очень нужным в практическом плане, поэтому
подробно о нём говорить я не буду.
Подводя итог, скажу, что использование tacacs мне лично показалось весьма
удобным и простым (за исключением некоторой нестабильности работы - иногда
мрут дочерние процессы, что, в принципе, не смертельно). За дополнительной
информацией о tacacs можете обратиться на следующие сайты:
http://www.bog.pp.ru/work/tacacs.html - на мой взгляд, наиболее
качественный ресурс по данной теме на русском языке(также здесь вы найдёте
уйму полезной инфы)
http://cisco.opennet.ru - отличная подборка материалов по cisco
http://ftpeng.cisco.com/pub/tacacs/ - отсюда качаем
http://www.easynet.de/tacacs-faq/ - FAQ на английском языке по tacacs
http://rcp.ru/faq/cisco.html - FAQ на русском языке по маршрутизаторам CISCO
http://stiwww.epfl.ch/tacacs/u_g_F403.html - родная документация на
английском языке
http://www.disaster.com/tacplus/ - подписка на список рассылок tacacs
ftp://ftp.vsu.ru/pub/hardware/cisco/tacacs - пропатченный отечественными
народными умельцами tacacs(добавлены новые библиотеки, работа с cron),
также имеется pppd, работающий через tacacs
http://www.nttacplus.com - tacacs+ для Win9x&WinNt. Демо-версия доступна
для скачивания, полная - только за американские президенты.