О чём урок
В уроке создаём, изменяем и удаляем статическую запись Ивана в конфигурации OpenID и запись Елены во внешнем каталоге LDAP. Файлы редактируем вручную в nano, затем применяем изменения отдельными штатными командами. После создания и изменения проверяем новый вход и профиль, после удаления — отсутствие записи и отказ новой авторизации.
Команды и фрагменты ниже служат справкой к последовательным действиям урока. Перед повторением сопоставьте имена, пути, роли и параметры каталога со своей установкой.
Таймкоды и назначение действий
| Время | Действие |
| 00:00 | Два источника пользователей |
| 00:25 | Подготовка и резервная копия |
| 00:50 | Создание хеша и статической записи |
| 01:38 | Первый вход Ивана |
| 01:59 | Изменение имени и прав |
| 02:33 | Удаление статической записи |
| 03:05 | Подключение внешнего каталога |
| 03:38 | Создание пользователя в LDAP |
| 04:18 | Первый вход Елены |
| 04:38 | Изменение данных и группы |
| 05:12 | Удаление пользователя из LDAP |
| 05:42 | Что проверять после изменений |
Что подготовлено на стенде
Серверные компоненты Clearway CA размещены на одной виртуальной машине. В этой установке файл OpenID находится в /opt/itc/openid/config.json. Его владелец, технологическая учётная запись itc-svc, запускает пользовательскую службу openid.service. Команды systemctl --user выполняются в сеансе этого пользователя. Для работы используются nano, htpasswd из пакета apache2-utils, json_pp и ldap-utils.
«Внешний каталог» означает отдельный от OpenID источник учётных записей. Здесь это учебный OpenLDAP на той же VM: ldap://127.0.0.1:389, суффикс dc=training,dc=test. Классы inetOrgPerson и groupOfNames, атрибуты uid и displayName относятся к этому примеру. Это не готовая конфигурация Active Directory. Для рабочего AD/LDAP администратор каталога предоставляет адрес, базы поиска, фильтры, атрибуты и служебную учётную запись; защищённое подключение с проверкой сертификата настраивается отдельно.
Значения и откуда их брать
Файл конфигурации — /opt/itc/openid/config.json. Откуда брать: Параметры установки и команда запуска службы.
Владелец службы — itc-svc. Откуда брать: Технологическая учётная запись, выбранная при установке.
Служба — openid.service, systemctl --user. Откуда брать: Установленный unit и его область запуска.
Статический логин — ivan@training.test. Откуда брать: Новый уникальный логин; поле email.
userID — Новый UUID. Откуда брать: Получить командой из урока; при переименовании сохранить прежний.
username — Иван Петров → Иван Соколов. Откуда брать: Отображаемое имя пользователя.
Пароль Ивана — Training-OpenID-2026!. Откуда брать: Только учебный пример; для своей записи назначить свой.
hash — bcrypt, стоимость 12. Откуда брать: Результат htpasswd без логина и разделяющего двоеточия.
customClaims.roles — Три права, затем ещё просмотр событий. Откуда брать: Ролевая модель Clearway CA и полномочия пользователя.
LDAP-коннектор — ID ldap-training, имя «Учебный каталог». Откуда брать: Поля нужного элемента connectors.
LDAP URI и bind DN — Loopback и cn=admin,dc=training,dc=test. Откуда брать: Администратор каталога.
Базы поиска — ou=People,..., ou=Groups,.... Откуда брать: Реальная структура каталога.
Логин Елены — elena. Откуда брать: Значение атрибута uid, выбранного в userSearch.username.
Почта Елены — elena@training.test. Откуда брать: Значение mail; здесь это не логин.
Пароль Елены — Training-LDAP-2026!. Откуда брать: Только учебный пример; задаётся отдельно от LDIF.
Группы и права — CWCA_User, CWCA_Auditor. Откуда брать: Существующие группы и карта ldapGroupRolesMap.
Рабочие LDIF — /opt/itc/openid/lesson-manual. Откуда брать: Созданный для урока каталог файлов изменений.
Начальные права статической записи: rleMiniCACertList-r — просмотр сертификатов, rleMiniCATemplList-r — просмотр шаблонов, rleMiniCACertReq-w — запрос сертификата. При изменении добавляется rleMiniCAEventList-r — просмотр журнала событий.
Резервная копия
В сеансе itc-svc перейти к файлу и сохранить копию с исходными правами:
cp -p config.json config.before-manual-20261030.json
systemctl --user is-active openid.service
Имя копии в команде соответствует записи урока. Для следующей правки выбрать новое имя, чтобы не перезаписать предыдущую копию. Полную конфигурацию и её резервную копию в записи не показываем: в них есть служебные данные.
Создание статической записи
Вычислить bcrypt-хеш:
htpasswd -nBC12 ivan@training.test
Ввести пароль на два приглашения утилиты. -n выводит результат без изменения файла паролей, -B выбирает bcrypt, -C12 задаёт стоимость 12. Результат начинается с ivan@training.test:. В поле hash нужна только следующая за двоеточием строка $2y$12$… целиком. Открытый пароль в JSON не записывается. Из-за случайной соли повторный запуск с тем же паролем может дать другой хеш.
Получить новый UUID и открыть редактор:
cat /proc/sys/kernel/random/uuid
В nano найти staticPasswords клавишами Ctrl+W. Вручную добавить в массив новый объект. Существующие объекты сохранить. Два заполнителя в следующем примере заменить фактическими результатами команд:
"email": "ivan@training.test",
"hash": "<полный bcrypt-хеш>",
"username": "Иван Петров",
"userID": "<новый UUID>",
Между объектами массива ставится запятая, после последнего объекта её нет. Сохранить файл: Ctrl+O, Enter; выйти: Ctrl+X. Обозначение ^ в подсказках nano означает Ctrl.
Проверить синтаксис и применить изменения отдельными командами:
json_pp < config.json > /dev/null
systemctl --user restart openid.service
systemctl --user is-active openid.service
Успешная проверка json_pp не выводит текст; код 0 подтверждает корректный синтаксис JSON. Она не проверяет все настройки OpenID. При ошибке исправить файл в nano до перезапуска. После перезапуска ожидается active. Если служба не запускается, исправить ошибку или восстановить сохранённую копию до продолжения.
Выполнить новый вход с логином Ивана и заданным паролем. В профиле сверить имя Иван Петров и три права.
Изменение и удаление статической записи
Для изменения снова открыть config.json в nano и найти объект по ivan@training.test. Заменить username на Иван Соколов, добавить rleMiniCAEventList-r в roles. Проверить запятую после предыдущего элемента. Email, userID и hash сохранить прежними. Сохранить файл, выполнить блок json_pp и перезапуска, затем войти заново и проверить новое имя и четыре права.
Для удаления найти тот же объект и удалить его целиком, включая customClaims. Сохранить остальные записи и скобки массива. Если удаляется последний объект, убрать разделительную запятую после предыдущего. Сохранить файл, повторить проверку JSON и перезапуск. Новый вход Ивана должен быть отвергнут.
Настройки внешнего каталога
В редакторе просматриваются безопасные участки уже настроенного коннектора: userSearch, groupSearch и ldapGroupRolesMap. Служебные пароли и client secret в кадр не включаются.
В userSearch заданы username=uid, idAttr=uid, emailAttr=mail, nameAttr=displayName, preferredUsernameAttr=uid, база ou=People,dc=training,dc=test. В groupSearch база — ou=Groups,dc=training,dc=test, фильтр — (objectClass=groupOfNames), сопоставление — userAttr=DN и groupAttr=member, имя группы — cn.
Карта ldapGroupRolesMap связывает CWCA_User с тремя начальными правами пользователя. CWCA_Auditor получает rleMiniCACertList-r, rleMiniCAEventList-r, rleMiniCATemplList-r, rleMiniCACRL-r, rleMiniCAConfig-r, rleMiniCAReqList-r. Права создания запроса в этом наборе нет. Смена членства в каталоге не требует редактирования карты. Если меняется сама карта, нужно сохранить конфигурацию и перезапустить OpenID.
Создание LDAP-записи
Подготовить рабочий каталог и новый файл в редакторе:
mkdir -p /opt/itc/openid/lesson-manual
cd /opt/itc/openid/lesson-manual
Ввести и сохранить LDIF:
dn: uid=elena,ou=People,dc=training,dc=test
objectClass: organizationalPerson
objectClass: inetOrgPerson
sn:: 0KHQvNC40YDQvdC+0LLQsA==
givenName:: 0JXQu9C10L3QsA==
# displayName: Елена Смирнова
displayName:: 0JXQu9C10L3QsCDQodC80LjRgNC90L7QstCw
mail: elena@training.test
Двойное двоеточие означает представление значения в base64. В комментариях после # указаны исходные русские имена; комментарии не задают значения атрибутов. В записи показан ручной ввод LDIF и комментариев, без отдельной команды преобразования. Для подготовки своего значения можно использовать штатную справочную команду printf %s 'Елена Смирнова' | base64 и вручную перенести результат после displayName::. Base64 не является шифрованием или хешированием.
Добавить запись и отдельно установить пароль:
ldapadd -x -H ldap://127.0.0.1:389 \
-D 'cn=admin,dc=training,dc=test' -W -f elena-create.ldif
ldappasswd -x -H ldap://127.0.0.1:389 \
-D 'cn=admin,dc=training,dc=test' -W -S \
'uid=elena,ou=People,dc=training,dc=test'
На приглашение LDAP password вводится пароль администратора каталога. На New password и Re-enter new password — новый пароль Елены. Ввод скрыт, пароль в LDIF не сохраняется.
Создать через nano elena-join-user.ldif файл добавления в группу:
dn: cn=CWCA_User,ou=Groups,dc=training,dc=test
member: uid=elena,ou=People,dc=training,dc=test
Сохранить файл и применить:
ldapmodify -x -H ldap://127.0.0.1:389 \
-D 'cn=admin,dc=training,dc=test' -W -f elena-join-user.ldif
Проверка записи и группы
ldapsearch -x -H ldap://127.0.0.1:389 \
-D 'cn=admin,dc=training,dc=test' -W \
-LLL -o ldif-wrap=no -b 'ou=People,dc=training,dc=test' \
'(uid=elena)' uid cn mail
ldapsearch -x -H ldap://127.0.0.1:389 \
-D 'cn=admin,dc=training,dc=test' -W \
-LLL -o ldif-wrap=no -b 'ou=Groups,dc=training,dc=test' \
'(member=uid=elena,ou=People,dc=training,dc=test)' cn member
Первый поиск возвращает uid, cn и mail Елены, второй — CWCA_User и членство. Русское отображаемое имя проверяется в профиле после нового входа через «Учебный каталог». Логин в этом коннекторе — elena.
Изменение имени и группы LDAP
Создать через nano elena-edit.ldif файл замены cn, sn и displayName:
dn: uid=elena,ou=People,dc=training,dc=test
# displayName: Елена Орлова
displayName:: 0JXQu9C10L3QsCDQntGA0LvQvtCy0LA=
Создать через nano elena-group.ldif отдельный файл переноса членства из CWCA_User в CWCA_Auditor:
dn: cn=CWCA_User,ou=Groups,dc=training,dc=test
member: uid=elena,ou=People,dc=training,dc=test
dn: cn=CWCA_Auditor,ou=Groups,dc=training,dc=test
member: uid=elena,ou=People,dc=training,dc=test
Сохранить файлы и последовательно применить:
ldapmodify -x -H ldap://127.0.0.1:389 \
-D 'cn=admin,dc=training,dc=test' -W -f elena-edit.ldif
ldapmodify -x -H ldap://127.0.0.1:389 \
-D 'cn=admin,dc=training,dc=test' -W -f elena-group.ldif
DN, uid и mail сохраняются. Повторить оба поиска: cn становится Elena Orlova, группа — CWCA_Auditor. Выполнить новый вход и проверить имя Елена Орлова и шесть прав аудитора. В своей установке учитывать значение connectorCacheTimer.
Удаление LDAP-записи
Создать через nano elena-unlink.ldif файл удаления только членства Елены:
dn: cn=CWCA_Auditor,ou=Groups,dc=training,dc=test
member: uid=elena,ou=People,dc=training,dc=test
Применить его, затем удалить учебную запись:
ldapmodify -x -H ldap://127.0.0.1:389 \
-D 'cn=admin,dc=training,dc=test' -W -f elena-unlink.ldif
ldapdelete -x -H ldap://127.0.0.1:389 \
-D 'cn=admin,dc=training,dc=test' -W \
'uid=elena,ou=People,dc=training,dc=test'
Остальные member групп не изменяются. В учебных группах сохраняется технический member group-anchor; удалять его не нужно. Класс groupOfNames требует хотя бы одного member.
Повторить оба поиска: запись и членство Елены должны отсутствовать. Ошибка поиска не считается подтверждением отсутствия. Проверить отказ нового входа через «Учебный каталог».
Ключи LDAP-команд
-x — Simple bind вместо SASL.
-H — URI сервера LDAP.
-D — DN учётной записи для выполнения операции.
-W — Запрос её пароля скрытым вводом.
-S у ldappasswd — Запрос нового пароля пользователя.
-f — LDIF с добавлением или изменениями.
-b у ldapsearch — База поиска.
-LLL — Компактный вывод LDIF.
-o ldif-wrap=no — Не переносить значения строками.
Проверка результата и источники
Новый вход проверяет актуальные данные аутентификации и профиль. Уже открытая страница не заменяет эту проверку. Удаление записи и отказ нового входа не доказывают немедленного прекращения действия ранее выданных токенов.
Продуктовые поля и права сверены с «Руководством администратора Clearway CA 26.3.0-v6-20261006_144606.pdf», разделами OpenID, ролевой модели и сопоставления групп AD/LDAP, а также с установленным стендом. Путь JSON и пользовательская служба относятся к показанной быстрой установке; в документации встречается и YAML для другого способа развёртывания.
Синтаксис htpasswd: официальное руководство Apache, https://httpd.apache.org/docs/2.4/programs/htpasswd.html. Формат LDIF и base64: RFC 2849, https://www.rfc-editor.org/rfc/rfc2849.html. Ключи LDAP-команд сверены с установленными manpages ldap-utils. Учебные DN, URI и группы не являются универсальными настройками AD.