sshproxy-lab/
âââ docker-compose.yaml [CRĂĂ]
âââ keys/
â âââ lab_rsa [CRĂĂ] ClĂ© privĂ©e Windows
â âââ lab_rsa.pub [CRĂĂ] ClĂ© publique Windows
â âââ gateway_rsa [CRĂĂ] ClĂ© privĂ©e Gateway
â âââ gateway_rsa.pub [CRĂĂ] ClĂ© publique Gateway
âââ gateway/
â âââ Dockerfile [CRĂĂ] Build multi-stage sshproxy
â âââ sshd_config [CRĂĂ] Config SSH daemon + ForceCommand
â âââ sshproxy.yaml [CRĂĂ] Config sshproxy v2.1.0
â âââ sshproxy-wrapper.sh [CRĂĂ] Wrapper shell pour proxy
âââ dest/
âââ Dockerfile [CRĂĂ] Build destination simple
âââ sshd_config [CRĂĂ] Config SSH normal
Documentation:
âââ DOCUMENTATION_COMPLETE.md [GĂNĂRĂ] Explication dĂ©taillĂ©e (17KB)
âââ QUICK_REFERENCE.md [GĂNĂRĂ] Architecture visuelle + checklist
âââ ELI5_EXPLICATION.md [GĂNĂRĂ] Explication simplifiĂ©
âââ RESOLUTION_RAPPORT.md [GĂNĂRĂ] RĂ©solution du bug exit 255
âââ INDEX_FICHIERS.md [CE FICHIER]
docker-compose.yaml â Point de dĂ©partRĂŽle: Orchestrer 3 conteneurs Docker en rĂ©seau privĂ©
Contenu:
gateway: Gateway sshproxy (port 2222)dest1: Destination 1 (172.30.0.11)dest2: Destination 2 (172.30.0.12)172.30.0.0/24Pourquoi c'est important:
Modifié: Jamais (c'est le fichier principal)
gateway/Dockerfile â 2e fichier critiqueRĂŽle: Builder l'image du proxy
Ătapes (multi-stage):
Stage builder (golang:1.24-bookworm)
Stage final (debian:bookworm-slim)
testuserPourquoi c'est important:
Clés à retenir:
# 3 lignes critiques:
COPY keys/gateway_rsa /etc/sshproxy/gateway_rsa
RUN chown testuser:testuser /etc/sshproxy/gateway_rsa â ClĂ©!
COPY gateway/sshproxy-wrapper.sh /usr/sbin/sshproxy-wrapper
gateway/sshd_config â 3e fichier critiqueRĂŽle: Configuration du daemon SSH cĂŽtĂ© gateway
Parametres clés:
ForceCommand /usr/sbin/sshproxy-wrapper
âââ CRUCIAL! C'est la ligne qui rend tout transparent âââ
PasswordAuthentication no # Clé uniquement
PubkeyAuthentication yes # Accepte clés publiques
AuthorizedKeysFile .ssh/authorized_keys
PermitRootLogin no # Pas de root
AllowTcpForwarding no # Pas de -L/-R
X11Forwarding no # Pas de graphique
Différence vs dest:
ForceCommand â intercepteForceCommand â SSH normalgateway/sshproxy.yaml â 4e fichier critiqueRĂŽle: Configuration du proxy (destinations, stratĂ©gie, commandes SSH)
Sections:
log: "/tmp/sshproxy-{user}.log" # Fichier log par utilisateur
log_level: "debug" # Verbosité
ssh: # Commande SSH pour rebond
exe: "/usr/bin/ssh"
args:
- "-v" # Verbose
- "-tt" â CRUCIAL! # Force PTY (pour shell interactif)
- "-i" "/etc/sshproxy/gateway_rsa" # Clé privée
- "-o" "StrictHostKeyChecking=no" # Accepte nouvelles clés
- "-o" "UserKnownHostsFile=/dev/null" # Pas de known_hosts
etcd: # Clustering (vide = mode stateless)
endpoints: []
mandatory: false
dest: # Destinations Ă proxifier
- "172.30.0.11:22" # dest1
- "172.30.0.12:22" # dest2
route_select: "random" # Sélection aléatoire
mode: "balanced" # Mode équilibré
Le -tt c'est quoi?
-t = alloue un pseudo-terminal (shell interactif possible)
-tt = force allocation mĂȘme si no TTY en input
Sans ça: commandes OK mais shell freeze
gateway/sshproxy-wrapper.sh â Wrapper simpleRĂŽle: DĂ©tecte si c'est shell interactif ou commande, exĂ©cute sshproxy
Contenu:
#!/bin/bash
if [ -z "$SSH_ORIGINAL_COMMAND" ]; then
# Shell interactif (pas de commande)
exec /usr/sbin/sshproxy
else
# Commande fournie
exec /usr/sbin/sshproxy
fi
Observations:
dest/Dockerfile â Build simpleRĂŽle: Image pour dest1 et dest2
Contenu:
FROM debian:bookworm-slim # MĂȘme base que gateway
RUN apt-get install openssh-server # Juste sshd
# Crée testuser
# Copie gateway_rsa.pub dans authorized_keys
# Copie dest/sshd_config
Différence vs gateway/Dockerfile:
dest/sshd_config â Configuration destinationRĂŽle: SSH normal (pas d'interception)
Différence clé:
Gateway: ForceCommand /usr/sbin/sshproxy-wrapper (intercepte)
Dest: (pas de ForceCommand) (SSH normal)
keys/lab_rsa & keys/lab_rsa.pubRĂŽle: Client Windows â Gateway
Lab_rsa (privée):
Windows garde dans C:\Users\user\.ssh\lab_rsa
Utilisée pour: ssh -i lab_rsa -p 2222 localhost
lab_rsa.pub (publique):
Copié dans gateway:/home/testuser/.ssh/authorized_keys
Signature: autorise ce client
Génération:
ssh-keygen -t ed25519 -f keys/lab_rsa -N ""
keys/gateway_rsa & keys/gateway_rsa.pubRĂŽle: Gateway â Destinations
gateway_rsa (privée):
Compilée DANS l'image gateway
Utilisée par sshproxy pour rebond: ssh -i /etc/sshproxy/gateway_rsa testuser@dest
gateway_rsa.pub (publique):
Copié dans dest1/dest2:/home/testuser/.ssh/authorized_keys
Signature: autorise la gateway
Génération:
ssh-keygen -t ed25519 -f keys/gateway_rsa -N ""
1. Client Windows
Lit: keys/lab_rsa (privée)
2. Docker compose lance gateway
Lit: gateway/Dockerfile
Compile: sshproxy (depuis sources GitHub)
Copie: keys/gateway_rsa dans /etc/sshproxy
Copie: keys/lab_rsa.pub dans authorized_keys
Copie: gateway/sshd_config
Copie: gateway/sshproxy.yaml
Copie: gateway/sshproxy-wrapper.sh
Lance: /usr/sbin/sshd -D
3. Docker compose lance dest1/dest2
Lit: dest/Dockerfile
Copie: keys/gateway_rsa.pub dans authorized_keys
Copie: dest/sshd_config
Lance: /usr/sbin/sshd -D
4. Client se connecte
ssh -i keys/lab_rsa -p 2222 localhost
â
Gateway sshd lit authorized_keys
Retrouve lab_rsa.pub
Lance ForceCommand: /usr/sbin/sshproxy-wrapper
â
Wrapper lance /usr/sbin/sshproxy
â
sshproxy lit gateway/sshproxy.yaml
Choisit dest1 ou dest2 au hasard
Exécute rebond SSH avec keys/gateway_rsa
â
Destination sshd lit authorized_keys
Retrouve gateway_rsa.pub
Exécute commande
â
Résultat retourné au client
| Fichier | Responsabilité | Critique? |
|---|---|---|
| docker-compose.yaml | Orchestration 3 conteneurs | âââ |
| gateway/Dockerfile | Build + permissions | âââ |
| gateway/sshd_config | ForceCommand interception | âââ |
| gateway/sshproxy.yaml | -tt + destinations | âââ |
| gateway/sshproxy-wrapper.sh | Lance sshproxy | ââ |
| dest/Dockerfile | Build destination | ââ |
| dest/sshd_config | SSH normal | ââ |
| keys/lab_rsa | Auth clientâgateway | âââ |
| keys/gateway_rsa | Auth gatewayâdest | âââ |
â CrĂ©er docker-compose.yaml (3 services + rĂ©seau)
â CrĂ©er gateway/Dockerfile (build + config)
â CrĂ©er gateway/sshd_config (ForceCommand crucial!)
â CrĂ©er gateway/sshproxy.yaml (-tt crucial!)
â CrĂ©er gateway/sshproxy-wrapper.sh
â CrĂ©er dest/Dockerfile (simple)
â CrĂ©er dest/sshd_config (SSH normal)
â GĂ©nĂ©rer keys/lab_rsa + lab_rsa.pub
â GĂ©nĂ©rer keys/gateway_rsa + gateway_rsa.pub
â docker compose up -d
â ssh -p 2222 -i keys/lab_rsa testuser@localhost 'hostname'
â Voir dest1 ou dest2? â SuccĂšs!