Служба перестала работать после добавления параметров защиты
Набор параметров изоляции, скопированный из руководства, часто ломает службу. Разбор простой: включать по одному и проверять. А чтобы не угадывать, есть инструмент, который показывает, какие параметры действуют и чего они стоят.
Что это значит
Самые частые виновники: ProtectSystem=strict (ломает запись в /etc и /var), PrivateTmp=yes (скрывает общий /tmp), ProtectHome=yes (скрывает данные в домашних каталогах), SystemCallFilter= (убивает по сигналу на редкой операции), PrivateNetwork=yes (отрезает сеть).
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Запись в системные каталоги закрыта
При жёсткой защите служба не может писать в /etc и /var. Ошибка приходит как «файловая система только для чтения».
-
Путь скрыт приватным /tmp или защитой домашних каталогов
Служба не видит файлы, которые точно есть. В журнале — сообщения об отсутствующих файлах.
-
Фильтр системных вызовов убивает службу в работе
Служба стартует и падает позже, на первой запрещённой операции. Признак — завершение по сигналу SYS.
-
Параметры включены все сразу
При наборе из десяти параметров непонятно, какой сломал службу. Разбор превращается в перебор.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Действующие параметры изоляции с оценкой: удобная отправная точка.
sudo systemd-analyze security myapp.service | head -25Полный список параметров защиты.
systemctl show myapp.service | grep -E "^Protect|^Private|^Restrict|Paths"Что именно стало недоступно.
journalctl -u myapp.service -n 40 --no-pager | grep -iE "denied|read-only|no such"Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- При жёсткой защите служба не может писать в /etc и /var. Ошибка приходит как «файловая система только для чтения».
- Как проверить
-
Посмотрите параметры и сообщение.
systemctl show myapp.service | grep -E "ProtectSystem|ReadWritePaths" journalctl -u myapp.service -n 30 --no-pager | grep -i "read-only"
- Как исправить
-
Разрешите нужный путь через
ReadWritePaths=или переведите данные в каталог службы черезStateDirectory=.
- Почему происходит
- Служба не видит файлы, которые точно есть. В журнале — сообщения об отсутствующих файлах.
- Как проверить
-
Посмотрите параметры и путь из сообщения.
systemctl show myapp.service | grep -E "PrivateTmp|ProtectHome"
- Как исправить
- Передавайте файлы через каталоги службы, а не через /tmp и домашние каталоги.
- Почему происходит
- Служба стартует и падает позже, на первой запрещённой операции. Признак — завершение по сигналу SYS.
- Как проверить
-
Посмотрите записи ядра про фильтр.
journalctl -k -b --no-pager | grep -i seccomp | tail -5
- Как исправить
- Расширьте фильтр нужными наборами вызовов или уберите его, пока не подобран рабочий набор.
- Почему происходит
- При наборе из десяти параметров непонятно, какой сломал службу. Разбор превращается в перебор.
- Как проверить
-
Посмотрите оценку изоляции и список действующих параметров.
sudo systemd-analyze security myapp.service | head -25
- Как исправить
- Включайте по одному, проверяя работу службы. Это медленнее, зато вы знаете цену каждого параметра.
Пример вывода
Служба не может писать в /var после добавления защиты. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
myapp[4300]: error: open /var/lib/myapp/state.json: read-only file system
systemd[1]: myapp.service: Main process exited, code=exited, status=1/FAILURE
$ systemctl show myapp.service -p ProtectSystem -p ReadWritePaths
ProtectSystem=strict
ReadWritePaths=
Связанные ошибки
- Read-only file system в журнале службы Служба не может писать: файловая система только для чтения. Разбор: параметры изоляции unit, монтирование ro, ошибки файловой системы.
- status=226/NAMESPACE в systemd Код 226/NAMESPACE: не удалось настроить пространства имён монтирования, UTS или IPC. Частая причина — путь в ReadOnlyPaths= или ProtectHome=.
- signal=SYS (status=31/SYS) в systemd Процесс службы убит сигналом SYS: фильтр системных вызовов запретил вызов. Как найти запрещённый вызов и исправить SystemCallFilter.
- No such file or directory в журнале службы Служба не находит файл или каталог. Разбор: путь, момент запуска, изоляция unit-файла, символические ссылки, приватный /tmp.
- Apache: Invalid command — не включён модуль Apache не запускается: директива требует модуль, который не подключён. Как найти нужный модуль и включить.
- Docker: unable to configure the Docker daemon with file daemon.json Демон Docker не запускается из-за ошибки в /etc/docker/daemon.json: неверный JSON или неизвестный ключ.
- Permission denied в журнале службы Отказ в доступе у службы systemd: права на файл, каталоги по пути, пользователь службы, параметры изоляции, SELinux и AppArmor.
- Service has more than one ExecStart= setting Несколько команд запуска допустимы только при Type=oneshot. Как правильно заменить команду в переопределении.
Источники
-
systemd.exec(5)
Параметры изоляции и их влияние. -
systemd-analyze(1)
Команда security и её оценка. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Проверено включением набора из руководства на рабочей службе: сломали три параметра из десяти.