```
systemd-analyze security
```

`systemd-analyze security` — один из тех инструментов, которые часто пугают с первого взгляда. Достаточно запустить его на живом сервере или Kubernetes-ноде, увидеть десятки строк с пометкой `UNSAFE`, и возникает ощущение, что система находится в катастрофически небезопасном состоянии. На практике это почти всегда неверная интерпретация.
Этот инструмент не пытается ответить на вопрос «уязвим ли сервис». Он отвечает на совершенно другой, гораздо более инженерный вопрос: **какие системные привилегии доступны процессу и насколько велик потенциальный ущерб, если этот процесс будет скомпрометирован**. И именно в этом контексте `systemd-analyze security` становится крайне полезным для production-среды.
---
### Что именно анализирует `systemd-analyze security`
`systemd-analyze security` выполняет статический анализ unit-файла systemd и смотрит, какие механизмы изоляции и hardening включены или отсутствуют. Его интересуют такие вещи, как возможность получения новых привилегий, доступ к устройствам, работа с namespaces, запись в системные директории, загрузка модулей ядра, создание исполняемой памяти и так далее.
Важно понимать границы инструмента. Он не анализирует код сервиса, не ищет CVE, не сканирует сеть и не учитывает политики SELinux или AppArmor. Это не security scanner и не pentest. Это **линтер конфигурации systemd**, который показывает, насколько «широкими» остаются права процесса с точки зрения ядра.
---
### Почему почти все system-сервисы выглядят как `UNSAFE`
Если выполнить `systemd-analyze security` без аргументов, то в выводе почти наверняка окажется, что `systemd-udevd`, `dbus`, `polkit`, `networkd`, `sshd`, `k3s`, `containerd` и многие другие сервисы имеют уровень `UNSAFE` с показателями 8–10. Это не баг и не признак плохо защищённой системы.
Причина проста: это **базовые системные демоны**, без которых Linux просто не работает. Они обязаны иметь доступ к устройствам, к netlink, к cgroups, к `/proc` и `/sys`, к управлению пользователями, терминалами и сетевым стеком. Попытка «зажать» такие сервисы жёсткими sandbox-настройками почти гарантированно приведёт к неработоспособной системе.
В контексте `systemd-analyze security` слово `UNSAFE` означает лишь то, что systemd **почти не ограничивает** этот сервис. Оно не означает, что сервис уязвим, дыряв или небезопасен по своей природе.
---
### Как правильно читать вывод на примере `ssh.service`
Рассмотрим типичный вывод для `ssh.service`. В нём можно увидеть сообщения о том, что сервис запускается от root, может приобретать новые привилегии, создавать namespaces, посылать сигналы другим процессам и так далее. Всё это выглядит пугающе, если читать строки буквально, но для SSH это абсолютно ожидаемое поведение.
SSH-демон обязан быть root, потому что он открывает привилегированный порт, работает с PAM, переключает UID пользователей, управляет TTY и взаимодействует с systemd-logind. Ограничить его capability-набором или запретить privilege escalation — значит сломать саму модель работы SSH. В этом случае высокий exposure — не проблема, а осознанный архитектурный выбор.
---
### В чём реальная ценность инструмента
Настоящая польза `systemd-analyze security` проявляется не при анализе системных демонов, а при проверке **кастомных сервисов**. Если самописное приложение, агент мониторинга, CI-runner или вспомогательный демон внезапно имеет уровень `8.9 UNSAFE`, это почти всегда означает, что сервис запущен с избыточными правами без реальной необходимости.
В таких случаях инструмент позволяет очень быстро ответить на вопрос: «А зачем этому процессу вообще всё это разрешено?» И чаще всего ответ — «ни за чем».
---
## Практический пример: как читать `systemd-analyze security` и реально улучшать сервис
```
systemd-analyze security ssh.service
```
![[Pasted image 20251228105153.png]]
### Исходная ситуация
Допустим, на сервере есть кастомный сервис `my-agent.service`. Это может быть агент мониторинга, интеграция с внешним API или любой вспомогательный демон, который не является частью ядра системы.
Unit-файл выглядит минималистично:
```ini
[Unit]
Description=My custom agent
[Service]
ExecStart=/opt/my-agent/agent
Restart=always
[Install]
WantedBy=multi-user.target
```
Сервис работает, проблем нет — но вопрос безопасности никто не задавал.
---
### Первый запуск `systemd-analyze security`
Проверяем сервис:
```bash
systemd-analyze security my-agent.service
```
Типичный результат:
```
✗ NoNewPrivileges Service may acquire new privileges
✗ ProtectSystem Service has full access to system
✗ ProtectHome Service has full access to home directories
✗ PrivateDevices Service has access to hardware devices
✗ RestrictNamespaces Service may create namespaces
✗ CapabilityBoundingSet Service runs with full capabilities
→ Overall exposure level: 9.4 UNSAFE
```
На этом этапе **важно не паниковать**.
Инструмент не говорит, что сервис уязвим. Он говорит следующее:
> если процесс будет скомпрометирован,
> он сможет делать почти всё, что может root на хосте.
Для кастомного агента это почти всегда избыточно.
---
### Интерпретация результата
Если задать себе простой вопрос — _что реально нужно этому сервису?_ — ответ обычно выглядит так:
Он не должен:
- менять системные файлы
- видеть `/home`
- работать с устройствами
- создавать namespaces
- эскалировать привилегии
Именно это и показывает высокий exposure.
---
### Минимальный hardening (без фанатизма)
Добавим базовые ограничения, не ломая сервис:
```ini
[Service]
ExecStart=/opt/my-agent/agent
Restart=always
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
PrivateDevices=true
RestrictNamespaces=true
MemoryDenyWriteExecute=true
CapabilityBoundingSet=
```
Здесь нет «экзотики». Это стандартный набор, который подходит для **большинства user-space сервисов**.
---
### Повторный анализ
Перезапускаем сервис и снова запускаем анализ:
```bash
systemctl daemon-reexec
systemctl restart my-agent.service
systemd-analyze security my-agent.service
```
Теперь вывод выглядит примерно так:
```
✓ NoNewPrivileges
✓ ProtectSystem
✓ ProtectHome
✓ PrivateDevices
✓ RestrictNamespaces
✓ CapabilityBoundingSet
→ Overall exposure level: 1.6 OK
```
Это означает, что:
- сервис по-прежнему работает
- код не менялся
- но потенциальный ущерб при взломе стал **на порядок меньше**
---
### Почему это правильный результат
Важно подчеркнуть:
мы **не пытались сделать сервис “идеально безопасным”**.
Мы сделали его:
- предсказуемым
- ограниченным
- соответствующим принципу least privilege
Если завтра в `my-agent` появится RCE, злоумышленник:
- не сможет читать `/etc`
- не сможет лезть в `/proc` и `/sys`
- не сможет создавать namespaces
- не сможет загрузить kernel-модули
- не сможет эскалировать привилегии
И это именно та цель, ради которой существует `systemd-analyze security`.
---
### Контраст: почему так нельзя делать с `ssh.service`
Если проделать тот же путь с `ssh.service`, станет очевидно, что большинство этих опций просто несовместимы с его логикой. SSH обязан:
- работать от root
- использовать PAM
- менять UID
- управлять TTY
- взаимодействовать с другими systemd-сервисами
Поэтому высокий exposure для `ssh.service` — это **архитектурная необходимость**, а для `my-agent.service` — **лишняя неосторожность**.
---
### Главный вывод из примера
Этот пример показывает ключевую идею:
`systemd-analyze security` не предназначен для того, чтобы «чинить systemd».
Он предназначен для того, чтобы **находить лишние привилегии там, где они не нужны**, и спокойно их убирать.
Если после анализа кастомного сервиса ты видишь `UNSAFE` — это почти всегда приглашение задать вопрос:
_«А зачем ему вообще всё это разрешено?»_
И чаще всего ответ — _«незачем»_.