Содержание

openldap

OpenLDAP: https://github.com/osixia/docker-openldap
Админка: https://github.com/osixia/docker-phpLDAPadmin

Установка

---
services:
  openldap:
    image: osixia/openldap
    container_name: openldap
    hostname: openldap.workgroup.test
    ports:
#      - 389:389
      - 636:636
    volumes:
#      - ./data/schema:/tmp/schema # Для расширения схемы
      - ./data/ldap:/var/lib/ldap
      - ./data/slapd:/etc/ldap/slapd.d
    environment:
#      LDAP_SEED_INTERNAL_SCHEMA_PATH: "/tmp/schema" # Для расширения схемы
      LDAP_ORGANISATION: "Test LDAP"
      LDAP_DOMAIN: "workgroup.test"
      LDAP_ADMIN_USERNAME: "admin"
      LDAP_ADMIN_PASSWORD: "123456Qwerty"
      LDAP_CONFIG_PASSWORD: "123456Config"
      LDAP_BASE_DN: "dc=workgroup,dc=test"
      LDAP_READONLY_USER: "true"
      LDAP_READONLY_USER_USERNAME: "ro_user"
      LDAP_READONLY_USER_PASSWORD: "ro_pass"
      LDAP_TLS_VERIFY_CLIENT: "try" # Prevent client TLS errors

  phpldapadmin:
    image: osixia/phpldapadmin
    container_name: phpldapadmin
    hostname: phpldapadmin
    ports:
      - 6443:443
    environment:
      PHPLDAPADMIN_LDAP_HOSTS: "openldap"
      PHPLDAPADMIN_LDAP_CLIENT_TLS_REQCERT: "never" # Prevent client TLS errors
#      PHPLDAPADMIN_HTTPS: "false"
    depends_on:
      - openldap

networks:
  default:
    name: openldap

Использование

Вход в админку по dn (distinguishedName):

cn=admin,dc=workgroup,dc=test
P@ssw0rd

CLI

# Поиск с использованием read-only юзера
ldapsearch -x -H ldaps://openldap.workgroup.test -d "dc=workgroup,dc=test" -D "cn=ro_user,dc=workgroup,dc=test" -w ro_pass |grep uid:
uid: vpupkin
uid: pmokin

Генерация паролей (slappasswd)

docker exec openldap slappasswd -s P@ssw0rd123
{SSHA}HpBbHxfqUowX5f9VZYq1DZ0oGYnwM4X1

Импорт пользователей

# Список ФИО (как пример)
Import-Html https://www.hse.ru/science/scifund/bonus2012-1 # сохранить в CSV
 
# Сделать ldif (pwdReset не работает: attribute type undefined)
$fios = (Import-Csv 'C:\temp\Список ФИО.csv' -Delimiter ';').p2
 
$c = 1100
$ldif = foreach ($fio in $fios) {
$login = Get-Login $fio
"dn: cn=$login,cn=users,dc=workgroup,dc=test
uid: $login
cn: $login
givenName: $($fio -replace '^\w+\s')
sn: $($fio.Split()[0])
uidNumber: $c
gidNumber: 500
homeDirectory: /home/users/$login
loginShell: /usr/bin/bash
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
userPassword: {SSHA}hgNEx6EhrM7LD4uXRGMsfNFyKctjz+rd
#pwdReset: TRUE
"
$c++
}
 
$ldif |Set-Clipboard
 
# Далее вставить в файл users.ldif в Линуксе

Пример пользователя в файле

dn: cn=abramovrn,cn=users,dc=workgroup,dc=test
uid: abramovrn
cn: abramovrn
givenName: Роман Николаевич
sn: Абрамов
uidNumber: 1100
gidNumber: 500
homeDirectory: /home/users/abramovrn
loginShell: /usr/bin/bash
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
userPassword: {SSHA}hgNEx6EhrM7LD4uXRGMsfNFyKctjz+rd
#pwdReset: TRUE
# Загрузить пользователей
ldapadd -x -H ldaps://openldap.workgroup.test -D "cn=admin,dc=workgroup,dc=test" -w 123456Qwerty -f users.ldif
 
# Удалить пользователей
IFS=$'\n'
users=($(cat users.ldif |grep 'dn:'))
for i in ${users[*]}; do echo -e "$i\nchangeType: delete\n"; done > usersdel.ldif
ldapmodify -x -H ldaps://openldap.workgroup.test -D "cn=admin,dc=workgroup,dc=test" -w 123456Qwerty -f usersdel.ldif

https://simp.readthedocs.io/en/latest/user_guide/User_Management/LDAP/OpenLDAP/manage_users.html
https://tylersguides.com/guides/openldap-how-to-add-a-user/

Расширение схемы

Схемы, атрибуты и классы, справка: https://www.zytrax.com/books/ldap/ch3/
6.1.1.4.2 Добавление/удаление наборов схемы данных в OLC (cn=config)

Добавление атрибута sAMAccountName. Создаётся файл с расширением .schema, например, samaccountname.schema

attributeType ( 1.2.840.113556.1.4.221
    NAME 'sAMAccountName'
    SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
    SINGLE-VALUE )
 
objectClass ( 1.3.6.1.4.1.4203.666.100.1
    NAME 'custom'
    SUP top
    AUXILIARY
    MAY (sAMAccountName) )

Положить этот файл в каталог, монтирующийся в контейнер и указанный в LDAP_SEED_INTERNAL_SCHEMA_PATH. После запуска контейнера он будет импортирован. После этого нужно остановить контейнер, закомментировать смонтированный каталог и переменную и запустить контейнер заново. ldif-файл после импорта находится в data/slapd/cn=config/cn=schema.

# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 646e9291
dn: cn={5}samaccountname
objectClass: olcSchemaConfig
cn: {5}samaccountname
olcAttributeTypes: {0}( 1.2.840.113556.1.4.221 NAME 'sAMAccountName' SYNTAX
 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
olcObjectClasses: {0}( 1.3.6.1.4.1.4203.666.100.1 NAME 'custom' SUP top AUXI
 LIARY MAY sAMAccountName )
structuralObjectClass: olcSchemaConfig
entryUUID: 2576b05c-f82a-103e-8395-5dabf1ba3ed8
creatorsName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
createTimestamp: 20240826190713Z
entryCSN: 20240826190713.191090Z#000000#000#000000
modifiersName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
modifyTimestamp: 20240826190713Z

Другой более человекообразный вариант: сделать сразу файл ldif

dn: cn=custom,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: custom
olcAttributeTypes: ( 1.2.840.113556.1.4.221
    NAME 'sAMAccountName'
    EQUALITY caseIgnoreMatch
    SUBSTR caseIgnoreSubstringsMatch
    SYNTAX '1.3.6.1.4.1.1466.115.121.1.15'
    SINGLE-VALUE )
olcObjectClasses: ( 1.3.6.1.4.1.4203.666.100.1
    NAME 'custom'
    SUP top
    AUXILIARY
    DESC 'Custom attributes class'
    MAY (sAMAccountName) )

Потом скопировать его внутрь контейнера и импортировать. Работает только от рута, через админскую учётку не хватит полномочий.

docker cp samaccountname.ldif openldap:/tmp
docker exec -ti openldap ldapadd -Y EXTERNAL -H ldapi:/// -f /tmp/samaccountname.ldif

https://www.opennet.ru/docs/RUS/ldap_apacheds/ch6/slapd-config.html#use-schemas
https://stackoverflow.com/questions/45725124/openldap-samaccountname-as-custom-attribute

FIXME Как добавить ещё один AttributeType в тот же ObjectClass - вопрос. Вроде бы AttributeType добавляется без проблем, но потом надо модифицировать ObjectClass так, чтобы он включал в себя этот атрибут. В чудесном мире LDAP это вроде бы делается удалением и повторным добавлением ObjectClass.

Вот это добавляется, теперь надо включить его в ранее добавленный objectClass «custom».

customattr.ldif
dn: cn=extensionAttribute1,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: extensionAttribute1
olcAttributeTypes: ( 1.2.840.113556.1.2.423 NAME 'extensionAttribute1'
        DESC 'extensionAttribute1'
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
        SINGLE-VALUE )
 

https://www.ibm.com/support/pages/adding-custom-attribute-inetorgperson-objectclass-may-attribute

Ошибки

Невозможно работать по LDAPS

Ошибки типа
The TLS connection was non-properly terminated
Can't contact LDAP server (-1)

Решение:

echo 'TLS_REQCERT never' |sudo tee --append /etc/ldap/ldap.conf

https://convincingbits.wordpress.com/2016/01/27/ldapsearch-using-tls-and-self-signed-server-certificates/

FreeIPA

https://github.com/freeipa/freeipa-container/blob/master/README
https://github.com/freeipa/freeipa-container#running-freeipa-server-container
https://hub.docker.com/r/freeipa/freeipa-server/
https://www.altlinux.org/FreeIPA/%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0_FreeIPA
https://docs.altlinux.org/ru-RU/domain/10.2/html/freeipa/ch01s08.html
https://freeipa.readthedocs.io/en/latest/workshop/1-server-install.html

Установка

Настройка для cgroup версий 1 и 2 отличается, ниже настройка для cgroup2.

# Проверка версии cgroup
grep cgroup /proc/filesystems
nodev   cgroup
nodev   cgroup2

Если не планируется поднимать встроенный DNS, то нужно прописать IP сервера в существующем DNS, например, ipa.workgroup.test 192.168.1.32.

Docker run

docker run --name freeipa-server -ti \
-h ipa.workgroup.test --read-only \
--cgroupns=host -v /sys/fs/cgroup:/sys/fs/cgroup:rw \
--sysctl net.ipv6.conf.all.disable_ipv6=0 \
-v ~/volumes/freeipa/data:/data freeipa/freeipa-server:rocky-9 ipa-server-install --skip-mem-check

Docker compose (cgroups2, без DNS)

---
services:
  freeipa:
    image: freeipa/freeipa-server:rocky-9
    container_name: freeipa-server
    restart: unless-stopped
    ports:
      - 123:123/udp
      - 389:389
      - 443:443
      - 464:464
      - 464:464/udp
      - 636:636
      - 80:80
      - 88:88
      - 88:88/udp
    tty: true
    stdin_open: true
    cgroup: host
    environment:
      IPA_SERVER_HOSTNAME: ipa.workgroup.test
      IPA_SERVER_INSTALL_OPTS: "-n workgroup.test -r WORKGROUP.TEST --skip-mem-check -U"
      PASSWORD: "123456Qwerty"
      TZ: "Europe/Moscow"
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /sys/fs/cgroup:/sys/fs/cgroup:rw
      - ~/volumes/freeipa/data:/data
    sysctls:
      - net.ipv6.conf.all.disable_ipv6=0

Останов и чистка данных в случае неудачной установки

docker rm -f freeipa-server
sudo rm -rf ~/volumes/freeipa/data/*

Результат установки

he IPA Master Server will be configured with:
Hostname:       ipa.workgroup.test
IP address(es): 172.17.0.2
Domain name:    workgroup.test
Realm name:     WORKGROUP.TEST

The CA will be configured with:
Subject DN:   CN=Certificate Authority,O=WORKGROUP.TEST
Subject base: O=WORKGROUP.TEST
Chaining:     self-signed

1. You must make sure these network ports are open:
        TCP Ports:
          * 80, 443: HTTP/HTTPS
          * 389, 636: LDAP/LDAPS
          * 88, 464: kerberos
        UDP Ports:
          * 88, 464: kerberos
          * 123: ntp

2. You can now obtain a kerberos ticket using the command: 'kinit admin'
   This ticket will allow you to use the IPA tools (e.g., ipa user-add)
   and the web user interface.
3. Kerberos requires time synchronization between clients
   and servers for correct operation. You should consider enabling chronyd.

Be sure to back up the CA certificates stored in /root/cacert.p12
These files are required to create replicas. The password for these
files is the Directory Manager password
The ipa-server-install command was successful

Клиент

# Установить клиента + kerberos
sudo apt install krb5-user freeipa-client -y
 
# Список команд с кратким описанием
ipa help commands
 
# Ввод в домен
sudo ipa-client-install --mkhomedir --hostname ubuntu.workgroup.test --domain workgroup.test --server=ipa.workgroup.test -p admin -w 123456Qwerty -U
 
# Добавить пользователя с запросом пароля (--random вместо --password - случайный пароль, покажется в консоли после создания пользователя)
ipa user-add mivanova --first=Мария --last=Иванова --password --shell=/usr/bin/bash  
 
# Переделать всех пользователей на оболочку bash
for i in $(ipa user-find |grep 'User login' |cut -d: -f2); do ipa user-mod $i --shell=/usr/bin/bash; done
 
# Поиск пользователя
kinit admin
ipa user-find vpupkin
--------------
1 user matched
--------------
  User login: vpupkin
  First name: Василий
  Last name: Пупкин
  Home directory: /home/vpupkin
  Login shell: /usr/bin/bash
  Principal name: vpupkin@WORKGROUP.TEST
  Principal alias: vpupkin@WORKGROUP.TEST
  Email address: vpupkin@workgroup.test
  UID: 247200003
  GID: 247200003
  Account disabled: False
----------------------------
Number of entries returned 1
----------------------------
 
# Поиск через LDAP
# Общий поиск (2 результата)
ldapsearch -x -D 'cn=Directory Manager' -w 123456Qwerty -b "dc=workgroup,dc=test" "uid=vpupkin"
# Более подробный результат
ldapsearch -x -D 'cn=Directory Manager' -w 123456Qwerty -b "cn=users,cn=accounts,dc=workgroup,dc=test" "uid=vpupkin"
# Менее подробный
ldapsearch -x -D 'cn=Directory Manager' -w 123456Qwerty -b "cn=users,cn=compat,dc=workgroup,dc=test" "uid=vpupkin"

keytab

# Генерация keytab, будет изменение пароля.
# Все ранее выгруженные кейтабы этого пользователя становятся недействительными.
$ ipa-getkeytab -p username -k username.keytab -P
New Principal Password:
Verify Principal Password:
Keytab successfully retrieved and stored in: username.keytab
 
# Проверка информации в кейтабе
$ klist -kte username.keytab
Keytab name: FILE:service.keytab
KVNO Timestamp           Principal
---- ------------------- ------------------------------------------------------
   1 08/22/2024 11:01:03 service@WORKGROUP.TEST (aes256-cts-hmac-sha384-192)
   1 08/22/2024 11:01:03 service@WORKGROUP.TEST (aes128-cts-hmac-sha256-128)
   1 08/22/2024 11:01:03 service@WORKGROUP.TEST (aes256-cts-hmac-sha1-96)
   1 08/22/2024 11:01:03 service@WORKGROUP.TEST (aes128-cts-hmac-sha1-96)
 
# Получение kerberos-билета и проверка
$ kinit -kt username.keytab username
$ klist
Ticket cache: KEYRING:persistent:1000:krb_ccache_Wc0I0KA
Default principal: service@WORKGROUP.TEST
 
Valid starting       Expires              Service principal
08/22/2024 11:02:05  08/23/2024 10:48:14  krbtgt/WORKGROUP.TEST@WORKGROUP.TEST

https://debuntu.ru/n/sozdanie-keytab-faila-dlya-polzovatelskogo-principala/

Windows

# Установить модуль
Install-Module -Name Manage-FreeIPA

Ошибки

Configuring certificate server (pki-tomcatd)

При первоначальной установке

Configuring certificate server (pki-tomcatd). Estimated time: 3 minutes
  [1/30]: configuring certificate server instance
Failed to configure CA instance
See the installation logs and the following files/directories for more information:
  /var/log/pki/pki-tomcat
  [error] RuntimeError: CA configuration failed.
CA configuration failed.

Надо прописывать правильный hostname в команде запуска или в docker compose.