
Каркас защиты на уровне ядра для уязвимостей AF_ALG, включающий трассировку сокетов через eBPF, усиление защиты с помощью Ansible и криптоаудитор для обнаружения отклонений.
Фреймворк защиты на уровне ядра для подсистемы Linux AF_ALG (Address Family
Algorithm, семейство 38). Создан для центров мониторинга безопасности (SOC),
управляющих корпоративными парками Linux-серверов, где Zero Trust должен
распространяться внутрь ядра, а не останавливаться на сетевой периферии.
AF_ALG предоставляет доступ к криптографическому API ядра из пользовательского
пространства через сокетный интерфейс (socket(AF_ALG, SOCK_SEQPACKET, 0)).
Изначально он был добавлен для встраиваемых систем без /dev/crypto и с тех пор
накопил непропорционально большую долю CVE ядра, поскольку предоставляет
криптографический код режима ядра непривилегированным вызывающим — классическое
несоответствие поверхности атаки.
В типичной корпоративной сборке:
connect(), bind() или DNS, ничего не видят — трафик AF_ALG никогда не
покидает ядро.Этот фреймворк рассматривает каждое создание сокета AF_ALG как событие высокой
значимости и сокращает поверхность, делающую такие события эксплуатируемыми.
| Принцип Zero Trust | Механизм контроля в этом фреймворке |
|---|---|
| Никогда не доверяй, всегда проверяй | eBPF-трассировщик логирует каждую попытку создания сокета AF_ALG с pid/uid/comm |
| Предполагай взлом | Аудитор криптографии сверяет состояние ядра с подписанным базовым профилем |
| Минимальные привилегии | systemd RestrictAddressFamilies + ограничение capabilities на управляемых юнитах |
| Микросегментация (на стороне ядра) | unprivileged_userns_clone=0 устраняет точку опоры userns, используемую эксплойтами |
| Непрерывная валидация | CI проверяет отчёты аудита по версионированной схеме при каждом изменении |
.
├── ebpf/ Наблюдаемость в рантайме (BCC-трассировщик + список разрешений)
├── ansible/ Конфигурация как код (sysctl + systemd drop-in)
├── systemd/ Автономный systemd drop-in для хостов без Ansible
├── auditor/ Аудитор состояния ядра (Python)
├── schemas/ JSON Schema для приёма отчётов аудита
├── scripts/ Вспомогательные shell-скрипты (проверяются CI)
├── tests/ Модульные тесты + фикстуры отчётов
└── .github/workflows/ CI: shellcheck + валидация JSON Schema + lint
ebpf/af_alg_tracer.py подключает kprobe к security_socket_create.
Проба фильтрует по family == 38 на уровне BPF-программы, поэтому верификатор
отсекает несвязанные создания сокетов, а накладные расходы на событие остаются
в пределах наносекунд. На каждую попытку формируется одна JSON-запись:
{
"@timestamp": "2026-05-02T09:14:11.412041+00:00",
"event": {"category": "kernel", "action": "af_alg_socket_create", "severity": "high"},
"process": {"pid": 1394, "tgid": 1394, "comm": "suspicious_bin"},
"user": {"uid": 1000, "gid": 1000},
"socket": {"family": 38, "family_name": "AF_ALG", "type": 5, "protocol": 0},
"host": {"name": "web-prod-04"}
}
Перенаправляйте stdout в Vector, Fluent Bit или journald (через systemd-cat).
Список разрешений по именам comm (/etc/af-alg-defense/allow.list) подавляет
известные легитимные потребители, не теряя способности обнаруживать отклонения.
Цель kprobe — хук LSM, поэтому события срабатывают по намерению —
даже попытки, которые были бы отклонены seccomp или RestrictAddressFamilies,
всё равно создают запись. Именно это нужно SOC для поведенческого
базлайнинга.
ansible/roles/af_alg_hardening/ применяет два уровня защиты:
Sysctl drop-in (/etc/sysctl.d/90-af-alg-defense.conf):
kernel.unprivileged_userns_clone=0 — устраняет точку опоры userns,
используемую большинством цепочек повышения привилегий через AF_ALG.user.max_user_namespaces=0 — переносимая между дистрибутивами защита вглубь.Systemd drop-in (/etc/systemd/system/<unit>.d/50-af-alg-restrict.conf):
Использует RestrictAddressFamilies как список разрешений (а не запретов).
Юниту разрешены AF_UNIX AF_INET AF_INET6 AF_NETLINK; любое другое семейство —
включая AF_ALG — завершается ошибкой EAFNOSUPPORT, поскольку systemd
обеспечивает это через привязанный к cgroup BPF, который приложение не может
отключить. Drop-in также снимает CAP_SYS_ADMIN и применяет
ProtectKernel* для закрытия наиболее распространённых путей эскалации.
Применение:
ansible-playbook -i inventory ansible/site.yml --check --diff # предпросмотр
ansible-playbook -i inventory ansible/site.yml # применение
Для хостов без Ansible разместите автономный файл вручную:
sudo ./scripts/deploy_dropin.sh nginx.service
auditor/crypto_auditor.py формирует JSON-отчёт о состоянии безопасности,
проверяя:
/proc/crypto — каждый зарегистрированный cipher / hash / aead с
флагами FIPS и статусом самотестирования./sys/module/ — загруженные модули в поддереве криптографии с флагами
taint и снимками параметров./proc/sys/kernel/, /proc/sys/user/ — sysctl, управляющие путями атак
на AF_ALG./sys/kernel/security/lockdown — режим lockdown ядра.Отчёт привязан к стабильным идентификаторам находок (FND-001–FND-005
на данный момент), чтобы правила SIEM могли подавлять отдельные находки,
не отбрасывая весь документ. Обнаружение дрейфа сравнивает состояние
с базовым профилем:
sudo ./auditor/crypto_auditor.py --output /var/log/af-alg-defense/today.json
sudo ./auditor/crypto_auditor.py \
--baseline /var/log/af-alg-defense/baseline.json \
--fail-on-drift
Схема находится в schemas/audit_report.schema.json (Draft 2020-12)
и проверяется в CI при каждом пуше.
.github/workflows/ci.yml запускает четыре задания при каждом пуше и PR:
*.sh и скрипт с shebang.audit_report.schema.json,
затем аудитор запускается вживую на ядре раннера GH, а полученный отчёт
валидируется. Фикстуры в tests/fixtures/ также проверяются.ruff check .).Неудачная проверка схемы блокирует слияние, что предотвращает поломку нижестоящих парсеров SIEM из-за молча переименованного поля.
af_alg_socket_create от comm, отсутствующего в списке
разрешений — вызывайте дежурного при первом появлении, не агрегируйте.crypto_modules между последовательными запусками аудитора
на хосте, где загрузка модулей должна быть заморожена.hardened=false после прогона плейбука защиты —
указывает на ручное вмешательство или дрейф от параллельной системы конфигурации.lockdown из integrity/confidentiality в
none — сильный индикатор вмешательства в состояние ядра.allow.list
известными легитимными потребителями (обычно это cryptsetup при загрузке).baseline.json.af_alg_systemd_services, установленным на один низкорисковый юнит.
Следите за ошибками EAFNOSUPPORT в journald.systemd-analyze security <unit> должен показывать, что ограничение применяется.--fail-on-drift и направляйте
ненулевые коды выхода в очередь дежурных.af_alg, если он уже используется. Выгрузка модулей
вне области действия, поскольку легитимные потребители на этапе загрузки
могут всё ещё работать. Используйте modprobe.blacklist=af_alg в командной
строке ядра, если вы подтвердили, что никому на хосте он не нужен.security_socket_create).uname -r.CAP_BPF (или root) для загрузки трассировщика; доступ на чтение к /proc/crypto
для аудитора (для чтения привилегии не требуются).Apache-2.0. См. LICENSE.