После снятия привилегий: какие файлы OpenVPN всё ещё работают?
Дескрипторы, открытые до снятия привилегий, продолжают работать; пути, открываемые позже, нет. Определите, какой из трёх файлов времени выполнения вашей конфигурации нужно открыть заново.
Долгое время работы доказывает лишь то, что запуск удался с теми привилегиями, которые демон имел в тот момент. Отказы, важные здесь, приходят позже: подключается новый клиент, заменяется список отзыва, вспомогательному скрипту нужно записать файл. Каждый из них — это новое открытие, выполняемое учётной записью без привилегий, со своим вопросом о правах и своим сообщением об ошибке. Три решения отделяют конфигурацию, которая продолжает работать, от той, что срывается на следующем событии.
Отделите загруженное рано от открываемого позже
Дескриптор — это ручка на открытом описании файла, и режим доступа был зафиксирован при создании этого описания. Последующая смена пользователя процесса ручку не закрывает, поэтому файл ключа, прочитанный как root, работает и после снятия привилегий. Режим тоже не меняется: ручка, открытая на чтение, не становится записываемой, а записываемая ручка не отзывается только потому, что учётная запись потеряла права на путь. Эти два факта объясняют большую часть неожиданного поведения в таких отчётах.
Другая половина — память. Демон может разобрать сертификат, сохранить разобранный материал и закрыть файл; в работе остаются данные, а не открытый файл. Поэтому продолжающийся трафик не доказывает ни того, что дескриптор открыт, ни того, что имя пути достижимо. Он доказывает лишь то, что материал, нужный текущей сессии, был получен раньше.
Более позднее открытие — другая транзакция. Она идёт под текущими учётными данными, текущим контекстом безопасности и текущим представлением монтирования, поэтому путь, читаемый при запуске, может быть отвергнут при следующем подключении. Ротация добавляет ловушку: запись нового файла поверх того же имени пути оставляет существующий дескриптор привязанным к старому объекту, поэтому перезагрузка может выглядеть успешной, пока демон всё ещё использует прежнее содержимое. Сравните inode, который держит процесс, с тем, что на диске, прежде чем верить в ротацию.
Назовите три чтения времени выполнения и когда происходит каждое
Три ресурса обычно открываются намного позже инициализации и отказывают в разные моменты. Конфигурационный файл конкретного клиента читается, когда подключается именно этот клиент, поэтому он может сломаться у одного пользователя, пока остальные работают. Данные отзыва проверяются при аутентификации партнёра и ещё раз при замене файла. Временный каталог затрагивается только тогда, когда скрипт или плагин что-то пишет.
Ни один из трёх не относится к пути запуска, поэтому сервер, здоровый неделями, может отказать при следующем подключении. Категория называет и владельца исправления: первые два — права на чтение конфигурации под учётной записью демона, а третий — записываемое место с узким назначением.
| Path reopened later | What triggers the open | First sign when it fails |
|---|---|---|
| Client configuration file | A connection for that client identity | One client rejected while others connect |
| Revocation data | Peer authentication, including after replacement | Revoked and valid peers both refused |
| Script or plugin temporary directory | A helper needs to create a file | The 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Не заключайте, что скомпрометированный демон больше не может менять файлы только потому, что привилегии снижены. Что он ещё может, зависит от оставшихся учётных данных, его возможностей, каталогов, куда он может писать, и любой ещё удерживаемой записываемой ручки. Снижение привилегий сужает полномочия, и опись открытий времени выполнения показывает, насколько. Запишите эту границу рядом с конфигурацией, чтобы следующему человеку не пришлось открывать её заново.