Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ADR-074 — Vision air-sshd : démon SSH natif d’Air, wire-compatible OpenSSH mais pas opensshd (async io_uring, conf binaire, profil algorithmique moderne)

Statut : Accepté (2026-07-07, décision BDFL directe — vision cadrante ; le détail d’implémentation viendra par sous-ADR/RFC au fil des phases). S’appuie sur la Charte, les Principes d’ingénierie, le périmètre de connectivité tier-1 (ssh), et ADR-073 (configuration binaire). Consomme le socle réseau couche 1 d’ADR-069.

Catégorie : Vision d’un composant (couche 2+). Cadre un objectif majeur ; n’altère aucune couche scellée.

Contexte — pourquoi ne pas simplement porter OpenSSH

L’objectif intermédiaire « compiler OpenSSH sur Air » a été une fonction de forçage : il a servi à révéler et prioriser ce qui manquait fonctionnellement en couche 1 pour un vrai démon réseau (registre de handles, moteur socket, poll/select, résolution de noms). Cet objectif est atteint — mais porter OpenSSH n’est pas la fin visée.

OpenSSH, tel qu’implémenté, présente des défauts que la posture Air veut éliminer :

  • Sa configuration est en texte clair (~/.ssh/config, sshd_config) — surface d’attaque directe (cf. le modèle de menace d’ADR-073 : lecture/modification triviale par un shell compromis, réécriture de la conf du démon sous sudo permissif).
  • Sa base de code C historique porte tout un héritage d’algorithmes legacy (RSA-sha1, diffie-hellman-group1, modes CBC, etc.) que la charte Air veut ne pas faire cohabiter avec le moderne.
  • Le porter impliquerait la façade libc C et une libcrypto C-ABI — coûteux, et orthogonal à l’objectif.

Décision

Air fournit son propre démon SSH, air-sshd : compatible OpenSSH « on the wire » (protocole SSH-2, RFC 4251-4254, de sorte qu’un client ssh standard s’y connecte) mais PAS opensshd — une réimplémentation from-scratch en Rust, avec quatre partis pris :

  1. Asynchrone, sur le socle Air. air-sshd est bâti sur la runloop + io_uring d’Air (couche 0 Temps 2b réseau) et le socle couche 1 (air-socket/air-handle/ air-poll/air-runtime). Pas de thread-par-connexion bloquant : boucle d’événements.

  2. Configuration binaire (ADR-073). air-sshd lit sa configuration depuis un fichier binaire, manipulé par un CLI dédié sous ré-authentification administrateur. La compatibilité sshd_config texte, si fournie, passe par import/export — jamais par une conf texte vivante.

  3. Crypto native Rust, directe. air-sshd utilise l’API Rust d’air-crypto directementaucune libcrypto C-ABI, aucune façade libc. Le socle crypto est celui d’Air, sûr et audité côté Rust.

  4. Profil algorithmique moderne UNIQUEMENT — sûr par construction. air-sshd n’annonce et n’accepte que les algorithmes modernes, et refuse explicitement le legacy (pas de RSA-sha1, pas de diffie-hellman-group1, pas de CBC-EtM). Cible initiale, entièrement couverte par air-crypto aujourd’hui :

    • KEX : curve25519-sha256 (X25519 + SHA-256).
    • Clé d’hôte / signature : ssh-ed25519 (Ed25519).
    • Chiffrement authentifié : chacha20-poly1305@openssh.com et aes256-gcm@openssh.com.
    • MAC (pour les modes non-AEAD) : hmac-sha2-256/512.

    Le support RSA / ECDSA-NIST / DH-group est une extension de compatibilité client éventuelle et assumée comme non-souhaitée — pas un prérequis. « Le propre et le legacy ne cohabitent pas » (Charte).

Conséquences

  • air-sshd n’a besoin ni de la façade libc C ni d’une libcrypto C-ABI. Ces deux chantiers (les 55 manques libc, les ~120 symboles libcrypto révélés par la sonde OpenSSH) appartiennent à la piste distincte « compiler du C contre Air / clang air » et sont différés — ils ne sont pas sur le chemin critique d’air-sshd.
  • Le socle réseau couche 1 (ADR-069) est exactement ce que air-sshd consomme — le travail de la campagne réseau reste pleinement investi. Les shims socket libc restent un sous-produit utile à la piste C-toolchain.
  • Compatibilité = « on the wire », pas la conf. Un client ssh moderne se connecte à air-sshd ; en revanche la configuration est propriétaire/binaire (non compatible sshd_config, mais importable/exportable — ADR-073). C’est un choix de sécurité assumé.
  • Découpage en phases (chacune un sous-ADR/RFC + jalon) :
    1. Couche transport SSH-2 : échange d’identification (SSH-2.0-…), KEXINIT (négociation, n’annonçant que le moderne), KEX curve25519-sha256, dérivation de clés, protocole de paquets binaire chiffré (ChaCha20-Poly1305), le tout async.
    2. ssh-userauth : authentification publickey Ed25519 d’abord.
    3. ssh-connection : canaux, pty-req/shell/exec, redirections.
  • Provenance d’exécution : air-sshd s’inscrit dans la doctrine « exécution par provenance » d’Air (le shell servi, les binaires lancés) — à articuler au fil des phases.

Alternatives rejetées

  • Porter/compiler OpenSSH : conserve la surface d’attaque de la conf texte, tire la dépendance C + libcrypto, et impose l’héritage algorithmique legacy. C’était une fonction de forçage, pas la cible.
  • Enrober opensshd (wrapper) : reste opensshd, avec ses partis pris de conception.
  • Supporter les algorithmes legacy pour une compat client maximale : affaiblit la posture de sécurité ; contraire à la Charte. La compat legacy, si un jour nécessaire, sera un ajout explicite et délimité, jamais le défaut.