← retour aux outils back to tools

# sshuttle

Proxy transparent au-dessus de SSH. Route des sous-réseaux entiers à travers une connexion SSH sans configuration VPN ni root sur l'hôte distant. Transparent proxy over SSH. Routes entire subnets through an SSH connection without VPN configuration or root on the remote host.

↗ https://github.com/sshuttle/sshuttle

## Overview

sshuttle creates a VPN-like tunnel over SSH that transparently routes traffic to specified subnets. Unlike SSH port forwarding, it handles entire CIDR ranges without configuration on the remote host. Requires Python on the remote host but no root.

## Basic Usage

Route all traffic through SSH host

    sshuttle -r user@jumphost 0.0.0.0/0

Route specific subnet only

    sshuttle -r user@jumphost 10.10.10.0/24

Route multiple subnets

    sshuttle -r user@jumphost 10.10.10.0/24 192.168.1.0/24

Exclude your host from routing (avoid routing SSH connection itself)

    sshuttle -r user@jumphost 0.0.0.0/0 --exclude $(host jumphost | awk '{print $NF}')

Specify SSH port

    sshuttle -r user@jumphost:2222 10.10.10.0/24

Background mode

    sshuttle -r user@jumphost 10.10.10.0/24 --daemon --pidfile /tmp/sshuttle.pid

## Authentication Options

SSH key authentication

    sshuttle -r user@jumphost 10.10.10.0/24 -e 'ssh -i /path/to/key.pem'

SSH with password (requires sshpass)

    sshuttle -r user@jumphost 10.10.10.0/24 -e 'sshpass -p password ssh'

SSH options passthrough

    sshuttle -r user@jumphost 10.10.10.0/24 \
      -e 'ssh -o StrictHostKeyChecking=no -i /path/to/key'

Jump host chain (pivot through multiple hops)

    sshuttle -r user@outer_host 10.10.10.0/24 \
      -e 'ssh -J user@jump_host'

## DNS Routing

Route DNS through the tunnel (resolve internal hostnames)

    sshuttle -r user@jumphost 10.10.10.0/24 --dns

Specify DNS server

    sshuttle -r user@jumphost 10.10.10.0/24 --dns --to-ns 10.10.10.1

## Firewall Methods

Use NAT method (default on Linux)

    sshuttle -r user@jumphost 10.10.10.0/24 --method nat

Use iptables TPROXY (better performance)

    sudo sshuttle -r user@jumphost 10.10.10.0/24 --method tproxy

macOS / BSD

    sshuttle -r user@jumphost 10.10.10.0/24 --method pf

## Kill & Management

Kill a daemonized sshuttle

    kill $(cat /tmp/sshuttle.pid)

Verbose output for debugging

    sshuttle -r user@jumphost 10.10.10.0/24 -v

Verbose showing actual connections

    sshuttle -r user@jumphost 10.10.10.0/24 -vv

## Common Pivoting Scenario

    # Scenario: compromised DMZ host (jumphost) can reach internal network 10.10.10.0/24

Step 1: Set up tunnel

    sshuttle -r user@jumphost_IP 10.10.10.0/24 --dns

    # Step 2: All traffic to 10.10.10.0/24 now goes through jumphost
    nmap -sV 10.10.10.5
    curl http://10.10.10.10/internal-api
    ssh admin@10.10.10.1

## Tips

- sshuttle doesn’t require `sudo` on the remote host — just Python
- Requires `sudo` on your local machine (needs to modify iptables/pf rules)
- `--dns` is essential when targeting internal services that use internal hostnames
- For multi-hop pivoting, chain with SSH `-J` jump hosts

Help / Man page

    sshuttle [options] [-r [user@]sshserver[:port]] <subnets>

    -r HOST         Remote SSH host (and optional port)
    -l ADDR         Local listen address (default: auto)
    -x SUBNET       Exclude subnet from routing
    -e CMD          SSH command to use
    --dns           Forward DNS queries through the tunnel
    --to-ns DNS     DNS server to forward to
    --daemon        Run as background daemon
    --pidfile FILE  PID file for daemon mode
    --method METHOD Firewall method: nat, tproxy, pf, ipfw
    -v              Verbose output
    -vv             More verbose
    --version       Print version

    Subnets:
      0.0.0.0/0     All IPv4 traffic
      ::/0          All IPv6 traffic
      10.0.0.0/8   Private class A
      192.168.0.0/16 Private class C

## Vue d’ensemble

sshuttle crée un tunnel de type VPN au-dessus de SSH qui route de manière transparente le trafic vers des sous-réseaux spécifiés. Contrairement au port forwarding SSH, il gère des plages CIDR entières sans configuration sur l’hôte distant. Nécessite Python sur l’hôte distant mais pas de root.

## Utilisation de base

    # Router tout le trafic à travers l'hôte SSH
    sshuttle -r user@jumphost 0.0.0.0/0

    # Router uniquement un sous-réseau spécifique
    sshuttle -r user@jumphost 10.10.10.0/24

    # Router plusieurs sous-réseaux
    sshuttle -r user@jumphost 10.10.10.0/24 192.168.1.0/24

    # Exclure son propre hôte du routage (éviter de router la connexion SSH elle-même)
    sshuttle -r user@jumphost 0.0.0.0/0 --exclude $(host jumphost | awk '{print $NF}')

    # Spécifier le port SSH
    sshuttle -r user@jumphost:2222 10.10.10.0/24

    # Mode arrière-plan
    sshuttle -r user@jumphost 10.10.10.0/24 --daemon --pidfile /tmp/sshuttle.pid

## Options d’authentification

    # Authentification par clé SSH
    sshuttle -r user@jumphost 10.10.10.0/24 -e 'ssh -i /path/to/key.pem'

    # SSH avec mot de passe (nécessite sshpass)
    sshuttle -r user@jumphost 10.10.10.0/24 -e 'sshpass -p password ssh'

    # Transmission d'options SSH
    sshuttle -r user@jumphost 10.10.10.0/24 \
      -e 'ssh -o StrictHostKeyChecking=no -i /path/to/key'

    # Chaîne de jump hosts (pivoter à travers plusieurs sauts)
    sshuttle -r user@outer_host 10.10.10.0/24 \
      -e 'ssh -J user@jump_host'

## Routage DNS

    # Router le DNS à travers le tunnel (résoudre les noms d'hôtes internes)
    sshuttle -r user@jumphost 10.10.10.0/24 --dns

    # Spécifier un serveur DNS
    sshuttle -r user@jumphost 10.10.10.0/24 --dns --to-ns 10.10.10.1

## Méthodes de pare-feu

    # Utiliser la méthode NAT (par défaut sous Linux)
    sshuttle -r user@jumphost 10.10.10.0/24 --method nat

    # Utiliser iptables TPROXY (meilleures performances)
    sudo sshuttle -r user@jumphost 10.10.10.0/24 --method tproxy

    # macOS / BSD
    sshuttle -r user@jumphost 10.10.10.0/24 --method pf

## Arrêt et gestion

    # Arrêter un sshuttle démonisé
    kill $(cat /tmp/sshuttle.pid)

    # Sortie verbeuse pour débogage
    sshuttle -r user@jumphost 10.10.10.0/24 -v

    # Verbeux montrant les connexions réelles
    sshuttle -r user@jumphost 10.10.10.0/24 -vv

## Scénario de pivoting courant

    # Scénario : hôte DMZ compromis (jumphost) pouvant atteindre le réseau interne 10.10.10.0/24

Étape 1 : mettre en place le tunnel

    sshuttle -r user@jumphost_IP 10.10.10.0/24 --dns

    # Étape 2 : tout le trafic vers 10.10.10.0/24 passe maintenant par jumphost
    nmap -sV 10.10.10.5
    curl http://10.10.10.10/internal-api
    ssh admin@10.10.10.1

## Conseils

- sshuttle ne nécessite pas `sudo` sur l’hôte distant : juste Python
- Nécessite `sudo` sur sa propre machine (doit modifier les règles iptables/pf)
- `--dns` est essentiel quand on cible des services internes qui utilisent des noms d’hôtes internes
- Pour du pivoting multi-sauts, chaîner avec les jump hosts SSH `-J`

Aide / Page de manuel

    sshuttle [options] [-r [user@]sshserver[:port]] <subnets>

    -r HOST         Remote SSH host (and optional port)
    -l ADDR         Local listen address (default: auto)
    -x SUBNET       Exclude subnet from routing
    -e CMD          SSH command to use
    --dns           Forward DNS queries through the tunnel
    --to-ns DNS     DNS server to forward to
    --daemon        Run as background daemon
    --pidfile FILE  PID file for daemon mode
    --method METHOD Firewall method: nat, tproxy, pf, ipfw
    -v              Verbose output
    -vv             More verbose
    --version       Print version

    Subnets:
      0.0.0.0/0     All IPv4 traffic
      ::/0          All IPv6 traffic
      10.0.0.0/8   Private class A
      192.168.0.0/16 Private class C