Журнал дописывается, но не пересоздаётся: проверьте ACL каталога
Дозапись в файл не требует нового имени в каталоге; создание требует. Сравните ACL доступа с унаследованными значениями по умолчанию, прежде чем что-то расширять.
Журнал, который непрерывно растёт, перестаёт расти в тот момент, когда что-то пересоздаёт его, и ошибка сообщает, что доступ запрещён. Соблазнительный вывод — самому файлу журнала нужно больше прав, — но файл может уже быть доступен для записи той же учётной записью. Дозапись к существующему имени и создание нового имени — две разные проверки, и только вторая обращается к каталогу.
Дозапись и создание — разные проверки
Открытие существующего файла для дозаписи требует права записи на этот файл и права поиска по каждому каталогу в его пути. Создание файла требует записи и поиска в каталоге, который его содержит, потому что операция добавляет в него имя. Замена файла через переименование затрагивает оба каталога и их правила sticky bit.
| Operation | What must permit it | Typical failure message |
|---|---|---|
| Append to an existing log | File write access, path traversal | Permission denied on the file |
| Create a missing log | Directory write and search access | Permission denied on the path |
| Rename a replacement into place | Both directories, plus sticky restrictions | Permission denied or operation not permitted |
Уже открытый дескриптор добавляет четвёртый случай. Процесс может держать обработчик записи, открытый до сброса привилегий, и всё же не суметь повторно открыть тот же путь под своей более поздней личностью. Успешные дозаписи и неудачное создание могут быть одновременной правдой для одного и того же процесса.
ACL по умолчанию наследуются, они не предоставляют права
Запись, начинающаяся с префикса по умолчанию, описывает, что новые объекты наследуют от каталога. Она ничего не даёт самому каталогу и не исправляет ACL уже существующего файла.
namei -l /var/log/openvpn/server.log
getfacl -p /var/log/openvpn
getfacl -p /var/log/openvpn/server.log
Читайте записи доступа отдельно от записей по умолчанию и читайте маску. Именованная запись, перечисляющая полные права, всё равно может ограничиваться маской, поэтому эффективный комментарий важнее букв в первой строке.
Используйте разрешённый путь, а не путь из конфигурации. Символическая ссылка, точка монтирования или повёрнутый каталог могут поместить настоящий файл туда, куда выданное вами право никогда не доходит. Сначала пройдите путь инструментом имён, затем сравните каждый уровень с нужной учётной записью. Догадка о каталоге верхнего уровня — это способ, которым исправление оказывается на уровень выше.
Определите, кто пишет в этот момент
Прежде чем что-либо менять, проверьте служебный юнит, его drop-in и собственные настройки учётной записи демона. Процесс, который дописывает, и процесс, который пересоздаёт, могут различаться: помощник ротации, писатель состояния и веб-читатель редко делят одну личность.
Запуск теста из root-оболочки не воспроизводит ограниченный сервис, и он завершится успешно, пока сервис продолжает сбоить. Воспроизведите неудачную операцию под тем же юнитом, с той же учётной записью и теми же настройками sandbox. Если не можете, запустите юнит с временной оболочкой и проверьте сообщаемую им личность. Всё остальное измеряет ваш терминал, а не сервис.
Если создание действительно необходимо, дайте писателю доступ к выделенному каталогу журнала, а доступ на чтение для потребителей держите отдельно. Сделать общую учётную запись или всё дерево приложения записываемым ради одного вызова журналирования — это обмен небольшой проблемы на большую.
Выполняйте ротацию, не возвращая проблему
Тот, кто пересоздаёт файл, решает его владельца и режим на следующий цикл, поэтому согласуйте исправление с конфигурацией ротации. Замена, созданная под другой учётной записью или со свежим ACL, возвращает сбой после успешного исправления.
Задавайте режим и группу при создании, а не после, и проверяйте следующую ротацию, а не следующую дозапись. Дозапись лишь повторяет тест, который уже прошёл. Если инструмент ротации предлагает настройку режима создания, используйте её вместо chmod после создания. Промежуток между созданием и chmod — это именно тот момент, когда следующая запись может сбойнуть.
Когда усечение всё равно сбоит, перестаньте добавлять права
Сбой усечения файла, в который вы можете писать, не объясняется правами каталога, и добавление новых не поможет. Посмотрите вместо этого на атрибуты и ограничение: атрибут append-only разрешает запись только в режиме дописывания, а монтирование только для чтения или sandbox сервиса могут отклонить операцию, которую ACL разрешает.
Проверьте ограничения файловой системы юнита и параметры монтирования пути, затем воспроизведите точную операцию, которая сбойнула. Расширение права, к которому никогда не обращались, лишь скрывает, какое ограничение было настоящим. Удаляйте по одному ограничению за раз во временном юните и возвращайте его прежде, чем менять что-то постоянное.