LDAP Linux Auth: различия между версиями
Sirmax (обсуждение | вклад) (→SUDO) |
Sirmax (обсуждение | вклад) |
||
| (не показаны 104 промежуточные версии этого же участника) | |||
| Строка 1: | Строка 1: | ||
[[Категория:LDAP]] |
[[Категория:LDAP]] |
||
[[Категория:Linix]] |
[[Категория:Linix]] |
||
| + | [[Категория:HA]] |
||
| + | [[Категория:SSL]] |
||
[[Категория:Pam]] |
[[Категория:Pam]] |
||
| + | |||
| + | =Введение= |
||
| + | ==Соглашения и умолчания== |
||
| + | Везде в документе приняты следующие соглашения: |
||
| + | |||
| + | * пароль, если не указан - <B>r00tme</B> |
||
| + | * все пароли заведомо простые так как использовались для отладки. В реальной инсталляции рекомендую использовать более сложные пароли. |
||
| + | * изначально настройка не безопасна (используется "админская" учетная запись, и перенастройка на более безопасную конфигурацию описываетсяв отдельной секции. |
||
| + | * использование шифрования описывается в отдельной секции, изначальная настройка не использует шифрование. |
||
| + | * OS: Ubuntu 14.04 |
||
| + | * Вся настройка делается для конкретной цели и ОС установлена Fuel-ом (Base OS) для OpenStack и конфигурация может отличаться (незначительно) от обычной установки Ubuntu. |
||
| + | |||
| + | Для простоты и скорости работы я создаю алиасы для утилит, что бы не вписывать логин и пароль каждый раз. |
||
| + | <BR>По этой причине команды указаны БЕЗ пароля. |
||
| + | <PRE> |
||
| + | alias ldappasswd='ldappasswd -D "cn=admin,dc=fuel_domain" -w r00tme' |
||
| + | alias ldapsearch='ldapsearch -D "cn=admin,dc=fuel_domain" -w r00tme' |
||
| + | alias ldapmodify='ldapmodify -D "cn=admin,dc=fuel_domain" -w r00tme' |
||
| + | alias ldapadd='ldapadd -D "cn=admin,dc=fuel_domain" -w r00tme' |
||
| + | </PRE> |
||
| + | <BR>Если требуется ввести другой пароль то команда обычно предваряется символом <B>\</B> (unalias), например |
||
| + | <PRE> |
||
| + | \ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" |
||
| + | </PRE> |
||
| + | ==Репликация== |
||
| + | В моей инсталляции фигурируют 2 сервера, сначала настраивается 1 потом дополняется репликацией. |
||
| + | <BR> |
||
| + | Для простоты я использую алиасы через /etc/hosts |
||
| + | <PRE> |
||
| + | 10.20.0.6 ldap2 |
||
| + | 10.20.0.3 ldap1 |
||
| + | </PRE> |
||
| + | |||
| + | Прокси для Active-Backup конфигурации - на виртуальном IP который (не реализовано) будет перемещаться между нодами. (В примере - перенос осуществляется в ручном режиме) |
||
| + | <PRE> |
||
| + | 10.20.0.100 ldap |
||
| + | </PRE> |
||
| + | |||
| + | ==Запись сессии== |
||
| + | В статье встечаются ссылки на утилиту sudosh - это утилита для записи сессии пользователя. Отмечу что в моей конфигурации она установлена и используется, потому на нее иногда будут ссылки |
||
| + | |||
| + | * http://wiki.sirmax.noname.com.ua/index.php/Sudosh2 |
||
| + | |||
| + | <PRE> |
||
| + | dpkg -i <path>/sudosh2_2.0.1-1_amd64.deb |
||
| + | </PRE> |
||
| + | |||
| + | <PRE> |
||
| + | mkdir /var/log/sudosh; |
||
| + | chmod a+w /var/log/sudosh |
||
| + | chmod +r /etc/sudosh.conf |
||
| + | </PRE> |
||
=LDAP Server Installation= |
=LDAP Server Installation= |
||
| − | "Тихая" установка |
+ | "Тихая" установка (на ldap 1) |
<PRE> |
<PRE> |
||
DEBIAN_FRONTEND=noninteractive apt-get install slapd ldap-utils |
DEBIAN_FRONTEND=noninteractive apt-get install slapd ldap-utils |
||
</PRE> |
</PRE> |
||
| − | Современные дистрибутивы OpenLDAP используют сам LDAP как хранилище конфигурации. |
+ | Современные дистрибутивы OpenLDAP используют сам LDAP как хранилище конфигурации. <B>cn=config</B>. По-умолчанию настроен доступ без пароля для локального рута. |
<BR> |
<BR> |
||
| Строка 17: | Строка 71: | ||
ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" |
ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" |
||
</PRE> |
</PRE> |
||
| + | ==Create database== |
||
| − | |||
Создать отдельную базу данных для своих объектов. |
Создать отдельную базу данных для своих объектов. |
||
<BR> |
<BR> |
||
Внимательно проверить права на директорию - она должна существовать и быть доступна серверу на запись (/var/lib/ldap_fuel_domain/) |
Внимательно проверить права на директорию - она должна существовать и быть доступна серверу на запись (/var/lib/ldap_fuel_domain/) |
||
| + | |||
| + | <PRE> |
||
| + | 0002_createDatabase.ldif |
||
| + | </PRE> |
||
| + | |||
<PRE> |
<PRE> |
||
dn: olcDatabase={2}hdb,cn=config |
dn: olcDatabase={2}hdb,cn=config |
||
| Строка 46: | Строка 105: | ||
Изначально я даю полный доступ всем на все, изменю его позже. |
Изначально я даю полный доступ всем на все, изменю его позже. |
||
<BR> |
<BR> |
||
| + | |||
| − | Создание: (подключение через -H ldapi:/// в установке по умолчанию доступно руту без пароля. |
||
| + | В строке цифра 2 в строке <B>dn: olcDatabase={2}hdb,cn=config</B> обозначает что это 2-я база, ту что существует можно как удалить так и оставить "на потом" |
||
| − | <PRE> |
||
| + | |||
| − | ldapadd -Y EXTERNAL -H ldapi:/// < database |
||
| + | Создание: (подключение через <B>-H ldapi:///</B> в установке по умолчанию доступно руту без пароля. |
||
| − | SASL/EXTERNAL authentication started |
||
| + | <PRE> |
||
| − | SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth |
||
| + | mkdir -p /var/lib/ldap_fuel_domain/ |
||
| − | SASL SSF: 0 |
||
| + | chown openldap:openldap /var/lib/ldap_fuel_domain/ |
||
| + | </PRE> |
||
| + | |||
| + | <PRE> |
||
| + | ldapadd -Y EXTERNAL -H ldapi:/// < 0002_createDatabase.ldif |
||
| + | </PRE> |
||
| + | |||
| + | <PRE> |
||
adding new entry "olcDatabase={2}hdb,cn=config" |
adding new entry "olcDatabase={2}hdb,cn=config" |
||
</PRE> |
</PRE> |
||
| Строка 57: | Строка 124: | ||
Если права на директорию неправильные ИЛИ не настроен apparmor возникает ошибка: |
Если права на директорию неправильные ИЛИ не настроен apparmor возникает ошибка: |
||
<PRE> |
<PRE> |
||
| − | root@node-3:~/ldap# ldapadd -Y EXTERNAL -H ldapi:/// < database |
||
| − | SASL/EXTERNAL authentication started |
||
| − | SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth |
||
| − | SASL SSF: 0 |
||
adding new entry "olcDatabase={2}hdb,cn=config" |
adding new entry "olcDatabase={2}hdb,cn=config" |
||
ldap_add: Other (e.g., implementation specific) error (80) |
ldap_add: Other (e.g., implementation specific) error (80) |
||
additional info: olcDbDirectory: value #0: invalid path: Permission denied |
additional info: olcDbDirectory: value #0: invalid path: Permission denied |
||
</PRE> |
</PRE> |
||
| + | В логах: |
||
| + | <PRE> |
||
| + | apparmor="DENIED" operation="mknod" profile="/usr/sbin/slapd" name="/var/lib/ldap_fuel_domain/DUMMY" pid=26365 comm="slapd" requested_mask="c" denied_mask="c" fsuid=107 ouid=107 |
||
| + | </PRE> |
||
Исправить: |
Исправить: |
||
| + | |||
<PRE> |
<PRE> |
||
/etc/apparmor.d/usr.sbin.slapd |
/etc/apparmor.d/usr.sbin.slapd |
||
| + | </PRE> |
||
| − | |||
| + | <PRE> |
||
## |
## |
||
| + | /var/lib/ldap*/ rwk, |
||
/var/lib/ldap** rwk, |
/var/lib/ldap** rwk, |
||
</PRE> |
</PRE> |
||
| − | * http://ubuntuforums.org/showthread.php?t=1492043 |
||
| + | и перезапустить apparmor |
||
| + | <PRE> |
||
| + | /etc/init.d/apparmor restart |
||
| + | </PRE> |
||
| + | |||
| + | Some info: |
||
| + | * http://ubuntuforums.org/showthread.php?t=1492043 |
||
| + | |||
| + | ==Populate Database== |
||
Для работы создаем свой домен куда будем помещать все объекты. |
Для работы создаем свой домен куда будем помещать все объекты. |
||
* domain |
* domain |
||
<PRE> |
<PRE> |
||
| + | 0010_create_comain.ldiff |
||
| − | # fuel_domain |
||
| + | </PRE> |
||
| + | <PRE> |
||
dn: dc=fuel_domain |
dn: dc=fuel_domain |
||
objectClass: top |
objectClass: top |
||
| Строка 88: | Строка 168: | ||
* domain_admin |
* domain_admin |
||
<PRE> |
<PRE> |
||
| + | 0011_fuel_domain_admin.ldiff |
||
| − | # admin |
||
| + | </PRE> |
||
| + | <PRE> |
||
dn: cn=admin,dc=fuel_domain |
dn: cn=admin,dc=fuel_domain |
||
objectClass: simpleSecurityObject |
objectClass: simpleSecurityObject |
||
| Строка 100: | Строка 182: | ||
Загрузить объекты: |
Загрузить объекты: |
||
<PRE> |
<PRE> |
||
| − | ldapadd -Y EXTERNAL -H ldapi:/// < |
+ | ldapadd -Y EXTERNAL -H ldapi:/// < 0010_create_comain.ldiff |
| + | <PRE> |
||
| − | ldapadd -Y EXTERNAL -H ldapi:/// < domain_admin |
||
| + | <PRE> |
||
| + | adding new entry "dc=fuel_domain" |
||
| + | </PRE> |
||
| + | <PRE> |
||
| + | ldapadd -Y EXTERNAL -H ldapi:/// < 0011_fuel_domain_admin.ldiff |
||
| + | </PRE> |
||
| + | <PRE> |
||
| + | adding new entry "cn=admin,dc=fuel_domain" |
||
</PRE> |
</PRE> |
||
| + | ==Check connection== |
||
Проверить, подключившись с ново-созданным пользователем |
Проверить, подключившись с ново-созданным пользователем |
||
| + | |||
<PRE> |
<PRE> |
||
| − | ldapsearch -D "cn=admin,dc=fuel_domain" -w 'r00tme' -b 'dc=fuel_domain' '(objectclass=*)' |
+ | ldapsearch -LL -D "cn=admin,dc=fuel_domain" -w 'r00tme' -b 'dc=fuel_domain' '(objectclass=*)' |
</PRE> |
</PRE> |
||
| + | |||
* -D - "логин" |
* -D - "логин" |
||
* -w - пароль |
* -w - пароль |
||
| Строка 116: | Строка 209: | ||
<PRE> |
<PRE> |
||
| − | # extended LDIF |
||
| − | # |
||
| − | # LDAPv3 |
||
| − | # base <dc=fuel_domain> with scope subtree |
||
| − | # filter: (objectclass=*) |
||
| − | # requesting: ALL |
||
| − | # |
||
| − | |||
| − | # fuel_domain |
||
dn: dc=fuel_domain |
dn: dc=fuel_domain |
||
objectClass: top |
objectClass: top |
||
| Строка 132: | Строка 216: | ||
dc: fuel_domain |
dc: fuel_domain |
||
| − | # admin, fuel_domain |
||
dn: cn=admin,dc=fuel_domain |
dn: cn=admin,dc=fuel_domain |
||
objectClass: simpleSecurityObject |
objectClass: simpleSecurityObject |
||
| Строка 139: | Строка 222: | ||
description: LDAP administrator |
description: LDAP administrator |
||
userPassword:: e1NTSEF9YnhRcEZ6WW1Ja0lMU2JERUwzY1ZsK25mMDNtZHJhL3Q= |
userPassword:: e1NTSEF9YnhRcEZ6WW1Ja0lMU2JERUwzY1ZsK25mMDNtZHJhL3Q= |
||
| − | |||
| − | # search result |
||
| − | search: 2 |
||
| − | result: 0 Success |
||
| − | |||
| − | # numResponses: 3 |
||
| − | # numEntries: 2 |
||
</PRE> |
</PRE> |
||
| + | ==Fix permmissions== |
||
| − | |||
| − | Исправить права на базу |
+ | Исправить права на базу. |
| + | <PRE> |
||
| + | 0022_fix_database_permissions.ldif |
||
| + | </PRE> |
||
<PRE> |
<PRE> |
||
dn: olcDatabase={2}hdb,cn=config |
dn: olcDatabase={2}hdb,cn=config |
||
changetype: modify |
changetype: modify |
||
replace: olcAccess |
replace: olcAccess |
||
| − | olcAccess: {0}to |
+ | olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break |
| − | olcAccess: {1}to dn |
+ | olcAccess: {1}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=fuel_domain" write by * none |
| − | olcAccess: {2}to |
+ | olcAccess: {2}to dn.base="" by * read |
| + | olcAccess: {3}to * by dn="cn=admin,dc=fuel_domain" write by * read |
||
</PRE> |
</PRE> |
||
<PRE> |
<PRE> |
||
| − | ldapmodify -Y EXTERNAL -H ldapi:/// < |
+ | ldapmodify -Y EXTERNAL -H ldapi:/// < 0021_fix_database_permissions.ldif |
| + | </PRE> |
||
| − | SASL/EXTERNAL authentication started |
||
| + | <PRE> |
||
| − | SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth |
||
| − | SASL SSF: 0 |
||
modifying entry "olcDatabase={2}hdb,cn=config" |
modifying entry "olcDatabase={2}hdb,cn=config" |
||
</PRE> |
</PRE> |
||
| + | ==Download configuration and check it== |
||
Проверить права можно например скачав весь конфиг: |
Проверить права можно например скачав весь конфиг: |
||
<PRE> |
<PRE> |
||
ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" > all_config |
ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" > all_config |
||
</PRE> |
</PRE> |
||
| + | ==Результат== |
||
| + | |||
| + | На этом шаге - рабочий LDAP сервер с минимальными настройками и без шифрования. |
||
| + | |||
| + | =Шифрование= |
||
| + | Настройка шифрования вынесена на отдельную страницу |
||
| + | |||
| + | * http://wiki.sirmax.noname.com.ua/index.php/LDAP_Linux_LDAP_TLS |
||
| + | |||
| + | На данный момент настроено шифрование. |
||
| + | =Репликация= |
||
| + | Перед началом настройки репликации - настроить на обоих серверах шифрования. Конфигурация аналогичная за исключением сертификата и хостнейма |
||
| + | |||
| + | |||
| + | http://wiki.sirmax.noname.com.ua/index.php/LDAP_Linux_Replication |
||
=PHP LDAP Addmin= |
=PHP LDAP Addmin= |
||
| Строка 190: | Строка 285: | ||
</PRE> |
</PRE> |
||
| + | Если нужно шифрование то |
||
| − | =LDAP Configuration= |
||
| − | ==Aliases== |
||
| − | Для простоты я создаю алиасы что бы не вводить пароль каждый раз |
||
<PRE> |
<PRE> |
||
| + | apt-get install php5-sasl |
||
| − | alias ldapsearch='ldapsearch -D "cn=admin,dc=fuel_domain" -w r00tme' |
||
| − | alias ldapmodify='ldapmodify -D "cn=admin,dc=fuel_domain" -w r00tme' |
||
| − | alias ldapadd='ldapadd -D "cn=admin,dc=fuel_domain" -w r00tme' |
||
</PRE> |
</PRE> |
||
| + | И конфигурация будет выглядеть так: |
||
| + | <PRE> |
||
| + | $servers->setValue('server','host','ldaps://127.0.0.1:636'); |
||
| + | $servers->setValue('server','port',0); |
||
| + | </PRE> |
||
| + | В файле /etc/ldap/ldap.conf должны быть правильные настройки |
||
| + | <PRE> |
||
| + | TLS_CACERT /etc/ssl/certs/rootca.crt |
||
| + | TLS_REQCERT allow |
||
| + | TIMELIMIT 15 |
||
| + | TIMEOUT 20 |
||
| + | </PRE> |
||
| + | =Populate LDAP= |
||
| − | |||
| + | ==Customers_Organization== |
||
| − | ==Organization== |
||
| + | Контейнер для всех остальных объектов |
||
| − | Добавить организацию |
||
| + | <PRE> |
||
| − | Обратить внимание - <B>dn: dc=customer_organization,dc=fuel_domain</B> - порядок важен. dc В КОТОРЫЙ добавляется должен быть последним. |
||
| + | 0000_Customers_Organization |
||
| + | </PRE> |
||
<PRE> |
<PRE> |
||
| − | # 04_customer_organization |
||
dn: dc=customer_organization,dc=fuel_domain |
dn: dc=customer_organization,dc=fuel_domain |
||
dc: customer_organization |
dc: customer_organization |
||
| Строка 213: | Строка 317: | ||
objectClass: organization |
objectClass: organization |
||
</PRE> |
</PRE> |
||
| + | |||
| − | Добавить организацию: |
||
| + | ==Groups== |
||
| + | Контейнер для групп и для пользователей. |
||
<PRE> |
<PRE> |
||
| + | 0001_Groups |
||
| − | ldapadd < 04_customer_organization |
||
</PRE> |
</PRE> |
||
| − | Результат: |
||
<PRE> |
<PRE> |
||
| + | dn: ou=Group,dc=customer_organization,dc=fuel_domain |
||
| − | ldapadd < 04_customer_organization |
||
| + | ou: Group |
||
| − | adding new entry "dc=customer_organization,dc=fue_domain" |
||
| − | ldap_add: Server is unwilling to perform (53) |
||
| − | additional info: no global superior knowledge |
||
| − | |||
| − | root@node-3:~/ldap# ldapadd < 04_customer_organization |
||
| − | adding new entry "dc=customer_organization,dc=fuel_domain" |
||
| − | </PRE> |
||
| − | |||
| − | |||
| − | ==Manager Role== |
||
| − | <PRE> |
||
| − | # 05_manager |
||
| − | dn: cn=Manager,dc=customer_organization,dc=fuel_domain |
||
| − | cn: Manager |
||
| − | description: LDAP administrator |
||
| − | objectClass: organizationalRole |
||
objectClass: top |
objectClass: top |
||
| + | objectClass: organizationalUnit |
||
| − | roleOccupant: dc=customer_organization,dc=fuel_domain |
||
| − | </PRE> |
||
| − | <PRE> |
||
| − | ldapadd < 05_manager |
||
| − | adding new entry "cn=Manager,dc=customer_organization,dc=fuel_domain" |
||
| − | </PRE> |
||
| − | |||
| − | ==Organization Units People and Groups== |
||
| − | <PRE> |
||
| − | # 06_people |
||
dn: ou=People,dc=customer_organization,dc=fuel_domain |
dn: ou=People,dc=customer_organization,dc=fuel_domain |
||
ou: People |
ou: People |
||
| Строка 254: | Строка 335: | ||
</PRE> |
</PRE> |
||
| + | ==User sirmax (мой пользователь)== |
||
| + | Первый пользователь и его группа, который сможет логиниться на ноды. |
||
<PRE> |
<PRE> |
||
| + | 0002_User_sirmax |
||
| − | # 07_groups |
||
| − | dn: ou=Group,dc=customer_organization,dc=fuel_domain |
||
| − | ou: Group |
||
| − | objectClass: top |
||
| − | objectClass: organizationalUnit |
||
| − | </PRE> |
||
| − | |||
| − | <PRE> |
||
| − | ldapadd < 06_people |
||
| − | adding new entry "ou=People,dc=customer_organization,dc=fuel_domain" |
||
| − | |||
| − | root@node-3:~/ldap# ldapadd < 07_groups |
||
| − | adding new entry "ou=Group,dc=customer_organization,dc=fuel_domain" |
||
</PRE> |
</PRE> |
||
| − | ==Users== |
||
| − | Добавить пользователя. Обратить внимание - пароль такой же как в /etc/shadow <BR>(Как его генерировать я не знаю пока) |
||
<PRE> |
<PRE> |
||
dn: uid=sirmax,ou=People,dc=customer_organization,dc=fuel_domain |
dn: uid=sirmax,ou=People,dc=customer_organization,dc=fuel_domain |
||
| Строка 290: | Строка 359: | ||
userPassword: {CRYPT}$6$DS/mzad5$EB.cNCLE7KB7OCPK1nU6aEA8HnQDLY1FPd3KaWPVqaNBtWhmh/4cOUgD1I8tQSFu41yy7jMXDrg9TDqlAbuLX. |
userPassword: {CRYPT}$6$DS/mzad5$EB.cNCLE7KB7OCPK1nU6aEA8HnQDLY1FPd3KaWPVqaNBtWhmh/4cOUgD1I8tQSFu41yy7jMXDrg9TDqlAbuLX. |
||
labeledURI: http://wiki.sirmax.noname.com.ua/ |
labeledURI: http://wiki.sirmax.noname.com.ua/ |
||
| − | loginShell: /bin/ |
+ | loginShell: /usr/bin/sudosh |
uidNumber: 9999 |
uidNumber: 9999 |
||
gidNumber: 9999 |
gidNumber: 9999 |
||
| − | homeDirectory: /home/sirmax |
+ | homeDirectory: /home/sirmax |
| − | description: This is |
+ | description: This is me :) |
| − | </PRE> |
||
| − | <PRE> |
||
| − | ldapadd < 08_user1 |
||
| − | adding new entry "uid=sirmax,ou=People,dc=customer_organization,dc=fuel_domain" |
||
| − | </PRE> |
||
| + | dn: cn=sirmax,ou=Group,dc=customer_organization,dc=fuel_domain |
||
| − | ==Groups== |
||
| − | 2 группы |
||
| − | * группа пользователя |
||
| − | * группа fuel_users |
||
| − | |||
| − | <PRE> |
||
| − | dn: cn=sirmax,ou=Group,dc=example_organization,dc=fuel |
||
changetype: add |
changetype: add |
||
| − | cn: |
+ | cn: sirmax |
objectClass: posixGroup |
objectClass: posixGroup |
||
gidNumber: 9999 |
gidNumber: 9999 |
||
description: Fuel Users |
description: Fuel Users |
||
memberUid: sirmax |
memberUid: sirmax |
||
| + | </PRE> |
||
| + | |||
| + | ==Group Fuel_Users== |
||
| + | Группа пользователей которая используется для <b>sudo</b> |
||
| + | <PRE> |
||
| + | 0004_GroupFuelUsers |
||
</PRE> |
</PRE> |
||
<PRE> |
<PRE> |
||
| − | dn: cn=fuel_users,ou=Group,dc= |
+ | dn: cn=fuel_users,ou=Group,dc=customer_organization,dc=fuel_domain |
changetype: add |
changetype: add |
||
| − | cn: |
+ | cn: fuel_users |
objectClass: posixGroup |
objectClass: posixGroup |
||
gidNumber: 109999 |
gidNumber: 109999 |
||
| Строка 327: | Строка 391: | ||
</PRE> |
</PRE> |
||
| + | ==ServiceOU and Sudoers== |
||
| − | Добавить: |
||
| + | |||
| + | Создать контейнеры для сервисных объектов и поместить в него контейнер для sudo. |
||
| + | |||
| + | |||
<PRE> |
<PRE> |
||
| + | 0005_ServiceOU_and_Sudoers |
||
| − | ldapadd < 09_group_for_user1 |
||
| + | </PRE> |
||
| − | adding new entry "cn=sirmax,ou=Group,dc=customer_organization,dc=fuel_domain" |
||
| + | <PRE> |
||
| − | ldapadd < 10_group_fuel_users |
||
| − | + | dn: ou=services,dc=customer_organization,dc=fuel_domain |
|
| + | ou: Services |
||
| + | objectClass: top |
||
| + | objectClass: organizationalUnit |
||
| + | description: Group all services under this OU |
||
| + | dn: ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain |
||
| + | objectClass: organizationalUnit |
||
| + | description: sudo |
||
| + | objectClass: top |
||
</PRE> |
</PRE> |
||
| − | =Настройка клиента= |
||
| − | http://wiki.sirmax.noname.com.ua/index.php/LDAP_Linux_Auth_Client |
||
| + | ==ServieUsersOU== |
||
| − | =Запись сессии= |
||
| + | Контейнер для служебных пользователей |
||
| − | Для записи сессии используем утилиту sudosh2 |
||
| + | <PRE> |
||
| + | 0006_ServieUsersOU |
||
| + | </PRE> |
||
| + | <PRE> |
||
| − | * http://wiki.sirmax.noname.com.ua/index.php/Sudosh2 |
||
| + | dn: ou=service_users,dc=customer_organization,dc=fuel_domain |
||
| + | ou: service_users |
||
| + | objectClass: top |
||
| + | objectClass: organizationalUnit |
||
| + | </PRE> |
||
| + | ==nssproxy_group== |
||
| + | Группа для служебных пользователей, пользователям этой группы будет разрешено читать хеши пароля и пользователи этой группы используются для nss, pam и ldap-sudo |
||
<PRE> |
<PRE> |
||
| + | 0007_nssproxy_group |
||
| − | dpkg -i <path>/sudosh2_2.0.1-1_amd64.deb |
||
</PRE> |
</PRE> |
||
<PRE> |
<PRE> |
||
| + | dn: cn=nssproxy,ou=Group,dc=customer_organization,dc=fuel_domain |
||
| − | mkdir /var/log/sudosh; |
||
| + | cn: nssproxy |
||
| − | chmod a+w /var/log/sudosh |
||
| + | objectClass: groupOfNames |
||
| − | chmod +r /etc/sudosh.conf |
||
| + | objectClass: top |
||
| + | member: uid=nssproxy-node1,ou=service_users,dc=customer_organization,dc=fuel_domain |
||
| + | member: uid=nssproxy-node2,ou=service_users,dc=customer_organization,dc=fuel_domain |
||
| + | member: uid=nssproxy-node3,ou=service_users,dc=customer_organization,dc=fuel_domain |
||
| + | member: uid=nssproxy-node4,ou=service_users,dc=customer_organization,dc=fuel_domain |
||
</PRE> |
</PRE> |
||
| + | |||
| + | ==0008_nssProxyUsers== |
||
| + | |||
| + | Служебные пользователи (4 по числу серверов) |
||
<PRE> |
<PRE> |
||
| + | 0008_nssProxyUsers |
||
| + | </PRE> |
||
| + | <PRE> |
||
| + | dn: uid=nssproxy-node1,ou=service_users,dc=customer_organization,dc=fuel_domain |
||
| + | uid: nssproxy-node1 |
||
| + | gecos: Network Service Switch Proxy User |
||
| + | objectClass: top |
||
| + | #objectClass: account |
||
| + | objectClass: posixAccount |
||
| + | objectClass: shadowAccount |
||
| + | objectClass: organizationalPerson |
||
| + | objectClass: inetOrgPerson |
||
| + | userPassword: {SSHA}RsAMqOI3647qg1gAZF3x2BKBnp0sEVfa |
||
| + | cn: node1 |
||
| + | sn: node1 |
||
| + | shadowLastChange: 15140 |
||
| + | shadowMin: 0 |
||
| + | shadowMax: 99999 |
||
| + | shadowWarning: 7 |
||
| + | loginShell: /bin/false |
||
| + | uidNumber: 801 |
||
| + | gidNumber: 801 |
||
| + | homeDirectory: /home/nssproxy |
||
| + | |||
| + | |||
| + | dn: uid=nssproxy-node2,ou=service_users,dc=customer_organization,dc=fuel_domain |
||
| + | uid: nssproxy-node2 |
||
| + | gecos: Network Service Switch Proxy User |
||
| + | objectClass: top |
||
| + | #objectClass: account |
||
| + | objectClass: posixAccount |
||
| + | objectClass: shadowAccount |
||
| + | objectClass: organizationalPerson |
||
| + | objectClass: inetOrgPerson |
||
| + | userPassword: {SSHA}RsAMqOI3647qg1gAZF3x2BKBnp0sEVfa |
||
| + | cn: node2 |
||
| + | sn: node2 |
||
| + | shadowLastChange: 15140 |
||
| + | shadowMin: 0 |
||
| + | shadowMax: 99999 |
||
| + | shadowWarning: 7 |
||
| + | loginShell: /bin/false |
||
| + | uidNumber: 802 |
||
| + | gidNumber: 801 |
||
| + | homeDirectory: /home/nssproxy |
||
| + | |||
| + | |||
| + | dn: uid=nssproxy-node3,ou=service_users,dc=customer_organization,dc=fuel_domain |
||
| + | uid: nssproxy-node3 |
||
| + | gecos: Network Service Switch Proxy User |
||
| + | objectClass: top |
||
| + | #objectClass: account |
||
| + | objectClass: posixAccount |
||
| + | objectClass: shadowAccount |
||
| + | objectClass: organizationalPerson |
||
| + | objectClass: inetOrgPerson |
||
| + | userPassword: {SSHA}RsAMqOI3647qg1gAZF3x2BKBnp0sEVfa |
||
| + | cn: node3 |
||
| + | sn: node3 |
||
| + | shadowLastChange: 15140 |
||
| + | shadowMin: 0 |
||
| + | shadowMax: 99999 |
||
| + | shadowWarning: 7 |
||
| + | loginShell: /bin/false |
||
| + | uidNumber: 803 |
||
| + | gidNumber: 801 |
||
| + | homeDirectory: /home/nssproxy |
||
| + | |||
| + | |||
| + | dn: uid=nssproxy-node4,ou=service_users,dc=customer_organization,dc=fuel_domain |
||
| + | uid: nssproxy-node4 |
||
| + | gecos: Network Service Switch Proxy User |
||
| + | objectClass: top |
||
| + | #objectClass: account |
||
| + | objectClass: posixAccount |
||
| + | objectClass: shadowAccount |
||
| + | objectClass: organizationalPerson |
||
| + | objectClass: inetOrgPerson |
||
| + | userPassword: {SSHA}RsAMqOI3647qg1gAZF3x2BKBnp0sEVfa |
||
| + | cn: node4 |
||
| + | sn: node4 |
||
| + | shadowLastChange: 15140 |
||
| + | shadowMin: 0 |
||
| + | shadowMax: 99999 |
||
| + | shadowWarning: 7 |
||
| + | loginShell: /bin/false |
||
| + | uidNumber: 804 |
||
| + | gidNumber: 801 |
||
| + | homeDirectory: /home/nssproxy |
||
</PRE> |
</PRE> |
||
| + | |||
| − | =SUDO= |
||
| + | == Fix Permissions: Alow NSS Read Passwords== |
||
| − | Добавить разрешения в файл sudoers |
||
| + | Добавляем группе nss права на чтение паролей/хешей паролей |
||
| − | <BR>/etc/sudoers |
||
| + | |||
<PRE> |
<PRE> |
||
| + | 0009_FixPermissionsAlowNSSReadPAsswords.ldif |
||
| − | %fuel_users ALL=(ALL:ALL) ALL |
||
| + | </PRE> |
||
| + | <PRE> |
||
| + | dn: olcDatabase={2}hdb,cn=config |
||
| + | changetype: modify |
||
| + | replace: olcAccess |
||
| + | olcAccess: {0}to * |
||
| + | by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage |
||
| + | by * break |
||
| + | olcAccess: {1}to attrs=userPassword,shadowLastChange |
||
| + | by self write |
||
| + | by anonymous auth |
||
| + | by dn="cn=admin,dc=fuel_domain" write. |
||
| + | by group.exact="cn=nssproxy,ou=Group,dc=customer_organization,dc=fuel_domain" read |
||
| + | by * none |
||
| + | olcAccess: {2}to dn.subtree="ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain" |
||
| + | by dn="cn=admin,dc=fuel_domain" write. |
||
| + | by group.exact="cn=nssproxy,ou=Group,dc=customer_organization,dc=fuel_domain" read |
||
| + | by anonymous auth |
||
| + | by * none |
||
| + | olcAccess: {3}to dn.base="" |
||
| + | by * read |
||
| + | olcAccess: {4}to * |
||
| + | by dn="cn=admin,dc=fuel_domain" write |
||
| + | by * read |
||
| + | </PRE> |
||
| + | Вносить исправление через ldapi:/// |
||
| + | <PRE> |
||
| + | ldapmodify -Y EXTERNAL -H ldapi:/// < 0009_FixPermissionsAlowNSSReadPAsswords.ldif |
||
</PRE> |
</PRE> |
||
| + | ==Sudo Scheme== |
||
| + | Cхема для sudo (как ее генерировать описано в отдельном разделе) |
||
| + | <PRE> |
||
| − | Подробно про sudo: https://wiki.archlinux.org/index.php/Sudo_%28%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9%29 |
||
| + | 0010_SudoScheme.ldif |
||
| + | </PRE> |
||
| + | <PRE> |
||
| + | dn: cn=sudo,cn=schema,cn=config |
||
| + | objectClass: olcSchemaConfig |
||
| + | cn: sudo |
||
| + | olcAttributeTypes: {0}( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) |
||
| + | olcAttributeTypes: {1}( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) |
||
| + | olcAttributeTypes: {2}( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Command(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) |
||
| + | olcAttributeTypes: {3}( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(s)impersonated by sudo (deprecated)' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) |
||
| + | olcAttributeTypes: {4}( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Options(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) |
||
| + | olcAttributeTypes: {5}( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'User(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) |
||
| + | olcAttributeTypes: {6}( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Group(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) |
||
| + | olcAttributeTypes: {7}( 1.3.6.1.4.1.15953.9.1.8 NAME 'sudoNotBefore' DESC 'Start of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 ) |
||
| + | olcAttributeTypes: {8}( 1.3.6.1.4.1.15953.9.1.9 NAME 'sudoNotAfter' DESC 'End of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 ) |
||
| + | olcAttributeTypes: {9}( 1.3.6.1.4.1.15953.9.1.10 NAME 'sudoOrder' DESC 'an integer to order the sudoRole entries' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ) |
||
| + | olcObjectClasses: {0}( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' DESC 'Sudoer Entries' SUP top STRUCTURAL MUST cn MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotBefore $ sudoNotAfter $ description ) ) |
||
| + | </PRE> |
||
| + | ==Sudoers== |
||
| + | Файл sudoers (как его генерировать описано в отдельном разделе) |
||
| + | <PRE> |
||
| + | 0010_sudoers.ldif |
||
| + | </PRE> |
||
| + | |||
| + | <PRE> |
||
| + | dn: cn=defaults,ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain |
||
| + | objectClass: top |
||
| + | objectClass: sudoRole |
||
| + | cn: defaults |
||
| + | description: Default sudoOption's go here |
||
| + | sudoOption: env_reset |
||
| + | sudoOption: mail_badpass |
||
| + | sudoOption: secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" |
||
| + | sudoOrder: 1 |
||
| + | |||
| + | dn: cn=root,ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain |
||
| + | objectClass: top |
||
| + | objectClass: sudoRole |
||
| + | cn: root |
||
| + | sudoUser: root |
||
| + | sudoHost: ALL |
||
| + | sudoRunAsUser: ALL |
||
| + | sudoRunAsGroup: ALL |
||
| + | sudoCommand: ALL |
||
| + | sudoOrder: 2 |
||
| + | |||
| + | dn: cn=%admin,ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain |
||
| + | objectClass: top |
||
| + | objectClass: sudoRole |
||
| + | cn: %admin |
||
| + | sudoUser: %admin |
||
| + | sudoHost: ALL |
||
| + | sudoRunAsUser: ALL |
||
| + | sudoCommand: ALL |
||
| + | sudoOrder: 3 |
||
| + | |||
| + | dn: cn=%sudo,ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain |
||
| + | objectClass: top |
||
| + | objectClass: sudoRole |
||
| + | cn: %sudo |
||
| + | sudoUser: %sudo |
||
| + | sudoHost: ALL |
||
| + | sudoRunAsUser: ALL |
||
| + | sudoRunAsGroup: ALL |
||
| + | sudoCommand: ALL |
||
| + | sudoOrder: 4 |
||
| + | |||
| + | dn: cn=%fuel_users,ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain |
||
| + | objectClass: top |
||
| + | objectClass: sudoRole |
||
| + | cn: %fuel_users |
||
| + | sudoUser: %fuel_users |
||
| + | sudoHost: ALL |
||
| + | sudoRunAsUser: ALL |
||
| + | sudoRunAsGroup: ALL |
||
| + | sudoCommand: ALL |
||
| + | sudoOrder: 5 |
||
| + | </PRE> |
||
| + | |||
| + | ==Сброс паролей для служебных пользователей== |
||
| + | |||
| + | Пароли всем пользователям ставлю (для теста) - по номеру ноды, например для node-1 пользователь будет nssproxy-node1 с паролем '1111' |
||
| + | |||
| + | <PRE> |
||
| + | 0011_setPaswordsAndCheck.sh |
||
| + | </PRE> |
||
| + | |||
| + | <PRE> |
||
| + | for N in `seq 1 4` |
||
| + | do |
||
| + | echo user=nssproxy-node${N} |
||
| + | ldappasswd -H ldaps://ldap -s ${N}${N}${N}${N} uid=nssproxy-node${N},ou=service_users,dc=customer_organization,dc=fuel_domain -D "cn=admin,dc=fuel_domain" -w 'r00tme' |
||
| + | |||
| + | ldapsearch -D "uid=nssproxy-node${N},ou=service_users,dc=customer_organization,dc=fuel_domain" -w ${N}${N}${N}${N} -b 'dc=fuel_domain' -H ldaps://ldap '(objectclass=*)' |
||
| + | done |
||
| + | </PRE> |
||
| + | |||
| + | ==Test user== |
||
| + | Пользователь который добавляется для демонстрации - изначально не имеет прав sudo. |
||
| + | |||
| + | <PRE> |
||
| + | 9902_User_test_user |
||
| + | </PRE> |
||
| + | |||
| + | <PRE> |
||
| + | dn: uid=test1,ou=People,dc=customer_organization,dc=fuel_domain |
||
| + | objectClass: top |
||
| + | objectClass: person |
||
| + | objectClass: organizationalPerson |
||
| + | objectClass: inetOrgPerson |
||
| + | objectClass: posixAccount |
||
| + | objectClass: shadowAccount |
||
| + | uid: test1 |
||
| + | cn: test1 test1 |
||
| + | sn: test1 |
||
| + | givenName: test1 |
||
| + | title: test user for demo |
||
| + | telephoneNumber: +38 067 341 80 70 |
||
| + | mobile: +38 067 341 80 70 |
||
| + | postalAddress: AddressLine1$AddressLine2$AddressLine3 |
||
| + | userPassword: {CRYPT}$6$DS/mzad5$EB.cNCLE7KB7OCPK1nU6aEA8HnQDLY1FPd3KaWPVqaNBtWhmh/4cOUgD1I8tQSFu41yy7jMXDrg9TDqlAbuLX. |
||
| + | labeledURI: http://wiki.test1.noname.com.ua/ |
||
| + | loginShell: /usr/bin/sudosh |
||
| + | uidNumber: 9998 |
||
| + | gidNumber: 9998 |
||
| + | homeDirectory: /home/test1 |
||
| + | description: This is me :) |
||
| + | |||
| + | |||
| + | dn: cn=test1,ou=Group,dc=customer_organization,dc=fuel_domain |
||
| + | changetype: add |
||
| + | cn: test1 |
||
| + | objectClass: posixGroup |
||
| + | gidNumber: 9998 |
||
| + | description: Fuel Users |
||
| + | memberUid: test1 |
||
| + | </PRE> |
||
| + | |||
| + | =Настройка клиента= |
||
| + | Вынесено в отдельный документ: |
||
| + | |||
| + | http://wiki.sirmax.noname.com.ua/index.php/LDAP_Linux_Auth_Client |
||
| + | |||
| + | =SUDO= |
||
| + | http://wiki.sirmax.noname.com.ua/index.php/LDAP_Linux_LDAP_SUDO |
||
=Ссылки= |
=Ссылки= |
||
* ВВедение в PAM https://www.ibm.com/developerworks/ru/library/l-pam/ |
* ВВедение в PAM https://www.ibm.com/developerworks/ru/library/l-pam/ |
||
Текущая версия на 15:49, 30 мая 2016
Введение
Соглашения и умолчания
Везде в документе приняты следующие соглашения:
- пароль, если не указан - r00tme
- все пароли заведомо простые так как использовались для отладки. В реальной инсталляции рекомендую использовать более сложные пароли.
- изначально настройка не безопасна (используется "админская" учетная запись, и перенастройка на более безопасную конфигурацию описываетсяв отдельной секции.
- использование шифрования описывается в отдельной секции, изначальная настройка не использует шифрование.
- OS: Ubuntu 14.04
- Вся настройка делается для конкретной цели и ОС установлена Fuel-ом (Base OS) для OpenStack и конфигурация может отличаться (незначительно) от обычной установки Ubuntu.
Для простоты и скорости работы я создаю алиасы для утилит, что бы не вписывать логин и пароль каждый раз.
По этой причине команды указаны БЕЗ пароля.
alias ldappasswd='ldappasswd -D "cn=admin,dc=fuel_domain" -w r00tme' alias ldapsearch='ldapsearch -D "cn=admin,dc=fuel_domain" -w r00tme' alias ldapmodify='ldapmodify -D "cn=admin,dc=fuel_domain" -w r00tme' alias ldapadd='ldapadd -D "cn=admin,dc=fuel_domain" -w r00tme'
Если требуется ввести другой пароль то команда обычно предваряется символом \ (unalias), например
\ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config"
Репликация
В моей инсталляции фигурируют 2 сервера, сначала настраивается 1 потом дополняется репликацией.
Для простоты я использую алиасы через /etc/hosts
10.20.0.6 ldap2 10.20.0.3 ldap1
Прокси для Active-Backup конфигурации - на виртуальном IP который (не реализовано) будет перемещаться между нодами. (В примере - перенос осуществляется в ручном режиме)
10.20.0.100 ldap
Запись сессии
В статье встечаются ссылки на утилиту sudosh - это утилита для записи сессии пользователя. Отмечу что в моей конфигурации она установлена и используется, потому на нее иногда будут ссылки
dpkg -i <path>/sudosh2_2.0.1-1_amd64.deb
mkdir /var/log/sudosh; chmod a+w /var/log/sudosh chmod +r /etc/sudosh.conf
LDAP Server Installation
"Тихая" установка (на ldap 1)
DEBIAN_FRONTEND=noninteractive apt-get install slapd ldap-utils
Современные дистрибутивы OpenLDAP используют сам LDAP как хранилище конфигурации. cn=config. По-умолчанию настроен доступ без пароля для локального рута.
Посмотреть содержимое можно так:
ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config"
Create database
Создать отдельную базу данных для своих объектов.
Внимательно проверить права на директорию - она должна существовать и быть доступна серверу на запись (/var/lib/ldap_fuel_domain/)
0002_createDatabase.ldif
dn: olcDatabase={2}hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {2}hdb
olcDbDirectory: /var/lib/ldap_fuel_domain/
olcSuffix: dc=fuel_domain
olcAccess: {0}to * by * write
olcLastMod: TRUE
olcRootDN: cn=admin,dc=fuel_domain
olcRootPW: {SSHA}bxQpFzYmIkILSbDEL3cVl+nf03mdra/t
olcDbCheckpoint: 512 30
olcDbConfig: {0}set_cachesize 0 2097152 0
olcDbConfig: {1}set_lk_max_objects 1500
olcDbConfig: {2}set_lk_max_locks 1500
olcDbConfig: {3}set_lk_max_lockers 1500
olcDbIndex: objectClass eq
Обратить внимание на
olcAccess: {0}to * by * write
Изначально я даю полный доступ всем на все, изменю его позже.
В строке цифра 2 в строке dn: olcDatabase={2}hdb,cn=config обозначает что это 2-я база, ту что существует можно как удалить так и оставить "на потом"
Создание: (подключение через -H ldapi:/// в установке по умолчанию доступно руту без пароля.
mkdir -p /var/lib/ldap_fuel_domain/ chown openldap:openldap /var/lib/ldap_fuel_domain/
ldapadd -Y EXTERNAL -H ldapi:/// < 0002_createDatabase.ldif
adding new entry "olcDatabase={2}hdb,cn=config"
Если права на директорию неправильные ИЛИ не настроен apparmor возникает ошибка:
adding new entry "olcDatabase={2}hdb,cn=config"
ldap_add: Other (e.g., implementation specific) error (80)
additional info: olcDbDirectory: value #0: invalid path: Permission denied
В логах:
apparmor="DENIED" operation="mknod" profile="/usr/sbin/slapd" name="/var/lib/ldap_fuel_domain/DUMMY" pid=26365 comm="slapd" requested_mask="c" denied_mask="c" fsuid=107 ouid=107
Исправить:
/etc/apparmor.d/usr.sbin.slapd
## /var/lib/ldap*/ rwk, /var/lib/ldap** rwk,
и перезапустить apparmor
/etc/init.d/apparmor restart
Some info:
Populate Database
Для работы создаем свой домен куда будем помещать все объекты.
- domain
0010_create_comain.ldiff
dn: dc=fuel_domain objectClass: top objectClass: dcObject objectClass: organization o: fuel_users
- domain_admin
0011_fuel_domain_admin.ldiff
dn: cn=admin,dc=fuel_domain
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword: {SSHA}bxQpFzYmIkILSbDEL3cVl+nf03mdra/t
Пароль пользователя генерируется утилитой ldappasswd, в моем примере это 'r00tme'
Загрузить объекты:
ldapadd -Y EXTERNAL -H ldapi:/// < 0010_create_comain.ldiff <PRE> <PRE> adding new entry "dc=fuel_domain"
ldapadd -Y EXTERNAL -H ldapi:/// < 0011_fuel_domain_admin.ldiff
adding new entry "cn=admin,dc=fuel_domain"
Check connection
Проверить, подключившись с ново-созданным пользователем
ldapsearch -LL -D "cn=admin,dc=fuel_domain" -w 'r00tme' -b 'dc=fuel_domain' '(objectclass=*)'
- -D - "логин"
- -w - пароль
- -b - base, ветка дерева в которой искать
- '(objectclass=*)' - "что искать", в примере - "все"
Результат поиска:
dn: dc=fuel_domain objectClass: top objectClass: dcObject objectClass: organization o: fuel_users dc: fuel_domain dn: cn=admin,dc=fuel_domain objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin description: LDAP administrator userPassword:: e1NTSEF9YnhRcEZ6WW1Ja0lMU2JERUwzY1ZsK25mMDNtZHJhL3Q=
Fix permmissions
Исправить права на базу.
0022_fix_database_permissions.ldif
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break
olcAccess: {1}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=fuel_domain" write by * none
olcAccess: {2}to dn.base="" by * read
olcAccess: {3}to * by dn="cn=admin,dc=fuel_domain" write by * read
ldapmodify -Y EXTERNAL -H ldapi:/// < 0021_fix_database_permissions.ldif
modifying entry "olcDatabase={2}hdb,cn=config"
Download configuration and check it
Проверить права можно например скачав весь конфиг:
ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" > all_config
Результат
На этом шаге - рабочий LDAP сервер с минимальными настройками и без шифрования.
Шифрование
Настройка шифрования вынесена на отдельную страницу
На данный момент настроено шифрование.
Репликация
Перед началом настройки репликации - настроить на обоих серверах шифрования. Конфигурация аналогичная за исключением сертификата и хостнейма
http://wiki.sirmax.noname.com.ua/index.php/LDAP_Linux_Replication
PHP LDAP Addmin
Опционально можно поставить phpldapadmin
apt-get install phpldapadmin
Настройки минимальны и ограничиваются указанием домена пользователя
diff /etc/phpldapadmin/config.php /etc/phpldapadmin/config.php.original
300c300
< $servers->setValue('server','base',array('dc=fuel_domain'));
---
> $servers->setValue('server','base',array('dc=example,dc=com'));
326c326
< $servers->setValue('login','bind_id','cn=admin,dc=fuel_domain');
---
> $servers->setValue('login','bind_id','cn=admin,dc=example,dc=com');
Если нужно шифрование то
apt-get install php5-sasl
И конфигурация будет выглядеть так:
$servers->setValue('server','host','ldaps://127.0.0.1:636');
$servers->setValue('server','port',0);
В файле /etc/ldap/ldap.conf должны быть правильные настройки
TLS_CACERT /etc/ssl/certs/rootca.crt TLS_REQCERT allow TIMELIMIT 15 TIMEOUT 20
Populate LDAP
Customers_Organization
Контейнер для всех остальных объектов
0000_Customers_Organization
dn: dc=customer_organization,dc=fuel_domain dc: customer_organization o: Example Organization objectClass: dcObject objectClass: organization
Groups
Контейнер для групп и для пользователей.
0001_Groups
dn: ou=Group,dc=customer_organization,dc=fuel_domain ou: Group objectClass: top objectClass: organizationalUnit dn: ou=People,dc=customer_organization,dc=fuel_domain ou: People objectClass: top objectClass: organizationalUnit
User sirmax (мой пользователь)
Первый пользователь и его группа, который сможет логиниться на ноды.
0002_User_sirmax
dn: uid=sirmax,ou=People,dc=customer_organization,dc=fuel_domain
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: sirmax
cn: Max Mazur
sn: Mazur
givenName: Mazur
title: Max Mazur
telephoneNumber: +38 067 341 80 70
mobile: +38 067 341 80 70
postalAddress: AddressLine1$AddressLine2$AddressLine3
userPassword: {CRYPT}$6$DS/mzad5$EB.cNCLE7KB7OCPK1nU6aEA8HnQDLY1FPd3KaWPVqaNBtWhmh/4cOUgD1I8tQSFu41yy7jMXDrg9TDqlAbuLX.
labeledURI: http://wiki.sirmax.noname.com.ua/
loginShell: /usr/bin/sudosh
uidNumber: 9999
gidNumber: 9999
homeDirectory: /home/sirmax
description: This is me :)
dn: cn=sirmax,ou=Group,dc=customer_organization,dc=fuel_domain
changetype: add
cn: sirmax
objectClass: posixGroup
gidNumber: 9999
description: Fuel Users
memberUid: sirmax
Group Fuel_Users
Группа пользователей которая используется для sudo
0004_GroupFuelUsers
dn: cn=fuel_users,ou=Group,dc=customer_organization,dc=fuel_domain changetype: add cn: fuel_users objectClass: posixGroup gidNumber: 109999 description: Fuel Users memberUid: sirmax
ServiceOU and Sudoers
Создать контейнеры для сервисных объектов и поместить в него контейнер для sudo.
0005_ServiceOU_and_Sudoers
dn: ou=services,dc=customer_organization,dc=fuel_domain ou: Services objectClass: top objectClass: organizationalUnit description: Group all services under this OU dn: ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain objectClass: organizationalUnit description: sudo objectClass: top
ServieUsersOU
Контейнер для служебных пользователей
0006_ServieUsersOU
dn: ou=service_users,dc=customer_organization,dc=fuel_domain ou: service_users objectClass: top objectClass: organizationalUnit
nssproxy_group
Группа для служебных пользователей, пользователям этой группы будет разрешено читать хеши пароля и пользователи этой группы используются для nss, pam и ldap-sudo
0007_nssproxy_group
dn: cn=nssproxy,ou=Group,dc=customer_organization,dc=fuel_domain cn: nssproxy objectClass: groupOfNames objectClass: top member: uid=nssproxy-node1,ou=service_users,dc=customer_organization,dc=fuel_domain member: uid=nssproxy-node2,ou=service_users,dc=customer_organization,dc=fuel_domain member: uid=nssproxy-node3,ou=service_users,dc=customer_organization,dc=fuel_domain member: uid=nssproxy-node4,ou=service_users,dc=customer_organization,dc=fuel_domain
0008_nssProxyUsers
Служебные пользователи (4 по числу серверов)
0008_nssProxyUsers
dn: uid=nssproxy-node1,ou=service_users,dc=customer_organization,dc=fuel_domain
uid: nssproxy-node1
gecos: Network Service Switch Proxy User
objectClass: top
#objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
objectClass: organizationalPerson
objectClass: inetOrgPerson
userPassword: {SSHA}RsAMqOI3647qg1gAZF3x2BKBnp0sEVfa
cn: node1
sn: node1
shadowLastChange: 15140
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/false
uidNumber: 801
gidNumber: 801
homeDirectory: /home/nssproxy
dn: uid=nssproxy-node2,ou=service_users,dc=customer_organization,dc=fuel_domain
uid: nssproxy-node2
gecos: Network Service Switch Proxy User
objectClass: top
#objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
objectClass: organizationalPerson
objectClass: inetOrgPerson
userPassword: {SSHA}RsAMqOI3647qg1gAZF3x2BKBnp0sEVfa
cn: node2
sn: node2
shadowLastChange: 15140
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/false
uidNumber: 802
gidNumber: 801
homeDirectory: /home/nssproxy
dn: uid=nssproxy-node3,ou=service_users,dc=customer_organization,dc=fuel_domain
uid: nssproxy-node3
gecos: Network Service Switch Proxy User
objectClass: top
#objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
objectClass: organizationalPerson
objectClass: inetOrgPerson
userPassword: {SSHA}RsAMqOI3647qg1gAZF3x2BKBnp0sEVfa
cn: node3
sn: node3
shadowLastChange: 15140
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/false
uidNumber: 803
gidNumber: 801
homeDirectory: /home/nssproxy
dn: uid=nssproxy-node4,ou=service_users,dc=customer_organization,dc=fuel_domain
uid: nssproxy-node4
gecos: Network Service Switch Proxy User
objectClass: top
#objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
objectClass: organizationalPerson
objectClass: inetOrgPerson
userPassword: {SSHA}RsAMqOI3647qg1gAZF3x2BKBnp0sEVfa
cn: node4
sn: node4
shadowLastChange: 15140
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/false
uidNumber: 804
gidNumber: 801
homeDirectory: /home/nssproxy
Fix Permissions: Alow NSS Read Passwords
Добавляем группе nss права на чтение паролей/хешей паролей
0009_FixPermissionsAlowNSSReadPAsswords.ldif
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to *
by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
by * break
olcAccess: {1}to attrs=userPassword,shadowLastChange
by self write
by anonymous auth
by dn="cn=admin,dc=fuel_domain" write.
by group.exact="cn=nssproxy,ou=Group,dc=customer_organization,dc=fuel_domain" read
by * none
olcAccess: {2}to dn.subtree="ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain"
by dn="cn=admin,dc=fuel_domain" write.
by group.exact="cn=nssproxy,ou=Group,dc=customer_organization,dc=fuel_domain" read
by anonymous auth
by * none
olcAccess: {3}to dn.base=""
by * read
olcAccess: {4}to *
by dn="cn=admin,dc=fuel_domain" write
by * read
Вносить исправление через ldapi:///
ldapmodify -Y EXTERNAL -H ldapi:/// < 0009_FixPermissionsAlowNSSReadPAsswords.ldif
Sudo Scheme
Cхема для sudo (как ее генерировать описано в отдельном разделе)
0010_SudoScheme.ldif
dn: cn=sudo,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: sudo
olcAttributeTypes: {0}( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {1}( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {2}( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Command(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {3}( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(s)impersonated by sudo (deprecated)' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {4}( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Options(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {5}( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'User(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {6}( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Group(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {7}( 1.3.6.1.4.1.15953.9.1.8 NAME 'sudoNotBefore' DESC 'Start of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
olcAttributeTypes: {8}( 1.3.6.1.4.1.15953.9.1.9 NAME 'sudoNotAfter' DESC 'End of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
olcAttributeTypes: {9}( 1.3.6.1.4.1.15953.9.1.10 NAME 'sudoOrder' DESC 'an integer to order the sudoRole entries' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
olcObjectClasses: {0}( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' DESC 'Sudoer Entries' SUP top STRUCTURAL MUST cn MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotBefore $ sudoNotAfter $ description ) )
Sudoers
Файл sudoers (как его генерировать описано в отдельном разделе)
0010_sudoers.ldif
dn: cn=defaults,ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain objectClass: top objectClass: sudoRole cn: defaults description: Default sudoOption's go here sudoOption: env_reset sudoOption: mail_badpass sudoOption: secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" sudoOrder: 1 dn: cn=root,ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain objectClass: top objectClass: sudoRole cn: root sudoUser: root sudoHost: ALL sudoRunAsUser: ALL sudoRunAsGroup: ALL sudoCommand: ALL sudoOrder: 2 dn: cn=%admin,ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain objectClass: top objectClass: sudoRole cn: %admin sudoUser: %admin sudoHost: ALL sudoRunAsUser: ALL sudoCommand: ALL sudoOrder: 3 dn: cn=%sudo,ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain objectClass: top objectClass: sudoRole cn: %sudo sudoUser: %sudo sudoHost: ALL sudoRunAsUser: ALL sudoRunAsGroup: ALL sudoCommand: ALL sudoOrder: 4 dn: cn=%fuel_users,ou=sudo,ou=services,dc=customer_organization,dc=fuel_domain objectClass: top objectClass: sudoRole cn: %fuel_users sudoUser: %fuel_users sudoHost: ALL sudoRunAsUser: ALL sudoRunAsGroup: ALL sudoCommand: ALL sudoOrder: 5
Сброс паролей для служебных пользователей
Пароли всем пользователям ставлю (для теста) - по номеру ноды, например для node-1 пользователь будет nssproxy-node1 с паролем '1111'
0011_setPaswordsAndCheck.sh
for N in `seq 1 4`
do
echo user=nssproxy-node${N}
ldappasswd -H ldaps://ldap -s ${N}${N}${N}${N} uid=nssproxy-node${N},ou=service_users,dc=customer_organization,dc=fuel_domain -D "cn=admin,dc=fuel_domain" -w 'r00tme'
ldapsearch -D "uid=nssproxy-node${N},ou=service_users,dc=customer_organization,dc=fuel_domain" -w ${N}${N}${N}${N} -b 'dc=fuel_domain' -H ldaps://ldap '(objectclass=*)'
done
Test user
Пользователь который добавляется для демонстрации - изначально не имеет прав sudo.
9902_User_test_user
dn: uid=test1,ou=People,dc=customer_organization,dc=fuel_domain
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: test1
cn: test1 test1
sn: test1
givenName: test1
title: test user for demo
telephoneNumber: +38 067 341 80 70
mobile: +38 067 341 80 70
postalAddress: AddressLine1$AddressLine2$AddressLine3
userPassword: {CRYPT}$6$DS/mzad5$EB.cNCLE7KB7OCPK1nU6aEA8HnQDLY1FPd3KaWPVqaNBtWhmh/4cOUgD1I8tQSFu41yy7jMXDrg9TDqlAbuLX.
labeledURI: http://wiki.test1.noname.com.ua/
loginShell: /usr/bin/sudosh
uidNumber: 9998
gidNumber: 9998
homeDirectory: /home/test1
description: This is me :)
dn: cn=test1,ou=Group,dc=customer_organization,dc=fuel_domain
changetype: add
cn: test1
objectClass: posixGroup
gidNumber: 9998
description: Fuel Users
memberUid: test1
Настройка клиента
Вынесено в отдельный документ:
http://wiki.sirmax.noname.com.ua/index.php/LDAP_Linux_Auth_Client
SUDO
http://wiki.sirmax.noname.com.ua/index.php/LDAP_Linux_LDAP_SUDO
Ссылки
- ВВедение в PAM https://www.ibm.com/developerworks/ru/library/l-pam/
PAM
PAM vs NSS
http://serverfault.com/questions/538383/understand-pam-and-nss
http://pro-ldap.ru/tr/zytrax/ch6/slapd-config.html
https://wiki.archlinux.org/index.php/LDAP_authentication
RUS
http://www.bog.pp.ru/work/LDAP.html
http://pro-ldap.ru/tr/zytrax/ch6/slapd-config.html
http://xgu.ru/wiki/man:ldapmodify
https://rtfm.co.ua/openldap-migraciya-s-slapd-conf-na-cnconfig-olc/
http://www.slashroot.in/how-are-passwords-stored-linux-understanding-hashing-shadow-utils