06_DEBUG_ET_SOLUTIONS.md 4.6 KB

Analyse & Résolution — Exit Status 255 + Shell Interactif

Lab sshproxy CEA-HPC en Docker


I. Résolution du blocage EXIT 255

Cause racine

Deux facteurs cumulés causaient exit status 255 lors du rebond SSH:

  1. Permissions insuffisantes sur la clé privée (critique)

    • Fichier /etc/sshproxy/gateway_rsa en 600 (root:root)
    • sshproxy s'exécute en tant que testuser (via ForceCommand sshd)
    • Résultat: Permission denied → SSH exit 255
  2. Absence de contrôle PTY explicite (secondaire)

    • Manque du flag -T ou -tt dans sshproxy.yaml
    • SSH sans directive PTY alloue un TTY par défaut → conflits

Solutions appliquées

Fix 1: Permissions (gateway/Dockerfile)

# Avant
RUN mkdir -p /etc/sshproxy
COPY keys/gateway_rsa /etc/sshproxy/gateway_rsa
RUN chmod 600 /etc/sshproxy/gateway_rsa

# Après
RUN mkdir -p /etc/sshproxy && chmod 755 /etc/sshproxy
COPY keys/gateway_rsa /etc/sshproxy/gateway_rsa
RUN chmod 600 /etc/sshproxy/gateway_rsa && chown testuser:testuser /etc/sshproxy/gateway_rsa

Fix 2: PTY allocation (gateway/sshproxy.yaml)

ssh:
  exe: "/usr/bin/ssh"
  args:
    - "-v"      # Verbose logs
    - "-tt"     # Force PTY allocation pour shell interactif
    - "-i"
    - "/etc/sshproxy/gateway_rsa"
    - "-o"
    - "StrictHostKeyChecking=no"
    - "-o"
    - "UserKnownHostsFile=/dev/null"

Résultat: ✅ Exit status 0 — rebond SSH fonctionne


II. Gestion des shells interactifs

Problème

sshproxy est conçu comme proxy de commandes, pas multiplexeur de shell.

Quand aucune commande n'est passée:

  • SSH client attend un shell interactif
  • sshproxy ne sait pas gérer une boucle stdin interactive
  • Connexion reste en attente (timeout ou freeze)

Solution: Wrapper de détection

Créé gateway/sshproxy-wrapper.sh qui détecte:

  • Commande fournie (SSH_ORIGINAL_COMMAND non vide) → proxifier via sshproxy ✓
  • Shell interactif (SSH_ORIGINAL_COMMAND vide) → rejet sécurisé avec message clair

    #!/bin/bash
    if [ -z "$SSH_ORIGINAL_COMMAND" ]; then
    echo "Interactive shells not permitted through sshproxy gateway." >&2
    echo "Usage: ssh user@gateway 'command'" >&2
    exit 1
    else
    exec /usr/sbin/sshproxy
    fi
    

Updated gateway/sshd_config:

ForceCommand /usr/sbin/sshproxy-wrapper

Résultat

# ✓ Commandes exécutées correctement
ssh -p 2222 testuser@gateway 'whoami; hostname; id'
# testuser
# dest2
# uid=1000(testuser) gid=1000(testuser) groups=1000(testuser)

# ✓ Shells interactifs rejetés proprement
ssh -p 2222 testuser@gateway
# Interactive shells not permitted through sshproxy gateway.
# Usage: ssh user@gateway 'command'

III. Topologie finale fonctionnelle

Windows SSH Client
    ↓ (ssh -p 2222 testuser@gateway 'commande')
    ↓ auth: lab_rsa
Gateway sshproxy (172.30.0.10:22)
    ├─→ Wrapper détecte commande
    └─→ sshproxy proxifie vers:
        ├─ dest1 (172.30.0.11) — random selection
        └─ dest2 (172.30.0.12) — 50% de chance chacun

Métrique: 5 connexions de test → distribution (dest2, dest2, dest2, dest1, dest1) ✓


IV. Architecture de sécurité

  • Windows→Gateway: Clé SSH ed25519 (lab_rsa) + authentification par clé
  • Gateway→Dest: Clé privée gateway_rsa gérée par sshproxy, transparente
  • Mode: Stateless (pas d'etcd pour cette phase)
  • Politiques:
    • ✓ Commandes SSH uniquement (pas de shells interactifs)
    • ✓ Pas de port forwarding (AllowTcpForwarding no)
    • ✓ Round-robin aléatoire automatique

V. Prochaines phases

Phase 1: DNS Docker + Service Discovery

  • Remplacer IPs par hostnames: dest1:22, dest2:22
  • Valider résolution DNS intra-Docker

Phase 2: etcd + Persistance

  • Intégrer service etcd (endpoints, health-checks)
  • Valider failover et persistance session

Phase 3: OpenLDAP

  • Remplacer comptes locaux par LDAP
  • PAM/NSS pour résolution centralisée

Phase 4: Migration Linux natif

  • Tests hors Docker Desktop
  • Kubernetes ou Docker Swarm multi-nœuds

VI. Fichiers modifiés

gateway/
├── Dockerfile          (Fix: permissions testuser + wrapper)
├── sshd_config         (Fix: ForceCommand → sshproxy-wrapper)
├── sshproxy.yaml       (Fix: ajout -tt pour PTY allocation)
└── sshproxy-wrapper.sh (NEW: détection commande vs shell)

keys/
├── lab_rsa
├── lab_rsa.pub
├── gateway_rsa
└── gateway_rsa.pub

Status: ✅ Lab fonctionnel — prêt pour intégration etcd et DNS Docker