# Accéder à un service interne via un bastion
ssh -N -L 8080:internal.corp:80 user@jump
# Plusieurs tunnels dans la même session
ssh -N -L 8080:internal.corp:80 -L 5432:db.internal:5432 user@jump
# Arrière-plan, sans shell, échec si le port local est occupé
ssh -fNT -o ExitOnForwardFailure=yes -L 8080:internal:80 user@jump
# Rendre le port accessible aux autres machines de ton réseau
ssh -g -N -L 8080:internal:80 user@jump
# Forward d'un socket Unix (Docker, par exemple)
ssh -N -L /tmp/docker.sock:/var/run/docker.sock user@jump
bash
# Vérifier que le port écoute
ss -tlnp | grep 8080
curl -s http://127.0.0.1:8080/
# Exposer un service local sur le loopback du bastion
ssh -N -R 9001:127.0.0.1:9001 user@jump
# Exposer sur toutes les interfaces du bastion (GatewayPorts requis)
ssh -N -R 0.0.0.0:9001:127.0.0.1:9001 user@jump
# Laisser le serveur choisir le port (affiché en verbose)
ssh -v -N -R 0:127.0.0.1:9001 user@jump
# Callback pour un reverse shell (voir aussi /sheets/reverse-shells/)
ssh -N -R 4444:127.0.0.1:4444 user@jump
bash
# Sur le serveur SSH, pour autoriser un bind non-loopback# /etc/ssh/sshd_config.d/forwarding.conf
GatewayPorts clientspecified
eval"$(ssh-agent -s)"
ssh-add -t 8h ~/.ssh/id_ed25519
ssh-add -l
# Forward de l'agent : pratique, mais risqué sur un hôte non fiable
ssh -A user@jump
text
# ~/.ssh/authorized_keys
# Clé de backup : uniquement cette commande, depuis ce réseau
restrict,command="/usr/local/bin/backup",from="10.10.10.0/24" ssh-ed25519 AAAA...
# Clé de tunnel : pas de shell, uniquement le forwarding
restrict,pty,port-forwarding ssh-ed25519 AAAA...
# /etc/ssh/sshd_config.d/hardening.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding local
PermitOpen git.internal:22 db.internal:5432
ClientAliveInterval 60
ClientAliveCountMax 3