Автентифікація через PAM може проходити, коли ви запускаєте клієнт вручну, і зазнавати невдачі з AUTH_FAILED, щойно systemd запускає той самий профіль. Пароль між цими запусками не змінюється; змінюється набір обмежень навколо процесу, який ставить PAM питання. PAM відповідає через помічник, чия здатність змінювати власні облікові дані — саме те, що вилучено в укріпленому unit. Знайдіть цей помічник і межу, яка йому потрібна, перш ніж торкатися списку можливостей.

unix_chkpwd — це двійковий файл, який відповідає на питання PAM

За локальної автентифікації паролем pam_unix рідко читає файл хешів сам. Він запускає unix_chkpwd, який дистрибутиви встановлюють як setuid root або setgid shadow, щоб один пароль можна було перевірити від імені процесу, якому нема чого читати /etc/shadow. Заберіть можливість отримати цю ідентичність — і помічник не завершить перевірку, тож модуль поверне звичайну помилку автентифікації.

Тоді збій у кожному журналі, який бачить клієнт, виглядає як проблема з обліковими даними. Ось пастка: клієнт повідомляє те, що йому сказав PAM, а PAM повідомляє лише те, що стек сказав «ні». Запуск помічника вручну від root теж нічого не доводить, бо він проходить шлях привілеїв, який служба ніколи не використовує. Прочитайте unit, який systemd справді завантажив, а потім системний журнал про зроблену спробу. Ці два погляди відокремлюють проблему пісочниці від проблеми неправильного пароля.

Прочитайте unit, перш ніж читати журнал паролів

Пакувальний unit може нести drop-in, якого ви не писали, а чинна конфігурація — це результат злиття. Надрукуйте unit так, як його бачить systemd, разом із налаштуваннями пісочниці, які визначають, чи може помічник підняти власні привілеї. На цьому етапі достатньо огляду лише для читання.

systemctl cat [email protected]
systemctl show [email protected] -p User -p Group -p CapabilityBoundingSet -p AmbientCapabilities -p NoNewPrivileges
journalctl -u [email protected] -b

Перша команда показує, звідки походять unit і його drop-in, що важливо, бо перевизначення, додане місяці тому, живе довше за пам’ять про те, навіщо воно існує. Друга друкує значення пісочниці, від яких залежать два наступні розділи.

Порівняйте побачене з робочим вузлом того самого дистрибутива й версії. Різниця в User, CapabilityBoundingSet або NoNewPrivileges — конкретна зачіпка; різниця в пояснювальних коментарях — ні. Запишіть значення, перш ніж щось змінювати, бо пізніше порівняння з рухомою ціллю нічого не доводить. Якщо служба працює як непривілейований обліковий запис із порожнім обмежувальним набором, помічникові майже нема з чим працювати.

Перетворення облікових даних, доступ до файлів і політика — це три межі

Почніть із того, що відбувається під час exec. Двійковий файл setuid або файл із file capabilities спричиняє перетворення облікових даних, тому отримана ідентичність не є продовженням того, хто викликав. Обмежувальний набір обмежує те, що такий файл може отримати, а NoNewPrivileges повністю блокує отримання setuid, setgid і file capabilities. Будь-яке з цих трьох може зупинити помічник, залишивши недоторканою кожну іншу функцію служби.

Далі відокремте широкий обхід дискреційних перевірок від вузького доступу на читання. CAP_DAC_OVERRIDE пропускає дискреційні перевірки майже всюди, тоді як CAP_DAC_READ_SEARCH охоплює читання й обхід каталогів зі своїми додатковими повноваженнями. Це різні інструменти з різним радіусом дії, і жоден із них не є способом написати нехай PAM читає файл shadow.

Нарешті, запитайте, чи обов’язкова політика взагалі дозволяє цю дію. Можливість Linux не скасовує SELinux, і її наявність нічого не доводить про правило примусового контролю типів. Розглядайте відмову в доступі до файлу й відмову в можливості як різні докази, бо вони називають різні виправлення і часто різних власників. Читайте кожне поле запису, а не саме лише слово denied. Яка виконувана програма вчинила дію, у якому домені вона працювала, якого типу цілі торкнулася, який клас об’єкта був задіяний і який дозвіл відкинула політика — кожне з цього звужує відповідь по-своєму.

Витягніть відмову з журналу аудиту

На вузлі в режимі enforcing журнал аудиту — єдине місце, де фіксується відмова. Запитайте останні події й читайте їх щодо мітки часу невдалого входу, а не щодо часу, коли ви почали розслідування.

ausearch -m AVC,USER_AVC -ts recent

Порожній результат не є доказом невинності. Він означає або що аудит не збирає даних, або що ваше вікно пропустило спробу, і обидві можливості треба виключити, перш ніж виключати політику.

Настанова Red Hat щодо усунення несправностей SELinux ставить перевірки міток і конфігурації перед генерацією дозвільних правил, і для цієї проблеми це теж правильний порядок. Неправильно позначений двійковий файл помічника й прогалина в політиці дають схожі відмови, але потребують різних виправлень. Генерація дозвільного правила для помилки мітки приховує дефект і дозволяє наступному оновленню пакунка повернути його. Підтвердьте мітку на встановленому помічнику, перш ніж писати будь-яку політику.

Доведіть зміну одним прийнятим і одним відхиленим входом

Змініть лише ту межу, яку ви продемонстрували, потім перевірте обидва результати. Обліковий запис, який має автентифікуватися, мусить успішно увійти, а запис із неправильним паролем мусить і далі зазнавати невдачі. Зміна, після якої проходить кожна спроба, усунула автентифікацію, а не виправила її.

Виконайте реальну спробу з’єднання й одразу після неї прочитайте журнал. Рядок, що доводить виправлення, — це запис pam_unix(openvpn:auth) для цієї спроби: там має бути успіх автентифікації, і жоден запис AVC не повинен припадати на ту саму секунду.

journalctl -u [email protected] -n 30 --no-pager
ss -tnp | grep openvpn

Робочому тунелю потрібне й повторне з’єднання, бо зміни пісочниці ламають друге з’єднання частіше за перше. Перевірте встановлений сокет після повторного з’єднання й підтвердьте, що його досі обслуговує той самий unit.

Схожі статті