Framework di difesa a runtime a livello di kernel per le vulnerabilità AF_ALG, con tracciamento dei socket tramite eBPF, hardening Ansible e un auditor crittografico per il rilevamento delle derive.
Un framework di difesa a livello di kernel per il sottosistema Linux AF_ALG (Address Family Algorithm, famiglia 38). Progettato per i Security Operations Center che gestiscono flotte Linux enterprise dove la Zero Trust deve estendersi dentro il kernel, non fermarsi al perimetro di rete.
AF_ALG espone l'API crittografica del kernel allo spazio utente tramite un'interfaccia socket (socket(AF_ALG, SOCK_SEQPACKET, 0)). È stato originariamente aggiunto per sistemi embedded senza /dev/crypto e da allora ha accumulato una quota sproporzionata di CVE del kernel perché presenta codice crittografico in modalità kernel a chiamanti non privilegiati — un classico disallineamento di superficie.
In una tipica build enterprise:
connect(), bind() o DNS non vedono nulla — il traffico AF_ALG non lascia mai il kernel.Questo framework tratta ogni creazione di socket AF_ALG come un evento ad alta segnalazione e riduce la superficie che rende sfruttabili tali eventi.
| Principio Zero Trust | Controllo in questo framework |
|---|---|
| Mai fidarsi, verificare sempre | Tracer eBPF registra ogni tentativo di creazione socket AF_ALG con pid/uid/comm |
| Presumere la violazione | Auditor crittografico confronta la postura del kernel con una baseline firmata |
| Privilegio minimo | systemd RestrictAddressFamilies + capability bounding sulle unità gestite |
| Microsegmentazione (lato kernel) | unprivileged_userns_clone=0 rimuove il pivot userns usato dagli exploit |
| Validazione continua | CI valida i report di audit rispetto a uno schema versionato a ogni modifica |
.
├── ebpf/ Osservabilità runtime (tracer BCC + allowlist)
├── ansible/ Configuration-as-Code (sysctl + systemd drop-in)
├── systemd/ Drop-in systemd autonomo per host senza Ansible
├── auditor/ Auditor dello stato del kernel (Python)
├── schemas/ JSON Schema per l'ingestione dei report di audit
├── scripts/ Script shell di supporto (lintati dalla CI)
├── tests/ Test unitari + fixture dei report
└── .github/workflows/ CI: shellcheck + validazione JSON Schema + lint
ebpf/af_alg_tracer.py collega una kprobe a security_socket_create. La probe filtra su family == 38 a livello di programma BPF, così il verifier pota le creazioni di socket non correlate e l'overhead per evento rimane nell'ordine dei nanosecondi. Emette un record JSON per ogni tentativo:
{
"@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"}
}
Inoltra lo stdout a Vector, Fluent Bit o journald (tramite systemd-cat). Un'allowlist basata sui nomi comm (/etc/af-alg-defense/allow.list) sopprime i consumatori noti e legittimi senza perdere la capacità di rilevare deviazioni.
Il target della kprobe è l'hook LSM, quindi gli eventi scattano sull'intento — anche i tentativi che verrebbero negati da seccomp o RestrictAddressFamilies producono comunque un record. È esattamente ciò che un SOC vuole per la baseline comportamentale.
ansible/roles/af_alg_hardening/ applica due livelli di hardening:
Drop-in sysctl (/etc/sysctl.d/90-af-alg-defense.conf):
kernel.unprivileged_userns_clone=0 — rimuove il pivot userns usato dalla maggior parte delle catene di escalation AF_ALG.user.max_user_namespaces=0 — difesa in profondità portabile tra distribuzioni.Drop-in systemd (/etc/systemd/system/<unit>.d/50-af-alg-restrict.conf):
Usa RestrictAddressFamilies come allow-list (non deny-list). All'unità sono consentite AF_UNIX AF_INET AF_INET6 AF_NETLINK; qualsiasi altra famiglia — inclusa AF_ALG — fallisce con EAFNOSUPPORT perché systemd la applica tramite BPF collegato al cgroup che l'applicazione non può disabilitare. Il drop-in rimuove anche CAP_SYS_ADMIN e applica ProtectKernel* per chiudere i percorsi di escalation più comuni.
Applica con:
ansible-playbook -i inventory ansible/site.yml --check --diff # anteprima
ansible-playbook -i inventory ansible/site.yml # applica
Per host senza Ansible, posiziona il file autonomo:
sudo ./scripts/deploy_dropin.sh nginx.service
auditor/crypto_auditor.py produce un report JSON della postura di sicurezza ispezionando:
/proc/crypto — ogni cipher / hash / aead registrato, con flag FIPS e stato dei self-test./sys/module/ — moduli caricati nel sottosistema crittografico, con flag di taint e snapshot dei parametri./proc/sys/kernel/, /proc/sys/user/ — sysctl che controllano i percorsi di attacco AF_ALG./sys/kernel/security/lockdown — modalità di lockdown del kernel.Il report è indicizzato da ID di finding stabili (FND-001 fino a FND-005 al momento) così le regole SIEM possono sopprimere singoli finding senza scartare l'intero documento. Il rilevamento di drift confronta la postura con una baseline:
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
Lo schema si trova in schemas/audit_report.schema.json (Draft 2020-12) e viene validato in CI a ogni push.
.github/workflows/ci.yml esegue quattro job a ogni push e PR:
*.sh e script con shebang.audit_report.schema.json, poi esegue l'auditor live sul kernel del runner GH e valida il report risultante. Vengono controllate anche le fixture in tests/fixtures/.ruff check .).Un controllo schema fallito blocca i merge, impedendo ai parser SIEM a valle di rompersi su un campo rinominato silenziosamente.
af_alg_socket_create da un comm non in allowlist — pagina alla prima occorrenza, non aggregare.crypto_modules tra esecuzioni consecutive dell'auditor su un host dove il caricamento dei moduli dovrebbe essere congelato.hardened=false dopo un run del playbook di hardening — indica manomissione manuale o drift da un sistema di configurazione parallelo.lockdown che transita da integrity/confidentiality a none — forte indicatore di manomissione dello stato del kernel.