# Index complet des fichiers du projet ## 📂 Structure du projet ``` 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] ``` --- ## 📋 DĂ©tail de chaque fichier ### INFRASTRUCTURE & ORCHESTRATION #### `docker-compose.yaml` ← Point de dĂ©part **RĂŽle**: Orchestrer 3 conteneurs Docker en rĂ©seau privĂ© **Contenu**: - Service `gateway`: Gateway sshproxy (port 2222) - Service `dest1`: Destination 1 (172.30.0.11) - Service `dest2`: Destination 2 (172.30.0.12) - RĂ©seau privĂ©: `172.30.0.0/24` **Pourquoi c'est important**: - Chaque conteneur a une IP fixe (sshproxy doit savoir oĂč envoyer) - Port 2222 exposĂ© pour accĂšs depuis Windows - RĂ©seau isolĂ© (pas de sortie internet) **ModifiĂ©**: Jamais (c'est le fichier principal) --- ### GATEWAY — AUTHENTIFICATION & ORCHESTRATION #### `gateway/Dockerfile` ← 2e fichier critique **RĂŽle**: Builder l'image du proxy **Étapes** (multi-stage): 1. **Stage builder** (golang:1.24-bookworm) - Clone sshproxy v2.1.0 depuis GitHub - Compile 4 binaires Go (sshproxy, dumpd, replay, ctl) 2. **Stage final** (debian:bookworm-slim) - Installe sshd + ca-certificates - Copie binaires compilĂ©s du stage builder - CrĂ©e compte `testuser` - Copie et configure clĂ©s SSH - Configure sshd via sshd_config - Copie config sshproxy.yaml - Copie wrapper shell **Pourquoi c'est important**: - Multi-stage = image finale petit (pas de Go compiler) - Permissions testuser sur gateway_rsa = crucial (Ă©vite "Permission denied") - sshd sera lancĂ© au dĂ©marrage conteneur **ClĂ©s Ă  retenir**: ```dockerfile # 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 critique **RĂŽ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**: - Gateway a `ForceCommand` → intercepte - Dest n'a pas de `ForceCommand` → SSH normal --- #### `gateway/sshproxy.yaml` ← 4e fichier critique **RĂŽle**: Configuration du proxy (destinations, stratĂ©gie, commandes SSH) **Sections**: ```yaml 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 simple **RĂŽle**: DĂ©tecte si c'est shell interactif ou commande, exĂ©cute sshproxy **Contenu**: ```bash #!/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**: - Les deux branches font la MÊME chose! - sshproxy dĂ©tecte automatiquement le mode - Wrapper existe pour future extensibilitĂ© (audit, ACL, etc.) --- ### DESTINATIONS — SSH NORMAL #### `dest/Dockerfile` ← Build simple **RĂŽle**: Image pour dest1 et dest2 **Contenu**: ```dockerfile 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**: - ✗ Pas de Go builder - ✗ Pas de sshproxy (juste sshd) - ✗ Beaucoup plus simple --- #### `dest/sshd_config` ← Configuration destination **RĂŽle**: SSH normal (pas d'interception) **DiffĂ©rence clĂ©**: ``` Gateway: ForceCommand /usr/sbin/sshproxy-wrapper (intercepte) Dest: (pas de ForceCommand) (SSH normal) ``` --- ### AUTHENTIFICATION — CLÉS SSH #### `keys/lab_rsa` & `keys/lab_rsa.pub` **RĂŽ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**: ```bash ssh-keygen -t ed25519 -f keys/lab_rsa -N "" ``` --- #### `keys/gateway_rsa` & `keys/gateway_rsa.pub` **RĂŽ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**: ```bash ssh-keygen -t ed25519 -f keys/gateway_rsa -N "" ``` --- ## 🔄 Flux de fichiers lors d'une connexion ``` 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 ``` --- ## 📊 RĂ©sumĂ©: ResponsabilitĂ©s de chaque fichier | 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 | ⭐⭐⭐ | --- ## 🚀 Checklist de configuration ``` ☐ 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! ``` --- ## 📚 Documentation associĂ©e - **DOCUMENTATION_COMPLETE.md**: Explication ligne par ligne de chaque fichier - **QUICK_REFERENCE.md**: Diagrammes + checklist - **ELI5_EXPLICATION.md**: Version simplifiĂ©e pour non-techniciens - **RESOLUTION_RAPPORT.md**: Comment on a rĂ©solu le bug exit 255