На сцені знову лауреати міжнародних конкурсів SSH та sudo. Під керівництвом заслуженого диригента Active Directory

Історично склалося, що sudo права регулювалися вмістом файлів з /etc/sudoers.d и видудо, А авторизація за ключами велася з використанням ~/.ssh/авторизовані_ключі. Однак із зростанням інфраструктури виникає бажання керувати цими правами централізовано. На сьогоднішній день варіантів рішення може бути декілька:

  • Система управління конфігурацією - шеф-кухар, Ляльковий, Неможливо, Сіль
  • Active Directory + ssd
  • Різноманітні збочення у вигляді скриптів та ручного редагування файлів

На мій суб'єктивний погляд, оптимальним варіантом централізованого управління є все-таки зв'язування Active Directory + ssd. Переваги цього підходу ось у чому:

  • Справді Єдиний централізований каталог користувачів.
  • Роздача прав Суду зводиться до додавання користувача до певної групи безпеки.
  • У разі різних Linux-систем виникає потреба вводити додаткові перевірки визначення ОС під час використання систем конфігурації.

Сьогоднішня сюїта буде присвячена саме зв'язці Active Directory + ssd для управління правами Суду та зберіганням SSH ключів у єдиному репозиторії.
Отже, зал завмер у напруженому мовчанні, диригент підняв паличку, оркестр приготувався.
Поїхали.

дано:
— Домен Active Directory testopf.local Windows Server 2012 R2.
- Linux хост під керуванням Centos 7
- Налагоджена авторизація з використанням ssd
Обидва рішення вносять зміни до схеми Active DirectoryТому перевіряємо все на тестовому оточенні і тільки потім вносимо зміни до робочої інфраструктури. Хочу зауважити — усі зміни точкові та, по суті, додають лише необхідні атрибути та класи.

Дія 1: керування Суду ролями через Active Directory.

Для розширення схеми Active Directory необхідно завантажити останній реліз Суду - 1.8.27 на сьогоднішній день. Розпаковуємо, копіюємо файл schema.ActiveDirectory з каталогу ./doc на контролер домену. З командного рядка з правами адміністратора з директорії, куди скопіювали файл, запускаємо:
ldifde -i -f schema.ActiveDirectory -c dc=X dc=testopf,dc=local
(Не забуваємо підставляти свої значення)
Відкриваємо adsiedit.msc та підключаємося до контексту за замовчуванням:
У корені домену створюємо підрозділ судоєри. (Буржуїни наполегливо стверджують, що саме у цьому підрозділі демон ssd здійснює пошук на предмет sudoRole об'єктів. Однак, після включення детального дебагу та вивчення логів, було виявлено, що пошук здійснюється по всьому дереву каталогу.)
Створюємо у підрозділі перший об'єкт, що належить класу sudoRole. Ім'я може бути обране абсолютно довільно, оскільки служить виключно для зручної ідентифікації.
Серед можливих доступних атрибутів із розширення схеми основними є:

  • sudoCommand - Визначає, які команди дозволені до виконання на хості.
  • sudoHost - Визначає для яких хостів застосовується дана роль. Може бути задано як ALL, і для окремого хоста на ім'я. Також можливе використання маски.
  • sudoUser - Вказуємо, яким користувачам дозволено виконання Суду.
    У разі вказівки групи безпеки на початку імені додаємо знак “%”. Якщо в імені групи присутні прогалини, турбуватися нема про що. Судячи з логів, завдання екранування прогалин бере на себе механізм ssd.

На сцені знову лауреати міжнародних конкурсів SSH та sudo. Під керівництвом заслуженого диригента Active Directory
рис 1. Об'єкти sudoRole у підрозділі sudoers у корені каталогу

На сцені знову лауреати міжнародних конкурсів SSH та sudo. Під керівництвом заслуженого диригента Active Directory
Рис 2. Членство в групах безпеки, вказаних у судороле-об'єктах.

Наступне налаштування виконується на боці Linux.
У файлі /etc/nsswitch.conf додаємо в кінець файлу рядок:

sudoers: files sss

У файлі /etc/sssd/sssd.conf у секції [sssd] до сервісів додаємо Суду

cat /etc/sssd/sssd.conf | grep services
services = nss, pam, sudo

Після всіх операцій потрібно очистити кеш sssd демона. Автоматичне оновлення проводиться раз на 6 годин, але навіщо нам стільки чекати, коли ми хочемо вже зараз.

sss_cache -E

Часто трапляється так, що очищення кешу не допомагає. Тоді зупиняємо сервіс, чистимо базу, стартуємо сервіс.

service sssd stop
rm -rf /var/lib/sss/db/*
service sssd start

Підключаємося під першим користувачем та перевіряємо, що йому доступно з-під sudo:

su user1
[user1@testsshad log]$ id
uid=1109801141(user1) gid=1109800513(domain users) groups=1109800513(domain users),1109801132(admins_)
[user1@testsshad log]$ sudo -l
[sudo] password for user1:
Matching Defaults entries for user1 on testsshad:
    !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin,
    env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS",
    env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE",
    env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES",
    env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE",
    env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
    secure_path=/sbin:/bin:/usr/sbin:/usr/bin

User user1 may run the following commands on testsshad:
    (root) /usr/bin/ls, /usr/bin/cat

Те саме проробляємо з другим нашим користувачем:

su user2
[user2@testsshad log]$ id
uid=1109801142(user2) gid=1109800513(domain users) groups=1109800513(domain users),1109801138(sudo_root)
[user2@testsshad log]$ sudo -l
Matching Defaults entries for user2 on testsshad:
    !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin,
    env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS",
    env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE",
    env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES",
    env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE",
    env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
    secure_path=/sbin:/bin:/usr/sbin:/usr/bin

User user2 may run the following commands on testsshad:
    (root) ALL

Подібний підхід дозволяє централізовано визначати ролі sudo для різних груп користувачів.

Зберігання та використання ssh ключів у Active Directory

При невеликому розширенні схеми можна зберігати ключі ssh в атрибутах користувача Active Directory і використовувати їх при авторизації на хостах Linux.

Повинна бути настроєна авторизація через sssd.
Додаємо потрібний атрибут за допомогою скрипта PowerShell.
AddsshPublicKeyAttribute.ps1Function New-AttributeID {
$Prefix=«1.2.840.113556.1.8000.2554»
$GUID=[System.Guid]::NewGuid().ToString()
$Parts=@()
$Parts+=[UInt64]::Parse($guid.SubString(0,4),«AllowHexSpecifier»)
$Parts+=[UInt64]::Parse($guid.SubString(4,4),«AllowHexSpecifier»)
$Parts+=[UInt64]::Parse($guid.SubString(9,4),«AllowHexSpecifier»)
$Parts+=[UInt64]::Parse($guid.SubString(14,4),«AllowHexSpecifier»)
$Parts+=[UInt64]::Parse($guid.SubString(19,4),«AllowHexSpecifier»)
$Parts+=[UInt64]::Parse($guid.SubString(24,6),«AllowHexSpecifier»)
$Parts+=[UInt64]::Parse($guid.SubString(30,6),«AllowHexSpecifier»)
$oid=[String]::Format(«{0}.{1}.{2}.{3}.{4}.{5}.{6}.{7}»,$prefix,$Parts[0],
$Parts[1],$Parts[2],$Parts[3],$Parts[4],$Parts[5],$Parts[6])
$oid
}
$schemaPath = (Get-ADRootDSE).schemaNamingContext
$oid = New-AttributeID
$attributes = @{
lDAPDisplayName = 'sshPublicKey';
attributeId = $oid;
oMSyntax = 22;
attributeSyntax = "2.5.5.5";
isSingleValued = $true;
adminDescription = 'User Public key for SSH login';
}

New-ADObject -Name sshPublicKey -Type attributeSchema -Path $schemapath -OtherAttributes $attributes
$userSchema = get-adobject -SearchBase $schemapath -Filter 'name -eq 'user''
$userSchema | Set-ADObject -Add @{mayContain = 'sshPublicKey'}

Після додавання атрибута потрібно перезапустити службу Active Directory Domain Services.
Переходимо до користувачів Active Directory. У будь-який зручний для Вас спосіб генеруємо пару ключів для ssh підключення.
Запускаємо PuttyGen, натискаємо кнопочку «Generate» і судомно елозимо мишею в межах порожньої області.
Після завершення процесу ми можемо зберегти публічні та приватні ключі, залити публічний ключ в атрибут користувача Active Directory та насолоджуватися процесом. Однак публічний ключ необхідно використовувати із вікна «Public key for pasting into OpenSSH authorized_keys file:".
На сцені знову лауреати міжнародних конкурсів SSH та sudo. Під керівництвом заслуженого диригента Active Directory
Додаємо ключ до атрибуту користувача.
Варіант 1 - GUI:
На сцені знову лауреати міжнародних конкурсів SSH та sudo. Під керівництвом заслуженого диригента Active Directory
Варіант 2 - PowerShell:
get-aduser user1 | set-aduser -add @{sshPublicKey = 'AAAAB...XAVnX9ZRJJ0p/Q=='}
Отже, ми маємо на даний момент: користувач із заповненим атрибутом sshPublicKey, налаштований клієнт Putty для авторизації за ключами. Залишається один невеликий момент, як змусити демон sshd витягувати потрібний нам публічний ключ з атрибутів користувача. Із цим успішно справляється невеликий скрипт, знайдений на просторах буржуазного інтернету.

cat /usr/local/bin/fetchSSHKeysFromLDAP
#!/bin/sh
ldapsearch -h testmdt.testopf.local -xb "dc=testopf,dc=local" '(sAMAccountName='"${1%@*}"')' -D [email protected] -w superSecretPassword 'sshPublicKey' | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/n *//g;s/sshPublicKey: //gp'

Виставляємо на нього права 0500 для root.

chmod 0500  /usr/local/bin/fetchSSHKeysFromLDAP

У цьому прикладі для бінда до каталогу використовується обліковий запис адміністратора. У бойових умовах має бути окремий обліковий запис із мінімальним набором прав.
Мене особисто дуже бентежив момент пароля у чистому вигляді у скрипті, незважаючи на виставлені права.
Варіант рішення:

  • Зберігаю пароль в окремий файл:
    echo -n Supersecretpassword > /usr/local/etc/secretpass

  • Виставляю права на файл 0500 для root
    chmod 0500 /usr/local/etc/secretpass

  • Змінюю параметри запуску ldapsearch: параметр -w superSecretPassword Міняю на -y /usr/local/etc/secretpass

Фінальним акордом у сьогоднішній сюїті редагуємо sshd_config

cat /etc/ssh/sshd_config | egrep -v -E "#|^$" | grep -E "AuthorizedKeysCommand|PubkeyAuthe"
PubkeyAuthentication yes
AuthorizedKeysCommand /usr/local/bin/fetchSSHKeysFromLDAP
AuthorizedKeysCommandUser root

Як наслідок, отримуємо наступну послідовність при налаштованій авторизації за ключами у ssh клієнті:

  1. Користувач підключається до сервера, вказуючи власний логін.
  2. Демон sshd через скрипт витягує значення публічного ключа з атрибута користувача Active Directory і проводить авторизацію за ключами.
  3. Демон sssd здійснює подальшу аутентифікацію користувача на підставі приналежності до групи. Увага! Якщо така не налаштована, то будь-який користувач домену матиме доступ до хоста.
  4. При спробі sudo відбувається пошук демоном sssd у каталозі Active Directory щодо ролей. За наявності ролей перевіряються атрибути та членство користувача групи (якщо sudoRoles налаштовані використання груп користувачів)

Підсумок.

Таким чином, ключі зберігаються в атрибутах користувача Active Directory, дозволи sudo — аналогічно, доступ до хостів Linux за доменними обліковими записами здійснюється шляхом перевірки приналежності до групи Active Directory.
Фінальний помах диригентської палички — і зал завмирає у благоговійній тиші.

Ресури, використані для написання:

Sudo via Active Directory
Ssh keys via Active Directory
Powershell script, adding an atribute до Active Directory Schema
sudo stable release

Джерело: habr.com

Додати коментар або відгук