OTRS — система обработки заявок с открытым кодом (Open-source Ticket Request System), написанная на Perl.
Существует в двух вариантах:
- OTRS Business Solution — платная версия
- ((OTRS)) Community Edition — бесплатная версия
Перечислю немного из того фукционала, который поддерживает эта система:
- модуль ITSM (Service Level Management, Change Management, Configuration Management, CMDB)
- адаптивный веб-интерфейс
- API
- SLA и сервисы
- мультитенантность
- эскалации
- аутентификация: DB, LDAP, HTTPBasicAuth, Radius
- поддержка MySQL, MariaDB, PostgreSQL, Oracle
И если искать в ней недостатки — так это непривычность интерфейса и сложность в настройке. Под катом — об основах авторизации (группы, RBAC, поддержка нескольких компаний-клиентов), аутентификации и синхронизации метаданных (ФИО, телефона и прочего), используя различные каталоги LDAP
Клиенты, очереди, агенты и группы
После установки OTRS у вас сразу будут доступны:
- клиенты — могут создавать заявки, отправив письмо или используя веб-доступ
- очереди — каждая заявка попадает в одну из очередей заявок
- агенты — ИТ специалисты, работающие над выполнением заявок из доступных им очередей
- группы — сущность, связывающая между собой очереди, клиентов и агентов, а также задающая права агентов — например, только чтение, изменение приоритета заявки и т. п.
Стандартные группы
После установки системы вы увидите три созданные группы:
- admin — члены группы могут администрировать (настраивать) OTRS
- stats — возможность настраивать и запускать отчеты
- users — стандартная группа для клиентов, очередей и агентов
Права, связанные с группами
Основные права
Основные права, которые можно настроить в группе, ограничивающие действия агентов:
- только чтение — права только на чтение заявки в данной группе/очереди
- переместить — права на перемещение заявок в эту группу/очередь
- создание — права на создание заявок в этой группе/очереди
- заметка — права на добавление заметок в заявки в этой группе/очереди
- владелец — права на смену владельца заявок в этой группе/очереди
- приоритет — права на смену приоритета заявок в этой группе/очереди
- чтение/запись — полные права на чтение и запись для заявок в данной группе/очереди
Дополнительные права
Также существуют и дополнительные права, отображение которых можно включить в настройках (System::Permission):
- отчеты — предоставляет доступ к странице отчетов
- перенаправить — право перенаправить/bounce почтовое сообщение (ссылка перенаправить/bounce в ticketZoom)
- создать — право составления ответа на заявку
- клиент — право изменить клиента для этой заявки
- переслать — право пересылать сообщения (с помощью кнопки Переслать)
- в ожидании — право перевести заявку в ожидание
- телефон — право добавить содержание звонка клиента к заявке в виде сообщения/заметки
- ответственный — Право изменить ответственного за заявку
Рассмотрим это более подробно:
- каждый клиент может быть включен в одну или несколько групп, изначально все клиенты входят в группу users
- каждая очередь заявок связывается с какой-либо одной из групп
- через веб-интерфейс клиент может делать заявки в тех очередях, к которым имеют доступ группы, в которые он включен
- при отправке клиентом заявки по электронной почте существует возможность на основании анализа атрибутов письма (например, адреса отправителя или заголовка письма) изменять характеристики заявки, в том числе и очередь, в которую попадет заявка
- если клиент позвонил по телефону, агент может завести заявку вручную, выбрав любую из доступных агенту очередей
- желательно, чтобы заявка клиента всегда была в очередях, доступных клиенту, иначе он не сможет получить доступ к ней через веб-интерфейс
- агенты могут производить действия в заявками в соответствии с правами на очередь, в которой находится заявка
Аутентификация с использованием базы данных
Стандартный способ аутентификации и авторизации агентов и клиентов — это база данных.
Например, настройки аутентификации агентов, используя базу данных, выглядит так:
$Self->{'AuthModule'} = 'Kernel::System::Auth::DB';
Клиентов:
$Self->{'Customer::AuthModule'} = 'Kernel::System::CustomerAuth::DB';
$Self->{'Customer::AuthModule::DB::Table'} = 'customer_user';
$Self->{'Customer::AuthModule::DB::CustomerKey'} = 'login';
$Self->{'Customer::AuthModule::DB::CustomerPassword'} = 'pw';
Мы также оставим этот способ аутентификации и добавим в дополнение с нему аутентификацию через LDAP.
Роли и компании
Так же мы расширим возможности авторизации, добавив роли и компании:
- роли — позволяют более гибко управлять доступами, связывая между собой группы и агентов
- компании — позволяют изолировать заявки различных клиентов (будь то разные отделы или компании)
Постановка задачи
Вы — администратор системы OTRS в компании my-it-company.com, предоставляющей сервисные услуги другим компаниям (или подразделениям внутри вашего холдинга).
Вам очень бы не хотелось заводить учетные записи новых агентов и клиентов вручную, а также заполнять дополнительную информацию, такую как адрес электронной почты, телефон, должность, адрес и номер кабинета — ведь это все уже есть в каталогах LDAP.
И ваша компания также получит очевидные плюсы — единый пароль сотрудника во все системы, блокировка учетной записи в LDAP заблокирует доступ и во все остальные сервисы.
my-it-company.com работает на Linux и использует в качестве сервера каталогов Red Hat FreeIPA, а обслуживаемые вами подразделения — различные леса Microsoft Active Directory, с которыми у вас нет федерации, но есть возможность подключения к контроллерам домена.
Вам нужно разделить потоки заявок от различных клиентов, а также реализовать различные уровни доступа агентов к очередям — менеджеры должны иметь возможность менять приоритет задач в системе.
Сотрудники вашей компании так же могут ставить задачи в системе для внутренних нужд my-it-company.com, иногда являясь и агентами, и клиентами одновременно (а иногда и нет).
Подготовка
Учетные записи для просмотра LDAP
Если запрещен анонимный просмотр дерева каталогов, то создадим в доменах my-it-company.com, pear.com и macrohard.com учетные записи, прав которых нам хватит, чтобы делать запросы к LDAP (назовем их, например, ldap-bot)
Группы FreeIPA для синхронизации с ролями OTRS
Заведем на FreeIPA три группы пользователей, которые будут синхронизироваться с нашими ролями OTRS, например:
- otrs-sa — члены этой группы получат доступ к администрированию OTRS, но доступ к очередям давать не будем, чтобы не было желания всегда работать под администратором),
- otrs-admins — наши менеджеры, имеющие право изменения приоритета заявок) и
- otrs-helpdesk — учетные записи наших специалистов
Атрибут, определяющий принадлежность к компании
Выберем атрибут, по которому будем определять принадлежность к компании. Пусть это будет атрибут «Организация». Например, у вас все получилось организационно и технически, и все пользователи во всех доменах всегда имеют значение в поле «Организация»:
- my-it-company — для сотрудников my-it-company.com
- pear-company — для сотрудников pear.com
- macrohard-company — для сотрудников macrohard.com
Определим атрибуты пользователя, используемые FreeIPA
Изучим схему FreeIPA, выяснив названия атрибутов, которые нам понадобятся для синхронизации (ФИО, логин, телефон и т. п.).
kinit laptevs
ipa user-show --all --raw laptevs
Получим подобный вывод:
dn: uid=laptevs,cn=users,cn=accounts,dc=my-it-company,dc=com
uid: laptevs
givenname: Stanislav
sn: Laptev
cn: Laptev Stanislav
initials: SL
homedirectory: /home/laptevs
gecos: Laptev Stanislav
loginshell: /bin/sh
krbcanonicalname: laptevs@MY-IT-COMPANY.COM
krbprincipalname: laptevs@MY-IT-COMPANY.COM
mail: laptevs@MY-IT-COMPANY.COM
uidnumber: 1344600003
gidnumber: 1344600003
l: Moscow
telephonenumber: +7(863)999-99-99
mobile: +7(999)999-99-99
ou: My-it-company
title: SysAdm
sshpubkeyfp: SHA256:Yi8mKF+j28/r2cpxLgIbvZ/Oymt57rhliHKhqBuJxqE laptevs-putty (ssh-rsa)
nsaccountlock: FALSE
has_password: TRUE
has_keytab: TRUE
displayName: Laptev Stanislav
ipaSshPubKey: c3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBQkpRQUFBZ0VBNjQ1RTJjSjIvWXVVYm9GNzdZY3hLNzBndm1jWlgrZjBZTVpsaXRQVXNCWFZ0cENtTEtwcjRwK2JEeUdhRzNLTWx1T08ydW9wS0pXRk9mWE83Zzl3OTYzdklQblN3MzVHSmI3VGhhbk1pTXpNUE82T1lQZEY0em14b2k4N 0RGYkdXV2V6aGwzcitsbmFGYTB0dEQ5TkFWRU1Fb3BMdmkzcHZ1UXpyVmNjVlMxamFxY1dNT2ZGUC9TRlVoY1dGeVpZd3Z6eW0wWnZObUZtdjVjVHJGNzJMSXZOdHlsNkZGK2ZaU3ZpS01mcXZ6NStkT2xZZGd5bVVSOG5iaVpkTXZKaTIvbzhjTy84ekpoMFhtSnVRSjJXNEVvYVEvajVTTm8ySjZ6NklXNk I3cFB4Y002a0tJcUp5N08zTkNOcGRrVmVQbEFHbThsOFZDREpVa1RLSjRGOS9mSTZFUkhxVUZwK3p1VENTR1R3ZWlKdXppenFSZWJTTkNiMXh3RldmUitvYzFLdWNZSU5QbTYxRi93YXhOcC9aSG9OK2w1dCtkYWI4cElZSGZzTnNUNWx2RWt4Ukh0bnNyeUxsbWk1ZVdzd3RBbDB3TUpWd1cvUWNJcjhOaVN Ybm96Q3dHWTZCaTQ2L0FGTGVidmFLV0tKRmpKZFgxOFlRVDRpVzZGaE83aW40TGlUamlNaENXbStvbjNQbERYeXZpdkJ1WkFXUldXNEdjbXREVW8rSVhZT2t3MWh3UldqdkJtcExHMVZpMFhPckltbmQybTVZdWk1bHo0b1ZlekFRN1NjYVlrdDBoVEdQU1Z2UHpmVlowYWJCQlpiRmViK1hUV2tpSnBPMHBO T3dodGNadHYrN3RMMnc1OFN3QnhVTUk4NzUzdG5Sc1h1blBXZERqcUsxSDA9IGxhcHRldnMtcHV0dHk=
ipaUniqueID: 68d46dac-1d3c-11e9-82fd-0242ac110002
krbExtraData: AAL4VkVcbGFwdGV2c0BPTUlLUk9OLlBSTwA=
krbLastFailedAuth: 20190123084142Z
krbLastPwdChange: 20190121052200Z
krbLoginFailedCount: 0
krbPasswordExpiration: 20190421052200Z
memberof: cn=otrs-admins,cn=groups,cn=accounts,dc=my-it-company,dc=com
memberof: cn=ipausers,cn=groups,cn=accounts,dc=my-it-company,dc=com
mepManagedEntry: cn=laptevs,cn=groups,cn=accounts,dc=my-it-company,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
objectClass: inetuser
objectClass: posixaccount
objectClass: krbprincipalaux
objectClass: krbticketpolicyaux
objectClass: ipaobject
objectClass: ipasshuser
objectClass: ipaSshGroupOfPubKeys
objectClass: mepOriginEntry
uid: laptevs
givenname: Stanislav
sn: Laptev
cn: Laptev Stanislav
initials: SL
homedirectory: /home/laptevs
gecos: Laptev Stanislav
loginshell: /bin/sh
krbcanonicalname: laptevs@MY-IT-COMPANY.COM
krbprincipalname: laptevs@MY-IT-COMPANY.COM
mail: laptevs@MY-IT-COMPANY.COM
uidnumber: 1344600003
gidnumber: 1344600003
l: Moscow
telephonenumber: +7(863)999-99-99
mobile: +7(999)999-99-99
ou: My-it-company
title: SysAdm
sshpubkeyfp: SHA256:Yi8mKF+j28/r2cpxLgIbvZ/Oymt57rhliHKhqBuJxqE laptevs-putty (ssh-rsa)
nsaccountlock: FALSE
has_password: TRUE
has_keytab: TRUE
displayName: Laptev Stanislav
ipaSshPubKey: c3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBQkpRQUFBZ0VBNjQ1RTJjSjIvWXVVYm9GNzdZY3hLNzBndm1jWlgrZjBZTVpsaXRQVXNCWFZ0cENtTEtwcjRwK2JEeUdhRzNLTWx1T08ydW9wS0pXRk9mWE83Zzl3OTYzdklQblN3MzVHSmI3VGhhbk1pTXpNUE82T1lQZEY0em14b2k4N 0RGYkdXV2V6aGwzcitsbmFGYTB0dEQ5TkFWRU1Fb3BMdmkzcHZ1UXpyVmNjVlMxamFxY1dNT2ZGUC9TRlVoY1dGeVpZd3Z6eW0wWnZObUZtdjVjVHJGNzJMSXZOdHlsNkZGK2ZaU3ZpS01mcXZ6NStkT2xZZGd5bVVSOG5iaVpkTXZKaTIvbzhjTy84ekpoMFhtSnVRSjJXNEVvYVEvajVTTm8ySjZ6NklXNk I3cFB4Y002a0tJcUp5N08zTkNOcGRrVmVQbEFHbThsOFZDREpVa1RLSjRGOS9mSTZFUkhxVUZwK3p1VENTR1R3ZWlKdXppenFSZWJTTkNiMXh3RldmUitvYzFLdWNZSU5QbTYxRi93YXhOcC9aSG9OK2w1dCtkYWI4cElZSGZzTnNUNWx2RWt4Ukh0bnNyeUxsbWk1ZVdzd3RBbDB3TUpWd1cvUWNJcjhOaVN Ybm96Q3dHWTZCaTQ2L0FGTGVidmFLV0tKRmpKZFgxOFlRVDRpVzZGaE83aW40TGlUamlNaENXbStvbjNQbERYeXZpdkJ1WkFXUldXNEdjbXREVW8rSVhZT2t3MWh3UldqdkJtcExHMVZpMFhPckltbmQybTVZdWk1bHo0b1ZlekFRN1NjYVlrdDBoVEdQU1Z2UHpmVlowYWJCQlpiRmViK1hUV2tpSnBPMHBO T3dodGNadHYrN3RMMnc1OFN3QnhVTUk4NzUzdG5Sc1h1blBXZERqcUsxSDA9IGxhcHRldnMtcHV0dHk=
ipaUniqueID: 68d46dac-1d3c-11e9-82fd-0242ac110002
krbExtraData: AAL4VkVcbGFwdGV2c0BPTUlLUk9OLlBSTwA=
krbLastFailedAuth: 20190123084142Z
krbLastPwdChange: 20190121052200Z
krbLoginFailedCount: 0
krbPasswordExpiration: 20190421052200Z
memberof: cn=otrs-admins,cn=groups,cn=accounts,dc=my-it-company,dc=com
memberof: cn=ipausers,cn=groups,cn=accounts,dc=my-it-company,dc=com
mepManagedEntry: cn=laptevs,cn=groups,cn=accounts,dc=my-it-company,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
objectClass: inetuser
objectClass: posixaccount
objectClass: krbprincipalaux
objectClass: krbticketpolicyaux
objectClass: ipaobject
objectClass: ipasshuser
objectClass: ipaSshGroupOfPubKeys
objectClass: mepOriginEntry
dn: uid=laptevs,cn=users,cn=accounts,dc=my-it-company,dc=com
uid: laptevs
givenname: Stanislav
sn: Laptev
cn: Laptev Stanislav
mail: laptevs@MY-IT-COMPANY.COM
l: Moscow
telephonenumber: +7(863)999-99-99
mobile: +7(999)999-99-99
ou: My-it-company
title: SysAdm
Настройка конфигурации OTRS
Файлы конфигурации
- /opt/otrs/ — как правило, здесь располагаются файлы системы OTRS
- Kernel/Config.pm — файл конфигурации, который вы редактируете
- Kernel/Config/Defaults.pm — файл со стандартными настройками, его не редактируете, но в нем можно посмотреть все существующие параметры и комментарии к ним
Настройка агентов
Аутентификация агентов
# --------------------------------------------------- #
# Agents authentication #
# --------------------------------------------------- #
# my-it-company.com LDAP backend
$Self->{AuthModule} = 'Kernel::System::Auth::LDAP';
# Адрес LDAP-сервера
$Self->{'AuthModule::LDAP::Host'} = 'my-it-company.com';
$Self->{'AuthModule::LDAP::BaseDN'} = 'dc=my-it-company,dc=com';
$Self->{'AuthModule::LDAP::UID'} = 'uid';
# Блок нужен, только если запрещен анонимный просмотр структуры каталогов
$Self->{'AuthModule::LDAP::SearchUserDN'} = 'uid=ldap-bot,cn=users,cn=accounts,dc=my-it-company,dc=com';
$Self->{'AuthModule::LDAP::SearchUserPw'} = 'bot-password!';
# Фильтр запроса к LDAP. Пусть у нас будут только пользователи, имеющие заполненный атрибут "электронная почта"
$Self->{'AuthModule::LDAP::AlwaysFilter'} = '(mail=*)';
# Добавляем при проблемах с кодировкой
$Self->{'AuthModule::LDAP::Charset'} = 'utf-8';
$Self->{'AuthModule::UseSyncBackend'} = 'AuthSyncBackend';
# my-it-company.com DB backend
$Self->{AuthModule2} = 'Kernel::System::Auth::DB';
$Self->{'AuthModule::DB::CryptType2'} = 'sha2';
# --------------------------------------------------- #
# End Agents authentication #
# --------------------------------------------------- #
Синхронизация агентов (групп LDAP с ролями OTRS)
# --------------------------------------------------- #
# Agent authentication sync #
# (enable agent data sync. after succsessful #
# authentication) #
# --------------------------------------------------- #
# my-it-company.com LDAP auth sync. backend.
$Self->{AuthSyncModule} = 'Kernel::System::Auth::Sync::LDAP';
$Self->{'AuthSyncModule::LDAP::Host'} = 'my-it-company.com';
$Self->{'AuthSyncModule::LDAP::BaseDN'} = 'dc=my-it-company,dc=com';
$Self->{'AuthSyncModule::LDAP::UID'} = 'uid';
$Self->{'AuthSyncModule::LDAP::SearchUserDN'} = 'uid=ldap-bot,cn=users,cn=accounts,dc=my-it-company,dc=com';
$Self->{'AuthSyncModule::LDAP::SearchUserPw'} = 'bot-password!';
$Self->{'AuthSyncModule::LDAP::AlwaysFilter'} = '(mail=*)';
$Self->{'AuthSyncModule::LDAP::UserSyncMap'} = {
# DB -> LDAP
UserFirstname => 'givenName',
UserLastname => 'sn',
UserEmail => 'mail',
};
$Self->{'AuthSyncModule::LDAP::AccessAttr'} = 'member';
$Self->{'AuthSyncModule::LDAP::UserAttr'} = 'DN';
$Self->{'AuthSyncModule::LDAP::UserSyncRolesDefinition'} = {
# ldap group
'cn=otrs-sa,cn=groups,cn=accounts,dc=my-it-company,dc=com' => {
# otrs role
'otrs-sa' => 1,
},
'cn=otrs-admins,cn=groups,cn=accounts,dc=my-it-company,dc=com' => {
'otrs-admins' => 1,
},
'cn=otrs-helpdesk,cn=groups,cn=accounts,dc=my-it-company,dc=com' => {
'helpdesk' => 1,
}
};
$Self->{DatabaseUserTable} = 'users';
$Self->{DatabaseUserTableUserID} = 'id';
$Self->{DatabaseUserTableUserPW} = 'pw';
$Self->{DatabaseUserTableUser} = 'login';
# --------------------------------------------------- #
# End Agents authentication sync #
# --------------------------------------------------- #
Если вы решили, что роли вам не подходят, и вы хотите только группы, приведу два примера синхронизации групп LDAP с группами OTRS — упрощенный и с настройкой прав по каждой группе.
Альтернативная синхронизация агентов (групп LDAP с группами OTRS, с указанием прав)
# --------------------------------------------------- #
# Agent authentication sync #
# (enable agent data sync. after succsessful #
# authentication) #
# --------------------------------------------------- #
# my-it-company.com LDAP auth sync. backend.
$Self->{AuthSyncModule} = 'Kernel::System::Auth::Sync::LDAP';
$Self->{'AuthSyncModule::LDAP::Host'} = 'my-it-company.com';
$Self->{'AuthSyncModule::LDAP::BaseDN'} = 'dc=my-it-company,dc=com';
$Self->{'AuthSyncModule::LDAP::UID'} = 'uid';
$Self->{'AuthSyncModule::LDAP::SearchUserDN'} = 'uid=ldap-bot,cn=users,cn=accounts,dc=my-it-company,dc=com';
$Self->{'AuthSyncModule::LDAP::SearchUserPw'} = 'bot-password!';
$Self->{'AuthSyncModule::LDAP::AlwaysFilter'} = '(mail=*)';
$Self->{'AuthSyncModule::LDAP::UserSyncMap'} = {
# DB -> LDAP
UserFirstname => 'givenName',
UserLastname => 'sn',
UserEmail => 'mail',
};
$Self->{'AuthSyncModule::LDAP::AccessAttr'} = 'member';
$Self->{'AuthSyncModule::LDAP::UserAttr'} = 'DN';
# AuthSyncModule::LDAP::UserSyncGroupsDefinition
# (If "LDAP" was selected for AuthModule and you want to sync LDAP
# groups to otrs groups, define the following.)
$Self->{'AuthSyncModule::LDAP::UserSyncGroupsDefinition'} = {
# ldap group
'cn=otrs-admins,cn=groups,cn=accounts,dc=my-it-company,dc=com' => {
# otrs group
'admin' => {
# permission
rw => 1,
move_into => 1,
create => 1,
note => 1,
owner => 1,
prioriry => 1,
ro => 1,
},
'stats' => {
rw => 1,
move_into => 1,
create => 1,
note => 1,
owner => 1,
prioriry => 1,
ro => 1,
},
'users' => {
rw => 1,
move_into => 1,
create => 1,
note => 1,
owner => 1,
prioriry => 1,
ro => 1,
},
'pear-group' => {
rw => 1,
move_into => 1,
create => 1,
note => 1,
owner => 1,
prioriry => 1,
ro => 1,
},
'macrohard-group' => {
rw => 1,
move_into => 1,
create => 1,
note => 1,
owner => 1,
prioriry => 1,
ro => 1,
},
},
'cn=otrs-helpdesk,cn=groups,cn=accounts,dc=my-it-company,dc=com' => {
'stats' => {
rw => 1,
move_into => 1,
create => 1,
note => 1,
owner => 1,
prioriry => 1,
ro => 1,
},
'users' => {
rw => 1,
move_into => 1,
create => 1,
note => 1,
owner => 1,
prioriry => 1,
ro => 1,
},
}
};
$Self->{DatabaseUserTable} = 'users';
$Self->{DatabaseUserTableUserID} = 'id';
$Self->{DatabaseUserTableUserPW} = 'pw';
$Self->{DatabaseUserTableUser} = 'login';
# --------------------------------------------------- #
# End Agents authentication sync #
# --------------------------------------------------- #
Альтернативная упрощенная синхронизация агентов (групп LDAP с ролями OTRS с правами rw)
# --------------------------------------------------- #
# Agent authentication sync #
# (enable agent data sync. after succsessful #
# authentication) #
# --------------------------------------------------- #
# my-it-company.com LDAP auth sync. backend.
$Self->{AuthSyncModule} = 'Kernel::System::Auth::Sync::LDAP';
$Self->{'AuthSyncModule::LDAP::Host'} = 'my-it-company.com';
$Self->{'AuthSyncModule::LDAP::BaseDN'} = 'dc=my-it-company,dc=com';
$Self->{'AuthSyncModule::LDAP::UID'} = 'uid';
$Self->{'AuthSyncModule::LDAP::SearchUserDN'} = 'uid=ldap-bot,cn=users,cn=accounts,dc=my-it-company,dc=com';
$Self->{'AuthSyncModule::LDAP::SearchUserPw'} = 'bot-password!';
$Self->{'AuthSyncModule::LDAP::AlwaysFilter'} = '(mail=*)';
$Self->{'AuthSyncModule::LDAP::UserSyncMap'} = {
# DB -> LDAP
UserFirstname => 'givenName',
UserLastname => 'sn',
UserEmail => 'mail',
};
$Self->{'AuthSyncModule::LDAP::AccessAttr'} = 'member';
$Self->{'AuthSyncModule::LDAP::UserAttr'} = 'DN';
# Включать агента в какие-либо группы с доступом на чтение/запись
# AuthSyncModule::LDAP::UserSyncInitialGroups
# (sync following group with rw permission after initial create of first agent
# login)
$Self->{'AuthSyncModule::LDAP::UserSyncInitialGroups'} = [
'users',
];
$Self->{DatabaseUserTable} = 'users';
$Self->{DatabaseUserTableUserID} = 'id';
$Self->{DatabaseUserTableUserPW} = 'pw';
$Self->{DatabaseUserTableUser} = 'login';
# --------------------------------------------------- #
# End Agents authentication sync #
# --------------------------------------------------- #
Настройка клиентов
Аутентификация клиентов
# --------------------------------------------------- #
# Сustomer authentication #
# --------------------------------------------------- #
# Сustomer DB auth. backend
$Self->{'Customer::AuthModule'} = 'Kernel::System::CustomerAuth::DB';
$Self->{'Customer::AuthModule::DB::Table'} = 'customer_user';
$Self->{'Customer::AuthModule::DB::CustomerKey'} = 'login';
$Self->{'Customer::AuthModule::DB::CustomerPassword'} = 'pw';
# my-it-company.com (Сustomer) LDAP auth. backend
$Self->{'Customer::AuthModule2'} = 'Kernel::System::CustomerAuth::LDAP';
$Self->{'Customer::AuthModule::LDAP::Host2'} = 'my-it-company.com';
$Self->{'Customer::AuthModule::LDAP::BaseDN2'} = 'dc=my-it-company,dc=com';
$Self->{'Customer::AuthModule::LDAP::UID2'} = 'uid';
$Self->{'Customer::AuthModule::LDAP::SearchUserDN2'} = 'uid=ldap-bot,cn=users,cn=accounts,dc=my-it-company,dc=com';
$Self->{'Customer::AuthModule::LDAP::SearchUserPw2'} = 'bot-password!';
$Self->{'Customer::AuthModule::LDAP::AlwaysFilter2'} = '(mail=*)';
# pear LDAP auth. backend.
$Self->{'Customer::AuthModule3'} = 'Kernel::System::CustomerAuth::LDAP';
$Self->{'Customer::AuthModule::LDAP::Host3'} = 'pear.com';
$Self->{'Customer::AuthModule::LDAP::BaseDN3'} = 'DC=pear,DC=com';
$Self->{'Customer::AuthModule::LDAP::UID3'} = 'sAMAccountName';
$Self->{'Customer::AuthModule::LDAP::SearchUserDN3'} = 'ldap-bot@pear.com';
$Self->{'Customer::AuthModule::LDAP::SearchUserPw3'} = 'bot-password?';
# Отфильтруем: (mail=*) - у кого есть почта и (samAccountType=805306368) - учетная запись пользователя и (!(userAccountControl:1.2.840.113556.1.4.803:=2)) - не отключена
$Self->{'Customer::AuthModule::LDAP::AlwaysFilter3'} = '(&(mail=*)(samAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))';
# macrohard LDAP auth. backend.
$Self->{'Customer::AuthModule4'} = 'Kernel::System::CustomerAuth::LDAP';
$Self->{'Customer::AuthModule::LDAP::Host4'} = 'macrohard.com';
$Self->{'Customer::AuthModule::LDAP::BaseDN4'} = 'dc=macrohard,dc=com';
$Self->{'Customer::AuthModule::LDAP::UID4'} = 'sAMAccountName';
$Self->{'Customer::AuthModule::LDAP::SearchUserDN4'} = 'ldap-bot@macrohard.com';
$Self->{'Customer::AuthModule::LDAP::SearchUserPw4'} = 'bot-password!?';
$Self->{'Customer::AuthModule::LDAP::AlwaysFilter4'} = '(&(mail=*)(samAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))';
# --------------------------------------------------- #
# End customer authentication settings #
# --------------------------------------------------- #
Синхронизация клиентов (получение атрибутов клиента из LDAP, связь с компаниями OTRS)
# --------------------------------------------------- #
# Customer authentication sync #
# --------------------------------------------------- #
# Customer user DB backend and settings
$Self->{CustomerUser} = {
Name => Translatable('Database Backend'),
Module => 'Kernel::System::CustomerUser::DB',
Params => {
Table => 'customer_user',
SearchCaseSensitive => 0,
},
# customer unique id
CustomerKey => 'login',
# customer #
CustomerID => 'customer_id',
CustomerValid => 'valid_id',
CustomerUserListFields => [ 'first_name', 'last_name', 'email' ],
CustomerUserSearchFields => [ 'login', 'first_name', 'last_name', 'customer_id' ],
CustomerUserSearchPrefix => '*',
CustomerUserSearchSuffix => '*',
CustomerUserSearchListLimit => 250,
CustomerUserPostMasterSearchFields => ['email'],
CustomerUserNameFields => [ 'title', 'first_name', 'last_name' ],
CustomerUserEmailUniqCheck => 1,
CustomerCompanySupport => 1,
CacheTTL => 60 * 60 * 24,
Map => [
[ 'UserTitle', Translatable('Title or salutation'), 'title', 1, 0, 'var', '', 0, undef, undef ],
[ 'UserFirstname', Translatable('Firstname'), 'first_name', 1, 1, 'var', '', 0, undef, undef ],
[ 'UserLastname', Translatable('Lastname'), 'last_name', 1, 1, 'var', '', 0, undef, undef ],
[ 'UserLogin', Translatable('Username'), 'login', 1, 1, 'var', '', 0, undef, undef ],
[ 'UserPassword', Translatable('Password'), 'pw', 0, 0, 'var', '', 0, undef, undef ],
[ 'UserEmail', Translatable('Email'), 'email', 1, 1, 'var', '', 0, undef, undef ],
[ 'UserCustomerID', Translatable('CustomerID'), 'customer_id', 0, 1, 'var', '', 0, undef, undef ],
[ 'UserPhone', Translatable('Phone'), 'phone', 1, 0, 'var', '', 0, undef, undef ],
[ 'UserFax', Translatable('Fax'), 'fax', 1, 0, 'var', '', 0, undef, undef ],
[ 'UserMobile', Translatable('Mobile'), 'mobile', 1, 0, 'var', '', 0, undef, undef ],
[ 'UserStreet', Translatable('Street'), 'street', 1, 0, 'var', '', 0, undef, undef ],
[ 'UserZip', Translatable('Zip'), 'zip', 1, 0, 'var', '', 0, undef, undef ],
[ 'UserCity', Translatable('City'), 'city', 1, 0, 'var', '', 0, undef, undef ],
[ 'UserCountry', Translatable('Country'), 'country', 1, 0, 'var', '', 0, undef, undef ],
[ 'UserComment', Translatable('Comment'), 'comments', 1, 0, 'var', '', 0, undef, undef ],
[ 'ValidID', Translatable('Valid'), 'valid_id', 0, 1, 'int', '', 0, undef, undef ],
],
# default selections
Selections => {
# UserTitle => {
# 'Mr.' => Translatable('Mr.'),
# 'Mrs.' => Translatable('Mrs.'),
# },
},
};
# my-it-company.com customer user ldap backend and settings
$Self->{CustomerUser2} = {
Name => 'AD my-it-company.com',
Module => 'Kernel::System::CustomerUser::LDAP',
Params => {
# ldap host
Host => 'my-it-company.com',
# ldap base dn
BaseDN => 'dc=my-it-company,dc=com',
# search scope (one|sub)
SSCOPE => 'sub',
UserDN => 'uid=ldap-bot,cn=users,cn=accounts,dc=my-it-company,dc=com',
UserPw => 'bot-password!',
# in case you want to add always one filter to each ldap query, use
# this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)'
AlwaysFilter => '(mail=*)',
SourceCharset => 'utf-8',
Die => 0,
},
# customer unique id
CustomerKey => 'uid',
# customer #
CustomerID => 'ou',
CustomerUserListFields => ['uid', 'cn', 'mail'],
CustomerUserSearchFields => ['uid', 'cn', 'mail'],
CustomerUserSearchPrefix => '',
CustomerUserSearchSuffix => '*',
CustomerUserSearchListLimit => 250,
CustomerUserPostMasterSearchFields => ['mail'],
CustomerUserNameFields => ['sn', 'givenname'],
# Configures the character for joining customer user name parts. Join single space if it is not defined.
CustomerUserNameFieldsJoin => ' ',
# show customer user and customer tickets in customer interface
CustomerUserExcludePrimaryCustomerID => 0,
# add a ldap filter for valid users (expert setting)
# CustomerUserValidFilter => '(!(description=gesperrt))',
# admin can't change customer preferences
AdminSetPreferences => 1,
# cache time to live in sec. - cache any ldap queries
CacheTTL => 0,
Map => [
[ 'UserTitle', Translatable('Title or salutation'), 'title', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserFirstname', Translatable('Firstname'), 'givenname', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserLastname', Translatable('Lastname'), 'sn', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserLogin', Translatable('Username'), 'uid', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserEmail', Translatable('Email'), 'mail', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserCustomerID', Translatable('CustomerID'), 'ou', 0, 1, 'var', '', 1, undef, undef ],
[ 'UserPhone', Translatable('Phone'), 'telephonenumber', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserMobile', Translatable('Mobile'), 'mobile', 1, 0, 'var', '', 1, undef, undef ],
],
};
# pear customer user ldap backend and settings
$Self->{CustomerUser3} = {
Name => 'AD pear',
Module => 'Kernel::System::CustomerUser::LDAP',
Params => {
# ldap host
Host => 'pear.com',
BaseDN => 'DC=pear,DC=com',
SSCOPE => 'sub',
UserDN => 'ldap-bot@pear.com',
UserPw => 'bot-password?',
AlwaysFilter => '(&(mail=*)(samAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))',
SourceCharset => 'utf-8',
Die => 0,
},
# customer unique id
CustomerKey => 'sAMAccountName',
# customer #
CustomerID => 'company',
CustomerUserListFields => ['sAMAccountName', 'cn', 'mail'],
CustomerUserSearchFields => ['sAMAccountName', 'cn', 'mail'],
CustomerUserSearchPrefix => '',
CustomerUserSearchSuffix => '*',
CustomerUserSearchListLimit => 250,
CustomerUserPostMasterSearchFields => ['mail'],
CustomerUserNameFields => ['sn', 'givenname'],
# Configures the character for joining customer user name parts. Join single space if it is not defined.
CustomerUserNameFieldsJoin => ' ',
# show customer user and customer tickets in customer interface
CustomerUserExcludePrimaryCustomerID => 0,
AdminSetPreferences => 1,
CacheTTL => 0,
Map => [
# note: Login, Email and CustomerID needed!
# var, frontend, storage, shown (1=always,2=lite), required, storage-type, http-link, readonly, http-link-target, link class(es)
[ 'UserTitle', Translatable('Title or salutation'), 'title', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserFirstname', Translatable('Firstname'), 'givenname', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserLastname', Translatable('Lastname'), 'sn', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserLogin', Translatable('Username'), 'sAMAccountName', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserFullLogin', Translatable('FullUsername'), 'userPrincipalName', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserEmail', Translatable('Email'), 'mail', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserCustomerID', Translatable('CustomerID'), 'company', 0, 1, 'var', '', 1, undef, undef ],
[ 'UserPhone', Translatable('Phone'), 'telephoneNumber', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserMobile', Translatable('Mobile'), 'mobile', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserAddress', Translatable('Address'), 'postaladdress', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserOffice', Translatable('Office'), 'physicalDeliveryOfficeName', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserDepartment', Translatable('Department'), 'department', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserComment', Translatable('Comment'), 'description', 1, 0, 'var', '', 1, undef, undef ],
],
};
# macrohard customer user ldap backend and settings
$Self->{CustomerUser4} = {
Name => 'AD macrohard',
Module => 'Kernel::System::CustomerUser::LDAP',
Params => {
# ldap host
Host => 'macrohard.com',
# ldap base dn
BaseDN => 'dc=macrohard,dc=com',
# search scope (one|sub)
SSCOPE => 'sub',
UserDN => 'ldap-bot@macrohard.com',
UserPw => 'bot-password!?',
AlwaysFilter => '(&(mail=*)(samAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))',
SourceCharset => 'utf-8',
Die => 0,
},
# customer unique id
CustomerKey => 'sAMAccountName',
# customer #
CustomerID => 'company',
CustomerUserListFields => ['sAMAccountName', 'cn', 'mail'],
CustomerUserSearchFields => ['sAMAccountName', 'cn', 'mail'],
CustomerUserSearchPrefix => '',
CustomerUserSearchSuffix => '*',
CustomerUserSearchListLimit => 250,
CustomerUserPostMasterSearchFields => ['mail'],
CustomerUserNameFields => ['sn', 'givenname'],
# Configures the character for joining customer user name parts. Join single space if it is not defined.
CustomerUserNameFieldsJoin => ' ',
# show customer user and customer tickets in customer interface
CustomerUserExcludePrimaryCustomerID => 0,
AdminSetPreferences => 1,
CacheTTL => 0,
Map => [
[ 'UserTitle', Translatable('Title or salutation'), 'title', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserFirstname', Translatable('Firstname'), 'givenname', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserLastname', Translatable('Lastname'), 'sn', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserLogin', Translatable('Username'), 'sAMAccountName', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserFullLogin', Translatable('FullUsername'), 'userPrincipalName', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserEmail', Translatable('Email'), 'mail', 1, 1, 'var', '', 1, undef, undef ],
[ 'UserCustomerID', Translatable('CustomerID'), 'company', 0, 1, 'var', '', 1, undef, undef ],
[ 'UserPhone', Translatable('Phone'), 'telephoneNumber', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserMobile', Translatable('Mobile'), 'mobile', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserAddress', Translatable('Address'), 'postaladdress', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserOffice', Translatable('Office'), 'physicalDeliveryOfficeName', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserDepartment', Translatable('Department'), 'department', 1, 0, 'var', '', 1, undef, undef ],
[ 'UserComment', Translatable('Comment'), 'description', 1, 0, 'var', '', 1, undef, undef ],
],
};
Заключение
Как вы увидели, настройка аутентификации и синхронизации аккаунтов в OTRS — это очень просто, но все же надеюсь, что эта статья поможет тем, кто только начинает знакомиться с этой системой.
Что осталось за бортом этой статьи?
- Параллельно с LDAP можно также запустить SSO-авторизацию, что еще упростит жизнь клиентам
- Если есть специалисты по Perl — можно написать собственные backend для подключения к другим информационным системам.
- Сознательно упрощена конфигурация, например, нет блоков фильтрации по принадлежности к группам LDAP, нет доменных суффиксов, BASE DN, работы с дополнительными атрибутами, работы с LDAP на других портах и много другого
Советы и уточнения приветствуются комментариях, информация об опечатках — в ЛС.
Спасибо за внимание. Отдельное спасибо авторам, чьи материалы по OTRS я использовал много лет назад при знакомстве с этой системой: Turilion, supersuperoleg, wmlex