← retour aux snippets

ssh: proxy SOCKS5 dynamique

Créer un proxy SOCKS5 local via SSH (-D) et router curl/git vers api.data.pm depuis le réseau du bastion.


objectif

Établir un proxy SOCKS5 local avec ssh -D pour accéder à des ressources comme api.data.pm via un bastion, sans ouvrir de ports distants, et éviter les fuites DNS.

code minimal

# ouvre un SOCKS5 local sur 127.0.0.1:1080 via le bastion
ssh -N -D 127.0.0.1:1080 user@bastion.data.pm

# tester en forçant la résolution côté proxy (socks5h)
curl -fsS --socks5-hostname 127.0.0.1:1080 https://api.data.pm/health

utilisation

# 1) lancer en arrière-plan après authentification (-f) et fail-fast si le bind échoue
ssh -f -N -D 127.0.0.1:1080 -o ExitOnForwardFailure=yes \
  -o ServerAliveInterval=60 -o ServerAliveCountMax=3 \
  user@bastion.data.pm

# 2) utiliser le proxy avec curl (DNS via proxy: socks5h)
curl -fsS --socks5-hostname 127.0.0.1:1080 https://data.pm/

# 3) variables d'env pour outiller tout l'écosystème (git, npm, etc.)
export ALL_PROXY="socks5h://127.0.0.1:1080"
# exemple: git clone via bastion (si la forge est publique, c'est juste pour l'exemple)
git ls-remote https://git.data.pm/org/repo.git | head -n1

# 4) atteindre une cible interne (ex: admin.data.pm) via bastion
curl -fsS --socks5-hostname 127.0.0.1:1080 http://admin.data.pm/internal/status

# 5) fermer proprement la session
pkill -f 'ssh -f -N -D 127.0.0.1:1080' || true

variante(s) utile(s)

# config dédiée (~/.ssh/config) pour simplifier
cat >> ~/.ssh/config <<'SSHCONF'
Host bastion
  HostName bastion.data.pm
  User user
  ControlMaster auto
  ControlPersist 15m
  ControlPath ~/.ssh/cm/%C
  ServerAliveInterval 60
  ServerAliveCountMax 3
SSHCONF

# démarrer le SOCKS via l'alias
ssh -f -N -D 127.0.0.1:1080 bastion

# chaîner via ProxyJump jusqu'à un hôte interne puis créer le SOCKS sur la chaîne
ssh -f -N -J bastion user@intranet.data.pm -D 127.0.0.1:1080

# choisir un port aléatoire libre et l'exporter
PORT="$(python3 - <<'PY'
import socket; s=socket.socket(); s.bind(('127.0.0.1',0)); p=s.getsockname()[1]; s.close(); print(p)
PY
)"
ssh -f -N -D "127.0.0.1:$PORT" bastion && export ALL_PROXY="socks5h://127.0.0.1:$PORT"

# vérifier l'IP de sortie (doit correspondre au bastion/data center)
curl -fsS --socks5-hostname 127.0.0.1:1080 https://ifconfig.me/ip

notes

  • utilisez --socks5-hostname (ou socks5h://) pour que la résolution DNS se fasse via le proxy (évite les fuites DNS).
  • liez toujours sur 127.0.0.1 pour ne pas exposer le proxy sur le réseau. Évitez -D 0.0.0.0:1080.
  • -f -N place la session en arrière-plan sans exécuter de commande distante; combinez avec -o ExitOnForwardFailure=yes.
  • combinez avec le multiplexage SSH (ControlMaster) pour des démarrages instantanés et une meilleure stabilité.
  • pensez à révoquer/fermer la session (pkill ou ssh -O exit) quand vous n’en avez plus besoin.