Утилита YandexADSCIM
Чтобы подключить синхронизацию пользователей из Active Directory, ALD Pro или Samba DC на Windows, Linux или других *nix-платформах, установите утилиту YandexADSCIM по инструкции ниже и запустите ее от имени пользователя с правами чтения из каталога LDAP.
Протоколы синхронизации
|
Направление |
Адрес |
Порт |
Протокол |
Назначение |
|
В сторону Яндекс |
|
443 |
HTTPS/SSL |
SCIM API для синхронизации данных |
|
|
443 |
HTTPS/SSL |
Работа утилиты |
|
|
|
443 |
HTTPS/SSL |
Загрузка образа утилиты |
|
|
В сторону вашей инфраструктуры |
Ваши серверы (AD или другие) |
389 или 636 |
LDAP или LDAPS |
Чтение данных пользователей и групп |
Для корректной работы утилиты разрешите исходящие подключения в настройках файрвола:
# Разрешить исходящий HTTPS к SCIM API Яндекс
Allow outbound: TCP 443 to scim-api.passport.yandex.net
# Разрешить исходящий HTTPS для работы утилиты
Allow outbound: TCP 443 to 77.88.21.80
# Разрешить исходящий HTTPS для загрузки образа утилиты
Allow outbound: TCP 443 to registry.yandexcloud.net
# Разрешить исходящий LDAP/LDAPS к вашим серверам
Allow outbound: TCP 389,636 to your-ad-servers.example.com
Перед запуском утилиты проверьте доступность конечных точек:
# Проверка доступа к SCIM API Яндекс
telnet scim-api.passport.yandex.net 443
# Или
curl -I https://scim-api.passport.yandex.net/
# Проверка доступа для работы утилиты
telnet 77.88.21.80 443
# Или
curl -I https://77.88.21.80/
# Проверка доступа к вашим серверам
telnet dc.example.com 389
Шаг 1. Получите Docker-образ утилиты
Выполните команду для загрузки последней версии образа из нашего реестра в Docker:
# Загрузка образа из внешнего реестра
docker pull registry.yandexcloud.net/cn1v24roe2k2kcqihnke/adscim:latest
# Проверка загруженного образа
docker images | grep adscim
Если у вас есть локальный архив с образом adscim2402.tar, выполните команду для загрузки образа в Docker:
# Загрузка образа из архива
docker load -i adscim2402.tar
# Проверка загруженного образа
docker images | grep adscim
Шаг 2. Подготовьте окружение
-
Для установки утилиты понадобятся:
- Docker и Docker Compose;
- OAuth-токен для доступа к
scim-api.passport.yandex.net; - Учетные данные для подключения. Где взять учетные данные и токен
-
Создайте рабочую директорию для утилиты:
mkdir -p adscim/config cd adscim
Шаг 3. Настройте конфигурационный файл
Создайте конфигурационный файл config/application.json:
{
"adscim": {
"source": {
"type": "active-directory", // Тип каталога: active-directory, generic-ldap
"ldap": {
"urls": [ // Адреса LDAP-серверов
"ldap://dc.example.com:389" // Формат: протокол://хост:порт
],
"paths": [ // Базовые DN для поиска пользователей
"OU=Users,DC=example,DC=com" // Организационные подразделения
],
"username": "sync_user@example.com", // Учетная запись для подключения
"password": { // Пароль (рекомендуется использовать файлы)
"value": "<пароль_от_вашего_сервера>" // Прямое значение пароля
}
}
},
"destination": {
"scim": {
"bearerToken": { // OAuth-токен для доступа к SCIM API
"value": "<токен_SCIM>"
},
"domainId": "<идентификатор_домена>" // ID домена в Яндекс 360
}
},
"sync": {
"dryRun": true, // Тестовый режим (без изменений в Яндекс 360)
"intervalMinutes": 60 // Интервал синхронизации в минутах
}
}
}
где
-
"dryRun": true— тестовый режим для проверки подключения к вашему серверу и SCIM API без внесения изменений на стороне Яндекс 360; -
dc.example.com:389— адрес вашего сервера (AD или другого); -
DC– domainComponent, собственный домен и доменная зона; -
OU– OrganizationUnit, компания, департамент или отдел, из которого вы хотите получить пользователей; -
OU=Users,DC=example,DC=com— путь к пользователям в каталоге LDAP; -
sync_user@example.com— пользователь для подключения к единому входу (SSO); -
<пароль_от_вашего_сервера>— пароль для подключения к единому входу (SSO); -
<токен_SCIM>— OAuth-токен для Яндекс 360; -
<идентификатор_домена>— ваш Domain ID в Яндекс 360. Где его взять
Ключевые параметры конфигурации
Базовые настройки подключения
urls— адреса серверов LDAP в форматеldap://хост:портилиldaps://хост:портдля защищенного соединения;paths— организационные подразделения для поиска пользователей, напримерOU=Users,DC=example,DC=com;username/password— учетные данные и пароль для подключения к LDAP-серверу.
Параметры синхронизации
dryRun— режим пробного запуска без внесения изменений в каталог Яндекс 360 — обязателен во время настройки синхронизации;intervalMinutes— интервал времени между автоматическими запусками синхронизации в минутах;allowUsersDeletion— разрешение на блокировку пользователей в Яндекс 360 при их отсутствии в LDAP-каталоге — обязательно при синхронизации из нескольких лесов Active Directory.
Полный список доступных параметров
|
Параметр |
Тип |
По умолчанию |
Описание |
|
logging |
|||
|
|
string |
|
Уровень детализации сообщений в журнале: |
|
adscim.source |
|||
|
|
string |
Тип используемого каталога пользователей: |
|
|
adscim.source.ldap |
|||
|
|
array[string] |
Адреса серверов LDAP в формате |
|
|
|
array[string] |
Организационные подразделения для поиска пользователей, например |
|
|
|
string |
Учетные данные для подключения к LDAP-серверу, например UPN ( |
|
|
|
object |
Пароль для аутентификации на LDAP-сервере |
|
|
|
integer |
|
Максимальное время ожидания установления подключения к LDAP-серверу в миллисекундах |
|
|
integer |
|
Максимальное время ожидания операций чтения данных из LDAP-сервера в миллисекундах |
|
|
integer |
|
Размер страницы для постраничного поиска (paged search) в LDAP |
|
|
boolean |
|
Загружать все адреса электронной почты контактов, включая алиасы и дополнительные адреса из атрибута proxyAddresses |
|
adscim.source.ldap.connectionPool |
|||
|
|
integer |
|
Начальное количество соединений в пуле подключений к LDAP-серверу |
|
|
integer |
|
Максимальное количество соединений в пуле подключений к LDAP-серверу |
|
|
integer |
|
Периодичность проверки работоспособности соединений в пуле в миллисекундах |
|
adscim.source.ldap.filters |
|||
|
|
string |
|
LDAP-фильтр для поиска объектов пользователей в каталоге |
|
|
string |
|
LDAP-фильтр для поиска объектов групп в каталоге |
|
|
string |
|
LDAP-фильтр для поиска объектов контактов в каталоге |
|
adscim.source.ldap.attributes.user |
|||
|
|
array[string] |
|
Атрибут, содержащий имя пользователя для входа в систему |
|
|
array[string] |
|
Атрибут, содержащий имя пользователя |
|
|
array[string] |
|
Атрибут, содержащий фамилию пользователя |
|
|
array[string] |
|
Атрибут, содержащий отчество пользователя |
|
|
array[string] |
|
Атрибут, содержащий отображаемое имя пользователя |
|
|
array[string] |
|
Атрибут, содержащий должность пользователя |
|
|
array[string] |
|
Атрибут, содержащий основной адрес электронной почты пользователя |
|
|
array[string] |
|
Атрибут, содержащий номер мобильного телефона пользователя |
|
|
array[string] |
|
Атрибут, содержащий номер рабочего телефона пользователя |
|
|
array[string] |
|
Атрибут, содержащий номер IP-телефона пользователя |
|
|
array[string] |
|
Список атрибутов, обязательных для успешной синхронизации пользователя |
|
adscim.source.ldap.attributes.group |
|||
|
|
array[string] |
|
Атрибут, содержащий название группы |
|
|
array[string] |
|
Атрибут, содержащий описание группы |
|
|
array[string] |
|
Атрибут, содержащий адрес электронной почты группы |
|
|
array[string] |
|
Атрибут, влияющий на отображение группы в каталоге |
|
adscim.source.ldap.attributes.sharedContact |
|||
|
|
array[string] |
|
Атрибут, содержащий имя контакта |
|
|
array[string] |
|
Атрибут, содержащий фамилию контакта |
|
|
array[string] |
|
Атрибут, содержащий отчество контакта |
|
|
array[string] |
|
Атрибут, содержащий должность контакта |
|
|
array[string] |
|
Атрибут, содержащий подразделение контакта |
|
|
array[string] |
|
Атрибут, содержащий организацию контакта |
|
|
array[string] |
|
Атрибут, содержащий основной адрес электронной почты контакта |
|
|
array[string] |
|
Атрибут, содержащий номер рабочего телефона контакта |
|
|
array[string] |
|
Атрибут, содержащий дополнительный номер рабочего телефона контакта |
|
|
array[string] |
|
Атрибут, содержащий номер мобильного телефона контакта |
|
|
array[string] |
|
Атрибут, содержащий дополнительный номер мобильного телефона контакта |
|
|
array[string] |
|
Атрибут, содержащий номер IP-телефона контакта |
|
|
array[string] |
|
Атрибут, содержащий дополнительный номер IP-телефона контакта |
|
|
array[string] |
|
Атрибут, содержащий адрес контакта (улица и дом) |
|
|
array[string] |
|
Атрибут, содержащий адрес контакта (город) |
|
|
array[string] |
|
Атрибут, содержащий адрес контакта (регион) |
|
|
array[string] |
|
Атрибут, содержащий почтовый индекс контакта |
|
adscim.destination.scim |
|||
|
|
object |
OAuth-токен для аутентификации в SCIM API Яндекс 360 (см. раздел безопасного хранения секретов) |
|
|
|
integer |
Уникальный идентификатор домена в Яндекс 360, для которого выполняется синхронизация |
|
|
adscim.sync |
|||
|
|
boolean |
|
Включить синхронизацию групп из LDAP-каталога в Яндекс 360 |
|
|
boolean |
|
Включить синхронизацию контактов из LDAP-каталога в Яндекс 360 |
|
|
integer |
|
Интервал времени между автоматическими запусками синхронизации в минутах |
|
|
boolean |
|
Режим пробного запуска без внесения изменений в каталог Яндекс 360 — обязателен во время настройки синхронизации |
|
|
boolean |
|
Разрешить блокировку пользователей в Яндекс 360 при их отсутствии в LDAP-каталоге |
|
|
boolean |
|
Разрешить блокировку групп в Яндекс 360 при их отсутствии в LDAP-каталоге |
|
|
boolean |
|
Разрешить блокировку контактов в Яндекс 360 при их отсутствии в LDAP-каталоге |
|
|
boolean |
|
Игнорировать доменную часть в именах пользователей (вместо |
|
|
boolean |
|
Игнорировать изменения адресов электронной почты пользователей при синхронизации |
|
|
integer |
|
Задержка перед первым запуском синхронизации после старта утилиты в секундах |
|
adscim.sync.aliases |
|||
|
|
boolean |
false |
Включить обработку псевдонимов адресов электронной почты при синхронизации |
|
|
array[string] |
|
Список доменов, используемых для псевдонимов — первый считается основным |
|
|
object |
|
Правила замены доменов в формате |
Пример расширенной конфигурации для Active Directory
{
"logging": { // Настройки логирования
"level": { // Уровни детализации логов
"ru.yandex.ya360.backend.b2b_platform.adscim": "INFO" // DEBUG, INFO, WARN, ERROR
}
},
"adscim": {
"source": {
"type": "active-directory",
"ldap": {
"urls": [
"ldap://dc.example.com:389"
],
"paths": [
"OU=Users,DC=example,DC=com"
],
"username": "sync_user@example.com",
"password": {
"value": "<пароль_от_вашего_сервера>"
},
"connectionTimeout": 5000, // Тайм-аут подключения (мс)
"readTimeout": 10000, // Тайм-аут чтения данных (мс)
"pageSize": 100, // Размер страницы для постраничного поиска
"contactFetchProxyAddresses": true, // Загружать прокси-адреса контактов
"connectionPool": { // Настройки пула подключений
"initialConnections": 1, // Начальное количество соединений
"maxConnections": 10, // Максимальное количество соединений
"healthCheckIntervalMs": 60000 // Интервал проверки здоровья (мс)
},
"filters": { // LDAP-фильтры для поиска объектов
"users": "(&(objectCategory=person)(objectClass=user))", // Фильтр для пользователей Active Directory
"groups": "(objectClass=group)", // Фильтр для групп
"contacts": "(objectClass=contact)" // Фильтр для контактов
},
"attributes": { // Сопоставление LDAP-атрибутов
"user": {
"loginName": ["userPrincipalName"], // Логин пользователя
"firstName": ["givenName"], // Имя
"lastName": ["surName", "sn"], // Фамилия
"middleName": ["middleName"], // Отчество
"displayName": ["displayName"], // Отображаемое имя
"title": ["title"], // Должность
"workMail": ["mail"], // Основная электронная почта
"mobilePhone": ["mobile"], // Мобильный телефон
"workPhone": ["telephoneNumber"], // Рабочий телефон
"ipPhone": ["ipPhone"], // IP-телефон
"required": ["userPrincipalName", "mail"] // Обязательные атрибуты
},
"group": { // Атрибуты групп
"name": ["name", "cn"], // Название группы
"description": ["description"], // Описание группы
"mail": ["mail"], // Электронная почта группы
"displayFlag": [] // Флаг отображения группы
},
"sharedContact": { // Атрибуты контактов
"firstName": ["givenName"], // Имя контакта
"lastName": ["surName", "sn"], // Фамилия контакта
"middleName": ["middleName"], // Отчество контакта
"title": ["title"], // Должность контакта
"department": ["department"], // Подразделение контакта
"company": ["company"], // Организация контакта
"workMail": ["mail"], // Основная электронная почта контакта
"workPhone": ["telephoneNumber"], // Рабочий телефон контакта
"otherWorkPhone": ["otherTelephone"], // Дополнительный рабочий телефон
"mobilePhone": ["mobile"], // Мобильный телефон контакта
"otherMobilePhone": ["otherMobile"], // Дополнительный мобильный телефон
"ipPhone": ["ipPhone"], // IP-телефон контакта
"otherIpPhone": ["otherIpPhone"], // Дополнительный IP-телефон
"address1": ["streetAddress"], // Адрес (улица и дом)
"address2": ["l"], // Адрес (город)
"address3": ["st"], // Адрес (регион)
"address4": ["postalCode"] // Почтовый индекс
}
}
}
},
"destination": {
"scim": {
"bearerToken": {
"value": "<токен_SCIM>" // OAuth-токен для доступа к SCIM API
},
"domainId": "<идентификатор_домена>" // ID домена в Яндекс 360
}
},
"sync": {
"enableGroups": false, // Включить синхронизацию групп
"enableContacts": false, // Включить синхронизацию контактов
"intervalMinutes": 60, // Интервал синхронизации
"dryRun": true, // Тестовый режим (без изменений в Яндекс 360)
"allowUsersDeletion": true, // Разрешить блокировку пользователей
"allowGroupsDeletion": true, // Разрешить блокировку групп
"allowContactsDeletion": true, // Разрешить блокировку контактов
"ignoreUsernameDomain": false, // Игнорировать домен в логине
"ignoreUserEmailChange": false, // Игнорировать изменение электронной почты
"initialDelaySeconds": 10, // Задержка перед стартом
"aliases": { // Настройки алиасов электронной почты
"enabled": false, // Включить обработку алиасов
"domains": [], // Разрешенные домены
"changeDomains": {} // Замена доменов
}
}
}
}
Пример расширенной конфигурации для FreeIPA и совместимых каталогов (ALD Pro)
logging:
level:
ru.yandex.ya360.backend.b2b_platform.adscim: INFO # Уровень детализации логов: DEBUG, INFO, WARN, ERROR
adscim:
source:
type: generic-ldap # Тип каталога: generic-ldap для FreeIPA и совместимых систем
ldap:
urls:
- ldap://ald-server.example.com:389 # Адрес вашего сервера
paths:
- cn=users,cn=accounts,dc=example,dc=com # Базовый DN для поиска в формате FreeIPA
username: uid=svc_sync,cn=users,cn=accounts,dc=example,dc=com # Учетная запись в формате Distinguished Name
password:
value: <пароль_от_вашего_сервера> # Пароль для подключения
filters:
users: "(objectClass=posixAccount)" # Фильтр для поиска пользователей
groups: "(objectClass=posixGroup)" # Фильтр для поиска групп
attributes:
user:
loginName:
- uid # Логин пользователя
firstName:
- givenName # Имя пользователя
lastName:
- sn # Фамилия пользователя
workMail:
- mail # Основной адрес электронной почты
destination:
scim:
bearerToken:
value: <токен_SCIM> # OAuth-токен для доступа к SCIM API Яндекс 360
domainId: <идентификатор_домена> # ID домена в Яндекс 360
sync:
dryRun: true # Тестовый режим (без изменений в Яндекс 360)
ignoreUsernameDomain: true # Игнорировать домен в логине (в FreeIPA обычно отсутствует)
Шаг 4. Запустите утилиту
-
Создайте
docker-compose.yml:services: adscim: image: registry.yandexcloud.net/cn1v24roe2k2kcqihnke/adscim:latest container_name: adscim restart: unless-stopped ports: - "127.0.0.1:3402:3402" volumes: - ./config/application.json:/app/config/application.json:ro - logs:/app/logs environment: - JAVA_OPTS=-Xmx1024m -Xms512m healthcheck: test: [ "CMD", "curl", "-f", "http://localhost:3402/actuator/health" ] interval: 30s timeout: 10s retries: 3 start_period: 60s volumes: logs: -
Запустите сервис:
docker-compose up -d -
Проверьте статус:
docker-compose ps docker-compose logs -fОсновные команды управления
# Управление сервисом docker-compose up -d # запуск docker-compose down # остановка docker-compose restart # перезапуск docker-compose ps # статус docker-compose logs -f # просмотр логов # Остановка с очисткой docker-compose down -v # остановка с удалением volumesВ колонке STATUS должен быть статус
Up (healthy).
Шаг 5. Включите синхронизацию
Если система в тестовом режиме работает корректно:
-
Измените в конфигурационном файле параметр
"dryRun"наfalse; -
Перезапустите сервис:
docker-compose restart
Хранение секретов
Для безопасного хранения секретов мы рекомендуем использовать внешние менеджеры секретов. Пример ниже носит иллюстративный характер, так как для реальной эксплуатации рекомендуется интегрироваться с менеджером секретов, используемым в организации.
Чтобы хранить секреты, вынесите их из конфигурационного файла в отдельные.
-
Создайте файлы с секретами в отдельной директории рядом с файлом
docker-compose.yml:# Создание директории для секретов mkdir -p secrets # Создание файлов с секретами (без лишних пробелов и переводов строк) echo "<пароль_от_вашего_сервера>" > secrets/ldap_password.txt echo "<токен_SCIM>" > secrets/scim_bearer_token.txt # Установка прав доступа к файлам (600 — чтение только владельцем) chmod 600 secrets/ldap_password.txt secrets/scim_bearer_token.txt -
Обновите конфигурационный файл
config/application.json:{ "adscim": { "source": { "type": "active-directory", "ldap": { "urls": ["ldap://dc.example.com:389"], "paths": ["OU=Users,DC=example,DC=com"], "username": "sync_user@example.com", "password": { "file": "/run/secrets/ldap_password" } } }, "destination": { "scim": { "bearerToken": { "file": "/run/secrets/scim_bearer_token" }, "domainId": "<идентификатор_домена>" } }, "sync": { "dryRun": true, "intervalMinutes": 60 } } } -
Добавьте в файл
docker-compose.ymlпуть к файлам с секретами:services: adscim: image: registry.yandexcloud.net/cn1v24roe2k2kcqihnke/adscim:latest container_name: adscim restart: unless-stopped ports: - "127.0.0.1:3402:3402" secrets: - ldap_password - scim_bearer_token volumes: - ./config/application.json:/app/config/application.json:ro - logs:/app/logs environment: - JAVA_OPTS=-Xmx1024m -Xms512m healthcheck: test: [ "CMD", "curl", "-f", "http://localhost:3402/actuator/health" ] interval: 30s timeout: 10s retries: 3 start_period: 60s secrets: ldap_password: file: ./secrets/ldap_password.txt scim_bearer_token: file: ./secrets/scim_bearer_token.txt volumes: logs: -
После внесения изменений перезапустите сервис:
docker-compose down docker-compose up -d
Возможные ситуации при работе
Типичные сценарии синхронизации
|
Ситуация |
Результат |
|
У пользователя изменились атрибуты на вашем сервере, но при этом уникальный идентификатор не изменился |
Система обновит атрибуты в каталоге Яндекса (кроме основной почты и NameID). |
|
Пользователь удален на вашем сервере |
Пользователь будет заблокирован в каталоге Яндекса. Чтобы при удалении аккаунтов на вашем сервере они оставались активными в каталоге Яндекса (например, при синхронизации из нескольких лесов Active Directory), установите для параметра |
|
Новый пользователь на вашем сервере |
Пользователь будет добавлен в каталог Яндекса с соответствующими атрибутами. |
|
Все пользователи в каталоге Яндекса заблокированы |
Это могло произойти, если:
|
Диагностика и устранение неполадок
Проверка подключения
# Проверка LDAP подключения
ldapsearch -H ldap://dc.example.com:389 -x -b "OU=Users,DC=example,DC=com" -D "sync_user@example.com" -W
# Проверка SCIM API
curl -H "Authorization: Bearer <токен_SCIM>" "https://scim-api.passport.yandex.net/v2/Users?domainId=<идентификатор_домена>"
Ответ при успешном подключении к LDAP:
- Список пользователей из указанного организационного подразделения (OU);
- Данные атрибутов для каждого пользователя (имя, электронная почта, должность и т.д.).
- Нет сообщений об ошибках
Invalid credentialsилиConnection failed.
Ответ при успешном подключении к SCIM API:
- HTTP-статус
200 OK; - JSON-файл с информацией о пользователях, уже существующих в каталоге Яндекс 360;
- Корректная структура данных SCIM без ошибок авторизации;
- Нет сообщений об ошибках
Authentication failedилиInvalid token.
В ответе есть ошибки
Проверьте правильность введенных учетных данных и актуальность токена, а также сетевую доступность серверов.
Анализ логов и решение проблем
Проверьте логи приложения для выявления причин ошибок:
docker-compose logs -f
|
Проблема |
Решение |
|
|
Проверьте URL, порт и учетные данные на вашем сервере, например AD. Убедитесь в правильности формата адреса ( |
|
|
Проверьте логин и пароль. Убедитесь в правильности формата UPN ( |
|
|
Проверьте актуальность OAuth-токена и убедитесь, что он имеет необходимые права доступа к SCIM API |
|
|
Проверьте сетевую доступность LDAP сервера. Убедитесь, что файрвол разрешает подключение на порт 389/636 |
|
Медленная синхронизация |
Увеличьте значение |
|
Пустой результат синхронизации |
Проверьте корректность |
|
Ошибки обработки атрибутов |
Убедитесь, что указанные в конфигурации атрибуты существуют в вашем LDAP-каталоге и доступны для чтения |
Мониторинг работы сервиса
Для проверки состояния утилиты используйте следующие команды:
# Проверка состояния через Health Check
curl http://localhost:3402/actuator/health
# Проверка статуса контейнера
docker-compose ps
Если утилита работает корректно:
-
Health Check должен вернуть HTTP-статус
200 OKс JSON-файлом:{"status":"UP"} -
Статус контейнера в ответе
docker-compose psдолжен содержать:UP— контейнер запущен;(healthy)— Health Check проходит успешно;- Время работы контейнера — например,
Up 5 minutes.
Если утилита работает некорректно:
-
Статус контейнера имеет значение
DOWN— проверьте логи для диагностики неполадок; -
Статус контейнера имеет значение
EXITилиRESTARTING— проверьте конфигурацию и доступность зависимостей; -
Отсутствие статуса
(healthy)— проблемы с внутренней работой утилиты.
Протокол хранения данных об организации, каталогах, пользователях, позволяющий осуществлять аутентификацию.
Высший уровень логической структуры доменной службы Microsoft. Представляет собой коллекцию доменов, объединенных общей схемой данных, конфигурацией, глобальным каталогом и доверительными отношениями.