signal=SYS (status=31/SYS) в systemd
SYS означает, что программа выполнила системный вызов, запрещённый фильтром seccomp. Это не дефект программы, а следствие настроек изоляции в unit-файле: SystemCallFilter=, RestrictAddressFamilies=, RestrictNamespaces= или готовых профилей вроде ProtectKernelModules=.
Что это значит
Разница с кодом 228/SECCOMP важна: там фильтр не удалось установить, здесь он установлен и сработал. Служба стартует, работает, а падает на первом запрещённом вызове — иногда спустя часы, когда дело доходит до редкой операции.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Фильтр системных вызовов слишком узкий
Набор
@system-serviceпокрывает обычные службы, но программы с нестандартными операциями (работа с ключами, монтирование, отладка) выходят за его пределы. -
Сработало ограничение семейств адресов
RestrictAddressFamilies=работает через тот же механизм. Попытка открыть сокет запрещённого семейства завершает процесс этим сигналом. -
Готовый профиль изоляции запрещает нужную операцию
ProtectKernelTunables=,ProtectKernelModules=,ProtectClock=иRestrictNamespaces=включают наборы запретов. Служба, которой нужно, например, менять время или загружать модуль, будет убита.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Ядро записывает номер запрещённого системного вызова — это точный адрес проблемы.
journalctl -k -b --no-pager | grep -i seccomp | tail -10Что входит в стандартный набор: позволяет понять, чего в нём нет.
systemd-analyze syscall-filter @system-service | head -30Сводка по всем параметрам изоляции службы с оценкой каждого.
sudo systemd-analyze security myapp.service | head -25Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Набор
@system-serviceпокрывает обычные службы, но программы с нестандартными операциями (работа с ключами, монтирование, отладка) выходят за его пределы.
- Как проверить
-
Найдите запрещённый вызов в записях ядра: они называют его номер.
journalctl -k -b --no-pager | grep -i seccomp | tail -5 systemctl show myapp.service -p SystemCallFilter
- Как исправить
-
Добавьте нужный вызов в фильтр по номеру или имени. Номер переводится в имя через
systemd-analyze syscall-filter. Начинать разбор лучше с расширения набора, а не с полного снятия фильтра.SystemCallFilter=@system-service @keyring
- Почему происходит
RestrictAddressFamilies=работает через тот же механизм. Попытка открыть сокет запрещённого семейства завершает процесс этим сигналом.
- Как проверить
-
Посмотрите ограничение и какие сокеты нужны службе.
systemctl show myapp.service -p RestrictAddressFamilies sudo ss -apn | grep myapp
- Как исправить
- Добавьте нужное семейство. AF_UNIX требуется почти всегда: через него идёт запись в журнал.
- Почему происходит
ProtectKernelTunables=,ProtectKernelModules=,ProtectClock=иRestrictNamespaces=включают наборы запретов. Служба, которой нужно, например, менять время или загружать модуль, будет убита.
- Как проверить
-
Посмотрите действующие параметры защиты.
systemctl show myapp.service | grep -E "^Protect|^Restrict"
- Как исправить
-
Отключите точечно тот параметр, который мешает, вместо снятия защиты целиком. Понять цену изоляции помогает
systemd-analyze security.
Пример вывода
Фильтр запретил системный вызов уже работающей службе. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
× myapp.service - My application
Active: failed (Result: signal) since Mon 2026-09-15 17:02:55 MSK; 4s ago
Main PID: 17200 (code=killed, signal=SYS)
kernel: audit: type=1326 audit(1789...): pid=17200 comm="myapp" syscall=169 compat=0 code=0x80000000
systemd[1]: myapp.service: Main process exited, code=killed, status=31/SYS
systemd[1]: myapp.service: Failed with result 'signal'.
Число после syscall= — номер вызова. Перевести его в имя помогает systemd-analyze syscall-filter, после чего понятно, что именно добавить в фильтр.
Связанные ошибки
- status=228/SECCOMP в systemd Код 228/SECCOMP: не удалось применить фильтр системных вызовов из SystemCallFilter=. Причины: неизвестное имя вызова, отсутствие поддержки в ядре.
- status=232/ADDRESS_FAMILIES в systemd Код 232/ADDRESS_FAMILIES: не удалось применить ограничение семейств адресов из RestrictAddressFamilies=.
- status=244/BPF в systemd Код 244/BPF: не удалось применить ограничения через BPF, например RestrictFileSystems=. В man-странице systemd этот код указан неверно.
- Failed with result 'signal' Состояние signal: процесс службы завершён сигналом без сохранения дампа. Как узнать, каким сигналом и от кого.
- Function not implemented в контейнере Ошибка 38 при системном вызове: вызов запрещён фильтром или отсутствует в окружении. Разбор для контейнеров.
- No such file or directory в журнале службы Служба не находит файл или каталог. Разбор: путь, момент запуска, изоляция unit-файла, символические ссылки, приватный /tmp.
- Operation not permitted в журнале службы Операция запрещена: не хватает возможностей процесса, мешает seccomp или модуль безопасности. Отличие от Permission denied.
- Permission denied в журнале службы Отказ в доступе у службы systemd: права на файл, каталоги по пути, пользователь службы, параметры изоляции, SELinux и AppArmor.
Где встречается чаще всего
Источники
-
systemd.exec(5)
SystemCallFilter= и последствия запрета вызова для работающего процесса. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено с SystemCallFilter=@system-service на программе, обращающейся к связке ключей.