Долгое время работы доказывает лишь то, что запуск удался с теми привилегиями, которые демон имел в тот момент. Отказы, важные здесь, приходят позже: подключается новый клиент, заменяется список отзыва, вспомогательному скрипту нужно записать файл. Каждый из них — это новое открытие, выполняемое учётной записью без привилегий, со своим вопросом о правах и своим сообщением об ошибке. Три решения отделяют конфигурацию, которая продолжает работать, от той, что срывается на следующем событии.

Отделите загруженное рано от открываемого позже

Дескриптор — это ручка на открытом описании файла, и режим доступа был зафиксирован при создании этого описания. Последующая смена пользователя процесса ручку не закрывает, поэтому файл ключа, прочитанный как root, работает и после снятия привилегий. Режим тоже не меняется: ручка, открытая на чтение, не становится записываемой, а записываемая ручка не отзывается только потому, что учётная запись потеряла права на путь. Эти два факта объясняют большую часть неожиданного поведения в таких отчётах.

Другая половина — память. Демон может разобрать сертификат, сохранить разобранный материал и закрыть файл; в работе остаются данные, а не открытый файл. Поэтому продолжающийся трафик не доказывает ни того, что дескриптор открыт, ни того, что имя пути достижимо. Он доказывает лишь то, что материал, нужный текущей сессии, был получен раньше.

Более позднее открытие — другая транзакция. Она идёт под текущими учётными данными, текущим контекстом безопасности и текущим представлением монтирования, поэтому путь, читаемый при запуске, может быть отвергнут при следующем подключении. Ротация добавляет ловушку: запись нового файла поверх того же имени пути оставляет существующий дескриптор привязанным к старому объекту, поэтому перезагрузка может выглядеть успешной, пока демон всё ещё использует прежнее содержимое. Сравните inode, который держит процесс, с тем, что на диске, прежде чем верить в ротацию.

Назовите три чтения времени выполнения и когда происходит каждое

Три ресурса обычно открываются намного позже инициализации и отказывают в разные моменты. Конфигурационный файл конкретного клиента читается, когда подключается именно этот клиент, поэтому он может сломаться у одного пользователя, пока остальные работают. Данные отзыва проверяются при аутентификации партнёра и ещё раз при замене файла. Временный каталог затрагивается только тогда, когда скрипт или плагин что-то пишет.

Ни один из трёх не относится к пути запуска, поэтому сервер, здоровый неделями, может отказать при следующем подключении. Категория называет и владельца исправления: первые два — права на чтение конфигурации под учётной записью демона, а третий — записываемое место с узким назначением.

Path reopened laterWhat triggers the openFirst sign when it fails
Client configuration fileA connection for that client identityOne client rejected while others connect
Revocation dataPeer authentication, including after replacementRevoked and valid peers both refused
Script or plugin temporary directoryA helper needs to create a fileThe helper exits with a path error

persist-key отвечает на более узкий вопрос, чем принято думать. Он держит файл ключа открытым через документированные сбросы SIGUSR1 и ping-restart, и он ничего не делает для файлов CCD, данных отзыва, вспомогательных исполняемых файлов или полного перезапуска процесса. Они по-прежнему идут своими путями открытия, под той учётной записью, что работает в этот момент.

Подтвердите учётную запись и представление, которое она реально имеет

Спросите у работающего демона, какую учётную запись он использует, вместо того чтобы доверять файлу unit, а затем сравните ответ с тем, что задаёт unit. Расхождение — первое, что нужно решить, потому что каждая последующая проверка прав идёт от имени того, кем процесс является на самом деле. Затем пройдите путь по компонентам; проходимость оценивается на каждом уровне, поэтому читаемый файл в непроходимом каталоге остаётся нечитаемым. Окончательный режим файла — последний вопрос, а не первый.

Пространства имён и песочницы службы добавляют границы, которые не описывают владение и биты режима. Путь, видимый в вашей оболочке, может отсутствовать или быть только для чтения внутри chroot, пространства имён монтирования или unit, скрывающего домашние каталоги. Модули безопасности добавляют ещё один слой, поэтому файл, который выглядит читаемым, всё равно может быть отвергнут при открытии.

ps -o user:12,pid,args -C openvpn
systemctl show -p User -p Group -p ProtectHome -p RootDirectory [email protected]
sudo -u openvpn namei -l /etc/openvpn/ccd/alice

Успешное чтение в оболочке администратора не проверяет ни одного из этих совместных условий. Выполните проверку от имени учётной записи демона, с тем же пространством имён и песочницей, или примите, что результат описывает вашу оболочку, а не сервер. Третья команда — дешёвая версия этого теста: она печатает режим каждого компонента и срывается на первом, который учётная запись демона не может пройти.

Дайте записи времени выполнения отдельный каталог

Чтение — только половина описи. Вспомогательному скрипту может понадобиться создать файл состояния, плагину — записать состояние рядом со своей конфигурацией, и эти записи не покрываются тем, что дерево конфигурации становится записываемым. Дайте конкретному каталогу право записи, которое требует его функция, с владельцем и режимом, которые вы можете объяснить. Предпочитайте доступ только для чтения всему, что только читается.

Держите права приватного ключа отдельно от файлов политики. Ключ, который нужно перечитать после сброса, требует иного, чем клиентский файл, читаемый при каждом подключении, а один мягкий режим для обоих даёт больше доступа, чем просит задача. Выделенная учётная запись демона с узким владением проверяется легче, чем широкая группа. Когда ключ должен пережить сбросы, persist-key устраняет перечитывание вместо расширения каталога.

Решайте по событию, которое можете воспроизвести

Живой туннель доказывает один путь в коде. Событие, которому нужен файл, — единственный тест, покрывающий интересующее вас открытие, будь то новое подключение клиента, заменённый файл отзыва, разрешённый мягкий сброс или плановый перезапуск. Выберите событие, выполните его и сохраните первую ошибку, а не последнюю.

При мягком сбросе один сигнал и журнал unit показывают, был ли ключ прочитан заново. Отправьте сигнал, затем прочитайте последние строки, которые записал unit:

systemctl kill -s SIGUSR1 [email protected]
journalctl -u [email protected] -n 40 --no-pager

Не заключайте, что скомпрометированный демон больше не может менять файлы только потому, что привилегии снижены. Что он ещё может, зависит от оставшихся учётных данных, его возможностей, каталогов, куда он может писать, и любой ещё удерживаемой записываемой ручки. Снижение привилегий сужает полномочия, и опись открытий времени выполнения показывает, насколько. Запишите эту границу рядом с конфигурацией, чтобы следующему человеку не пришлось открывать её заново.

Похожие статьи