ADR-105 — Campagne de tests de sécurité d’air-sshd : confrontation aux attaques SSH connues
Statut : Accepté (2026-07-25, décision BDFL). RFC de direction (ADR-015). S’appuie sur ADR-093 (transport, strict-KEX), ADR-094 (userauth : login-grace, essais bornés, anti-énumération), ADR-104 (SFTP), ADR-031 (mesure privilégiée sur runners self-hosted).
Catégorie : Assurance sécurité. Ne modifie aucune couche ; définit une méthode
de test et ses critères de réussite. À lancer après la clôture d’air-sshd.
Contexte
air-sshd est un démon SSH exposé au réseau, écrit pour être secure-first. Plusieurs
de ses choix de conception sont précisément des contre-mesures à des attaques SSH
connues : strict-KEX contre Terrapin (CVE-2023-48795), login-grace + essais bornés
contre le brute-force, temps constant contre l’énumération de comptes
(CVE-2018-15473 côté OpenSSH). Ces contre-mesures ont été implémentées et testées
unitairement ; elles n’ont pas encore été confrontées à des outils d’attaque réels.
Directive BDFL (2026-07-25) : après clôture d’air-sshd, monter une campagne qui
confronte le démon à tous les types d’attaques SSH connus — flooding, DoS,
brute-force, timing / énumération de login — et qui prouve les contre-mesures plutôt
que de les supposer. Le test sert donc autant à attester nos choix qu’à chercher des
failles : sur beaucoup de vecteurs (algorithmes legacy, compression, KEX faible) nous
n’avons rien à trouver parce que la surface n’existe pas (moderne-only, charte) — la
campagne le démontre.
Décision
1. Deux niveaux, parce que le timing réseau ne prouve pas le constant-time
Le point le plus délicat de la commande — prouver le temps constant — ne se démontre pas de façon fiable à travers le réseau : le jitter réseau masque des fuites (faux négatifs) et en invente (faux positifs). Une campagne uniquement réseau donnerait une fausse assurance. La méthode est donc à deux étages, complémentaires :
- Niveau 1 — local, cycle-précis (LA preuve). Mesure du chemin de code sensible
sur la machine, sans réseau : vérification Argon2id du mot de passe admin, comparaison
de clé publique, résolution de login (
air-account). Méthode dudect (Reparaz et al.) : deux classes d’entrées, mesure des cycles, test statistique de distinguabilité. C’est la preuve algorithmique du constant-time. - Niveau 2 — réseau, bout-en-bout (le test d’attaque). Confrontation du vrai démon depuis une machine distincte, avec outils d’attaque réels + harnais maison. Valide l’intégration et la défense en profondeur, jamais le constant-time à lui seul.
Sans le niveau 1, on ne peut pas conclure au constant-time. Le niveau 2 le corrobore, il ne le démontre pas.
2. Topologie — attaquant et cible séparés, réseau fermé
- Attaquant :
carbon(8 cœurs, 16 Gio) — porte l’outillage offensif. - Cible :
air-sshdsurspeedy, écoutant sur:2222(parallèle à OpenSSH). - Réseau interne uniquement (
air-desktop,speedy.net↔carbon.net) : jamais de cible externe. C’est un pentest de notre propre infrastructure — légitime, cadré, et écrit ici pour qu’il ne dérive pas.
Cibler le vrai livrable. La cible doit être le binaire *-unknown-linux-air
(notre std, sans glibc, static-pie — ADR-103), pas la version gnu de test : tester un
artefact qu’on ne livre pas ne prouverait rien sur ce qu’on livre. Prérequis : air-sshd
linux-air redéployé et active sur speedy.
3. Outillage — tiers pour la confrontation, maison pour la mesure fine
Installé sur carbon (hors dépôt, comme cbindgen — n’altère ni l’arbre Air ni le
Cargo.lock) :
| Catégorie | Outil | Ce qu’il éprouve |
|---|---|---|
| Audit algos + politique | ssh-audit 3.9.0 | on n’annonce que du moderne ; détecte Terrapin, algos faibles |
| Terrapin (CVE-2023-48795) | Terrapin-Scanner 1.1.3 | le strict-KEX (U.0) mitige réellement |
| Recon / méthodes d’auth | nmap 7.98 + NSE | surface annoncée conforme |
| Brute-force / drop | ncrack 0.7, hydra 9.6 | login-grace + essais bornés (U.4) coupent |
| DoS réseau | hping3 3.0 | tenue sous SYN flood |
Écrit en Rust, in-tree, au moment de la campagne (aucun outil clé-en-main fiable) :
- Harnais de timing (niveau 2). Mesure la distribution des temps de réponse entre classes d’entrées (user existant / inexistant ; bon / mauvais secret), avec statistique robuste au bruit réseau : quantiles bas (le minimum est moins bruité que la moyenne), tests non-paramétriques (Mann-Whitney), grand nombre d’échantillons.
- Harnais dudect (niveau 1). Le même en local, cycle-précis, sur les fonctions sensibles isolées.
- Harnais de DoS pré-auth. Ouvre N connexions laissées en pré-auth et vérifie que le démon les drop (login-grace) au lieu d’épuiser ses descripteurs — le vecteur DoS qui ne dépend pas des algorithmes, donc le plus intéressant à éprouver.
Le harnais maison est cohérent avec la doctrine sans-IO ([ADR-091]) : le cœur de mesure est pur et testable ; seul le pilote parle au réseau.
4. Critères de réussite — écrits avant de tirer
« On résiste » n’est mesurable que si l’on a écrit à quoi. Par vecteur :
- Terrapin :
Terrapin-Scannerrapporte non vulnérable ;ssh-auditne signale aucun algorithme faible ni downgrade. - Brute-force : après le nombre d’essais d’
ADR-094U.4, la connexion est coupée ;ncrack/hydrane progressent pas et le démon reste disponible pour les autres. - Énumération de login : la distribution des temps de réponse user-existant vs user-inexistant est statistiquement indistinguable (niveau 2), et le chemin de résolution est constant-time (niveau 1). Idem bon/mauvais secret.
- DoS pré-auth : N connexions pendantes n’empêchent pas une connexion légitime ; les slots sont récupérés par le login-grace.
- DoS réseau : sous SYN flood
hping3, le démon survit et se rétablit.
Un critère non atteint ouvre un correctif tracé, pas une exception silencieuse.
5. Séquence
C.0 (cet ADR) → déploiement de la cible linux-air sur speedy → audit non intrusif
(ssh-audit, Terrapin, nmap) → harnais dudect (niveau 1) → harnais timing réseau
(niveau 2) → brute-force → DoS pré-auth → DoS réseau. Chaque étape : résultat consigné,
critère coché ou correctif ouvert.
Conséquences
air-sshdacquiert une attestation de robustesse face aux attaques SSH connues, au-delà des tests unitaires — et une preuve de ses contre-mesures.- Aucune modification de couche n’est induite par cet ADR ; les correctifs éventuels suivront la discipline habituelle (additif couche 1 si besoin, jamais de raccourci).
- L’outillage vit sur
carbon, hors dépôt ; le harnais maison sera in-tree, test-only ([ADR-030]). - Dépendance : la campagne attend la clôture d’
air-sshd(fin de la phase SFTP) et un redéploiement linux-air de la cible surspeedy.
Alternatives rejetées
- Prouver le constant-time par le seul timing réseau. Rejeté : statistiquement non concluant (jitter). Le niveau 1 local est indispensable.
- N’utiliser que des outils tiers. Rejeté : aucun n’éprouve rigoureusement le timing SSH ni le DoS pré-auth — d’où le harnais maison.
- Tester la build gnu (plus simple à outiller). Rejeté : ce n’est pas le livrable (ADR-103). On éprouve ce qu’on livre.
- Lancer la campagne avant clôture. Rejeté : la surface bouge encore (SFTP en cours) ; on éprouve une cible figée.
Références
- ADR-093 — transport SSH-2, strict-KEX.
- ADR-094 — userauth : login-grace, essais bornés, anti-énumération.
- ADR-091 — motif sans-IO (harnais fuzzable/pur).
- CVE-2023-48795 — Terrapin. CVE-2018-15473 — énumération d’utilisateurs OpenSSH.