Читать далее...
Краткое описание реализации:
В качестве места хранения данных используется openldap, протокол - ldap+TLS, аутентификация/авторизация при входе в систему/получении sudo-прав происходит по паролям и открытым ключам
Используемое ПО:
- nss_ldap (ldap-бекенд для nsswitch.conf)
- pam_ldap (аутентификация и авторизация через ldap)
- openssh-portable с патчем LPK (аутентификация )
- pam_mkhomedir (создание домашней директории пользователя)
- openldap (реализация протокола ldap)
- sudo (авторизация через ldap)
Установка серверной части:
В первую очередь создадим CA (certification authority) для выдачи нужного нам для ldap сертификата(ов):
Для этого в базовой системе есть скрипт CA.pl (/usr/src/crypto/openssl/apps/CA.pl)
В принципе, он работает и out-of-box, однако для удобства можно сделать следующее:
- Исправить путь в $CATOP из скрипта на тот, где планируется держать файлы CA (а это несколько директорий)
- Исправить путь в секции Default_ca файла /etc/ssl/openssl.cnf
- Выставить предпочтительные параметры в секции req_distinguished_name (страну, город, etc..) для упрощения дальнейших выдач сертификатов
Для этого необходимо дописать примерно следующие строчки в openssl.cnf (на момент выдачи этого сертификата):
Приступим собственно к выдаче:
[ req ]
...
req_extensions = v3_req
[ v3_req ]
...
subjectAltName = @alt_names
[ alt_names ]
IP.1 =1.2.3.4
Создаем CA (инициализация дерева директорий, создание root-сертификата):
central# ./CA.pl -newcaТеперь в директории catest у нас есть root сертификат (cacert.pem) нашего CA, который мы будем выдавать сомневающимся^Wldap-клиентам
Show output..
CA certificate filename (or enter to create)
Making CA certificate ...
Generating a 1024 bit RSA private key
...............++++++
...........................................++++++
writing new private key to './cctest/private/cakey.pem'
Enter PEM pass phrase: somegoodpassword
Verifying - Enter PEM pass phrase: somegoodpassword
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [RU]:
State or Province Name (full name) [Moscow]:
Locality Name (eg, city) [Moscow]:
Organization Name (eg, company) [JSC Roga and Kopyta]:
Organizational Unit Name (eg, section) [Telecommunications]:
Common Name (eg, YOUR name) []:central.rogaandkopyta.ru
Email Address [tech@rogaandkopyta.ru]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/ssl/openssl.cnf
Enter pass phrase for ./cctest/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number:
ef:3d:cb:f2:46:2a:3f:96
Validity
Not Before: Jan 10 13:15:04 2009 GMT
Not After : Jan 9 13:15:04 2014 GMT
Subject:
countryName = RU
stateOrProvinceName = Moscow
organizationName = JSC Roga and Kopyta
organizationalUnitName = Telecommunications
commonName = central.rogaandkopyta.ru
emailAddress = tech@rogaandkopyta.ru
X509v3 extensions:
X509v3 Subject Key Identifier:
49:43:94:4F:16:D0:E7:01:DE:60:6D:98:C8:10:C6:25:7E:4E:77:C4
X509v3 Authority Key Identifier:
keyid:49:43:94:4F:16:D0:E7:01:DE:60:6D:98:C8:10:C6:25:7E:4E:77:C4
DirName:/C=RU/ST=Moscow/O=JSC Roga and Kopyta/OU=Telecommunications/CN=central.rogaandkopyta.ru/emailAddress=tech@rogaandkopyeta.ru
serial:EF:3D:CB:F2:46:2A:3F:96
X509v3 Basic Constraints:
CA:TRUE
Certificate is to be certified until Jan 9 13:15:04 2014 GMT (1825 days)
Write out database with 1 new entries
Data Base Updated
Осталось выдать сертификат (точнее, создать request и подписать его) собственно для ldap-сервера:
central# ./CA.pl -newreqВ результате мы получили следующие файлы:
Show output..
Generating a 1024 bit RSA private key
..++++++
.......++++++
writing new private key to 'newkey.pem'
Enter PEM pass phrase: sometemppassword
Verifying - Enter PEM pass phrase: sometemppassword
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [RU]:
State or Province Name (full name) [Moscow]:
Locality Name (eg, city) [Moscow]:
Organization Name (eg, company) [JSC Roga and Kopyta]:
Organizational Unit Name (eg, section) [Telecommunications]:
Common Name (eg, YOUR name) []:central.rogaandkopyta.ru
Email Address [tech@central.rogaandkopyta.ru]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Request is in newreq.pem, private key is in newkey.pem
central# ./CA.pl -sign
Show output..
Using configuration from /etc/ssl/openssl.cnf
Enter pass phrase for /root/catest/private/cakey.pem: somegoodpassword
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number:
ef:3d:cb:f2:46:2a:3f:95
Validity
Not Before: Jan 10 12:42:22 2009 GMT
Not After : Jan 10 12:42:22 2010 GMT
Subject:
countryName = RU
stateOrProvinceName = Moscow
localityName = Moscow
organizationName = JSC Roga and Kopyta
organizationalUnitName = Telecommunications
commonName = central.rogaandkopyta.ru
emailAddress = tech@central.rogaandkopyta.ru
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
9A:43:A5:87:9A:9E:3A:F2:D1:AB:02:2C:46:4E:FC:49:62:28:3F:FE
X509v3 Authority Key Identifier:
keyid:7F:D8:88:76:09:5F:30:98:81:22:38:BC:B3:55:5D:43:75:FC:B3:1F
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Subject Alternative Name:
IP Address:1.2.3.4
Certificate is to be certified until Jan 10 12:42:22 2010 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Signed certificate is in newcert.pem
- newcert.pem - это собственно сертификат, переименовываем например в central.pem
- newkey.pem - приватный ключ для сертификата
central# openssl rsa -in newkey.pem -out central_key.pem
Enter pass phrase for newkey.pem: sometemppassword
writing RSA key
В результате получился нужный нам ключ, не защищенный паролем. На этом часть, непосредственно связанную с openssl можно считать [успешно] законченной и переходить к установке/настройке openldap.
В серверной части нас больше всего интересует bdb бекенд(по умолчанию) и, возможно audit log и access log.
Устанавливаем:
make -C /usr/ports/net/openldap24-server/ install cleanНастраиваем /usr/local/etc/openldap/slapd.conf (например, копируя из /usr/local/etc/openldap/slapd.default). Здесь необходимо выбрать название домена, в котором все будет жить. В данном примере это dc=roga,dc=ru. Кроме того, необходимо придумать иерархию обьектов в дереве ldap. У автора используется следующая схема:
dc=roga,dc=ru - корень
ou=People - контейнер, в которой находятся все сотрудники
ou=Tech,ou=People - контейнер с эккаунтами технического отдела (обьекты живут именно тут)
ou=Groups - контейнер с posix группами (обьекты живут тут)
ou=SUDOers - контейнер с конфигурацией sudo (обьекты живут именно тут)
Пример конфига с комментариями:
#Поддерживаемые схемы (описания возможных типов обьектов и их взаимоотношений)
# Базовые
include /usr/local/etc/openldap/schema/core.schema
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/nis.schema
# Для поддержки открытых ключей, брать с http://openssh-lpk.googlecode.com/files/openssh-lpk_openldap.schema
include /usr/local/etc/openldap/schema/openssh-lpk_openldap.schema
# Ставится после пересобки sudo с LDAP (при первичной отладке лучше закомментировать)
include /usr/local/share/doc/sudo/schema.OpenLDAP
pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
modulepath /usr/local/libexec/openldap
moduleload back_bdb
# Разграничение доступа
access to dn.base="" by * read
access to dn.base="cn=Subschema" by * read
# Предоставляем доступ до хешированного пароля только специальному эккаунту (getpass)
access to attrs=userPassword
by self ssf=128 write
by dn.base="cn=getpass,ou=People,dc=roga,dc=ru" ssf=128 read
by anonymous ssf=128 auth
# Остальные данные читать может кто угодно
access to dn.sub="ou=People,dc=astel,dc=ru"
by * read
# Остальные данные читать может кто угодно
access to dn.sub="ou=Groups,dc=astel,dc=ru"
by * read
# Сами мы можем менять свой эккаунт (нпример, пароль)
access to *
by self write
by users read
by anonymous auth
# Настройки для работы SSL/TLS
TLSCipherSuite HIGH:MEDIUM:+SSLv2
TLSCACertificateFile /usr/local/etc/openldap/cacert.pem
TLSCertificateFile /usr/local/etc/openldap/central.pem
TLSCertificateKeyFile /usr/local/etc/openldap/central_key.pem
# Настройки стораджа для куска ldap-дерева, живущего под suffix
database bdb
suffix "dc=roga,dc=ru"
# DN (Distinguished name) рутового эккаунта, который может все
rootdn "cn=toor,dc=roga,dc=ru"
# Пароль (хеш), генерируется с помощью slappasswd
rootpw {SSHA}.....
directory /var/db/openldap-data
index objectClass,uid,uidNumber,gidNumber eq
echo slapd_enable=\"YES\" >> /etc/rc.confПробуем запустить (начать стоит именно с такого способа, т.к. скрипт запуска инициализирует директории из конфига перед запуском):
/usr/local/etc/rc.d/slapd startВ случае необходимости (возможные -d можно посмотреть в slapd.conf(5)):
/usr/local/libexec/slapd -h "ldap:// ldaps://" -u ldap -g ldap -d 256Для упрощения жизни на сервере с openldap дописываем откуда клиенту брать root сертификат для TLS:
echo TLS_CACERT /usr/local/etc/openldap/cacert.pem >> /usr/local/etc/openldap/ldap.confПосле того как slapd успешно запущен, необходимо добавить в него [придуманную раньше] структуру. Работа с сервером openldap производится утилитами ldapadd, ldapmodify и ldapsearch. Добавить обьекты из файла можно следующим образом:
ldapadd -xWZ -h-D cn=toor,dc=roga,dc=ru -f obj.ldif
(Hint: -x говорит не использовать sasl, -W спрашивает пароль, -Z включает TLS)
Пример obj.ldif для описанной выше структуры с группой и тестовым сотрудником:
# "Корень структуры"
dn: dc=roga,dc=ru
objectClass: dcObject
objectClass: organization
o: JSC Roga and Kopyta
dc: roga
dn: ou=People,dc=roga,dc=ru
description: Employees Accounts
objectClass: organizationalUnit
ou: People
dn: ou=Tech,ou=People,dc=roga,dc=ru
description: Tech people here
objectClass: organizationalUnit
ou: Tech
dn: ou=Groups,dc=roga,dc=ru
description: Unix groups OU
objectClass: organizationalUnit
ou: Groups
# Первая группа
dn: cn=tech_pd,ou=Groups,dc=roga,dc=ru
objectclass: top
objectclass: posixGroup
description: IP/services admins
cn: tech_pd
gidNumber: 10001
# эккаунт для непривилигированного хождения по лдапу
dn: cn=getnfo,ou=People,dc=roga,dc=ru
objectClass: top
objectClass: person
objectClass: organizationalPerson
description: Ldap Testovich
cn: getnfo
sn: getnfo
userPassword: {SSHA}securepass0
# эккаунт с возможностью прочитать хеш пароля (см. slapd.conf)
dn: cn=getpass,ou=People,dc=roga,dc=ru
objectClass: top
objectClass: person
objectClass: organizationalPerson
description: Ldap Testovich
cn: getpass
sn: getpass
userPassword: {SSHA}securepass1
# Первый тестовый сотрудник
dn: uid=vpupkin,ou=Tech,ou=People,dc=roga,dc=ru
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: posixAccount
objectclass: ldapPublicKey
description: Vasily V. Pupkin
userPassword: {SSHA}...
cn: Vasily V. Pupkin
sn: Vasily V. Pupkin
uid: vpupkin
uidNumber: 10001
gidNumber: 10001
homeDirectory: /home/vpupkin
loginShell: /bin/tcsh
sshPublicKey: ssh-rsa .....
Переход на централизованный sudo рассматривается после успешной конфигурации клиентской части, поэтому в данном .ldif нет обьектов sudo.
Если все прошло успешно, можно переходить к настройке клиентской части, которая значительно проще. Если нет - смотрим на ошибки, запускаем клиент/сервер с -vvv, дебагом, etc..
Клиентская часть:
Здесь все значительно проще и сводится к следующим вещам:
- [пере]установка портов с заданными опциями
- подкладывание новых конфигов ldap
- возможная схема группы, в которой должен состоять сотрудник для получения доступа
- изменение схемы работы pam для openssh/sudo
- изменение nsswitch.conf
- добавление бекапного эккаунта на случай отказа ldap
- вынос текущих эккаунтов
Конечно, всегда есть нюансы: например, в данном скрипте sshd переезжает в /usr/local и не конвертирует старый конфиг. Кроме того, необходимо будет перенести конфигурацию sudo в ldap (подробности ниже) и
Пример скрипта и краткое руководство:
Для реализации нам понадобится http сервер (напр. nginx):
Итак: собственно, скрипт и необходимые файлы
Клиентский конфиг с комментариями:
base dc=roga,dc=ru
uri ldap://1.2.3.4/
# "Обычный" DN (для "пользовательских" запросов)
binddn cn=getnfo,ou=People,dc=roga,dc=ru
bindpw secret
# привилегированный DN для запросов из-под root
rootbinddn cn=getpass,ou=People,dc=roga,dc=ru
# в случае недоступности сервера возвращаться сразу
bind_policy soft
# Если поставить persist, то из-за реализации защиты openssh необходимо будет выключать PrivilegeSeparation
nss_connect_policy oneshot
pam_filter objectclass=posixAccount
# Членство в этой группе требуется для получения доступа к серверу
pam_groupdn cn=tech_pd,ou=Groups,dc=roga,dc=ru
pam_min_uid 10000
pam_max_uid 20000
nss_base_passwd ou=People,dc=roga,dc=ru?sub
nss_base_shadow ou=People,dc=roga,dc=ru?sub
nss_base_group ou=Groups,dc=roga,dc=ru?one
# TLS включаем т.к. openssh-lpk не поддерживает SSL, а без него совсем несекьюрно
ssl start_tls
tls_cacertfile /usr/local/etc/openldap/cacert.pem
# Место, где лежат все обьекты с конфигурацией sudo
sudoers_base ou=SUDOers,dc=roga,dc=ru
В самом скрипте необходимо заменить
- URL на тот, по которому он доступен.
- заменить пароль в bindpw на securepass0
sed -i '' -e 's/dc=roga,dc=ru/dc=нужный,dc=домен/g' nss_ldap.confПосле чего запустить на первом сервере что-то типа fetch http:../pifpaf.sh && sh pifpaf.sh
sed -i '' -e 's/1.2.3.4/ldap.ip.addre.ss/g' nss_ldap.conf openldap.conf
Убедиться, что скрипт отработал корректно, возможно что-то подкорректировать под нужную конфигурацию и записать придуманный в серверный части serverpass1 в /usr/local/etc/nss_ldap.secret
Настройка sudo:
В данном примере будет рассматриваться тривиальная конфигурация, когда все члены определенной группы могут пользоваться sudo (т.е. аналог %wheel ALL=(ALL) ALL).
Более подробно об импорте конфигов можно почитать тут или в устанавливаемых sudo readme.
Итак, очередной .ldif (sudoers_base ou=SUDOers,dc=roga,dc=ru) уже указано в распостраненных nss_ldap.conf:
dn: ou=SUDOers,dc=roga,dc=ru
objectClass: top
objectClass: organizationalUnit
ou: SUDOers
# Эта группа может использовать sudo как угодно
dn: cn=%tech_pd,ou=SUDOers,dc=roga,dc=ru
objectClass: top
objectClass: sudoRole
cn: %tech_pd
sudoUser: %tech_pd
sudoHost: ALL
sudoCommand: ALL
# Осторожно! Этот обьект заставит sudo игнорировать локальный sudoers!
dn: cn=defaults,ou=SUDOers,dc=roga,dc=ru
objectClass: top
objectClass: sudoRole
cn: defaults
sudoOption: ignore_local_sudoers
Резюме:
Появилась единая точка аутентификации/авторизации для сотрудников, ходящих на сервера. Появилась возможность понемногу перетаскивать аунтентификацию остальных сервисов в LDAP. Исправления/дополнения/комментарии приветствуются
0 comments:
Post a Comment