A poor man's VPN — join a remote network over plain SSH.
net-ssh uses SSH's built-in tunnel support (ssh -w) to create a point-to-point
tun interface between your machine and a remote server, then configures local
routing and remote iptables/NAT rules so you can reach a network behind that
server as if you were on a real VPN.
It was written as a personal replacement for sshuttle,
which is great in many ways except speed. Instead of routing/forwarding packets
itself, net-ssh delegates that job to iptables, which in practice yields
2-5x faster throughput depending on the link between client and server.
Only reach for this over sshuttle if:
- you have remote root access via SSH, and
- you need a faster channel than sshuttle provides.
- Perl,
iproute2,iptableson both client and server - Root access on both ends
- Server's
sshd_configmust havePermitTunnel yes
net-ssh --server=[user@]host[:port] --net=<CIDR> [options...] [-- ssh-options]
| Option | Alias | Default | Description |
|---|---|---|---|
--server |
-s |
— | Remote SSH gate-in server, e.g. root@12.34.56.78:20022 (user defaults to root, port defaults to 22) |
--net-remote |
--net, -N |
— | Remote network to join, e.g. 10.1.1.0/24. Repeatable for multiple networks. Required. |
--tun-spec |
-t |
1:1 |
Local:remote tunnel device numbers, e.g. 2:5 creates tun2 locally and tun5 on the server |
--tun-addr |
-T |
10.190.190.250:251 |
Local (and optional remote) tunnel IP, e.g. 10.190.190.1:2 |
--dry-run |
--dry |
— | Print the commands without executing them |
--help |
— | — | Show help |
Anything after --, or any option net-ssh doesn't recognize, is passed straight through to the underlying ssh command.
Must be run as root - it temporarily patches routing table and iptables locally and remotely to allow bidirectional packet routing between local and remote subnets.
net-ssh --server=root@12.34.56.78:20022 --net=10.1.1.0/24 --tun-spec=2:5 --tun-addr=10.190.190.1:2
SSHes as root into 12.34.56.78:20022, creates tun2 on the client and tun5
on the server, assigns 10.190.190.1 to tun2 and 10.190.190.2 to tun5,
then configures routing on the client and iptables on the server so the
client can reach 10.1.1.0/24.
net-ssh --server=root@12.34.56.78 --net=10.1.1.0/24 --net=10.2.0.0/16
Pass --net/--net-remote more than once to route several remote networks
through the same tunnel in one session. Uses the default tunnel device (tun1)
and default tunnel addresses since none are specified.
net-ssh --server=root@12.34.56.78 --net=10.1.1.0/24 --dry-run -- -i ~/.ssh/id_ed25519 -v
--dry-run prints the local/remote commands net-ssh would run without
executing them, which is handy for reviewing the routing/iptables changes
before committing to them. Everything after -- (here, an identity file and
verbose logging) is forwarded directly to ssh.