What Is VPN over SSH?
VPN over SSH is an open-source SSH tunneling tool built by kleimer that turns stock OpenSSH into an L3 tunnel for Linux and Windows clients. VPN over SSH is one of the best SSH tunneling tools for Linux admins, DevOps engineers, and mixed-platform operators who want encrypted routing without deploying WireGuard, OpenVPN, or a custom control plane. The default pool spans tun100..tun200, which gives 101 tunnel slots and makes the server side predictable instead of dynamic.
The design goal is simple: reuse the SSH transport you already trust, then layer TUN-based packet forwarding on top. That means the server runs a separate sshd instance on port 65523, clients attach with ssh -w, and traffic exits through NAT on the WAN interface instead of through a dedicated VPN appliance.
Quick Overview
| Attribute | Details |
|---|---|
| Type | SSH tunneling |
| Best For | Linux admins, DevOps engineers, and mixed Linux/Windows teams that want a VPN without a dedicated VPN daemon |
| Language/Stack | OpenSSH ssh -w, Linux TUN/TAP, systemd, iptables, Go, Wintun |
| License | N/A |
| GitHub Stars | N/A as of Feb 2026 |
| Pricing | Open-Source |
| Last Release | N/A |
Who Should Use VPN over SSH?
- Ops teams that already trust SSH and want to avoid rolling out a second remote-access stack. VPN over SSH reuses key-based auth, SSH host keys, and familiar SSH ACLs instead of introducing another daemon and config language.
- Indie hackers and solo maintainers who need a private network for staging, admin access, or internal services but do not want to maintain a full VPN appliance. The server bootstrap is a shell script, not a distributed control plane.
- Mixed Linux/Windows environments that need the same routing model on both desktop classes. VPN over SSH ships a Linux shell client and a Windows Go client with Wintun, so the operational model stays close across platforms.
- Teams that need split tunneling for internal CIDRs while keeping local routes or private subnets outside the tunnel. The client supports include/exclude CIDRs and route lists, which is more practical than a hard-coded full-tunnel policy.
Not ideal for:
- High-throughput site-to-site links where kernel-space crypto and lower overhead matter more than SSH compatibility. WireGuard will usually win on latency and throughput.
- Organizations that require a centralized identity plane with device posture, SSO, and fine-grained ACLs. VPN over SSH keeps the control surface intentionally small.
- Networks that must carry native IPv6 end to end. The Linux client adds IPv6 leak protection, but the repo is centered on IPv4 routing and NAT.
Key Features of VPN over SSH
- Separate SSHD instance — The server does not modify the system SSH service on
22/tcp. It installs an isolatedsshdinstance for the tunnel service, which reduces blast radius and makes rollback easier if you already have a production SSH daemon. - Precreated TUN pool — The server prepares
tun100..tun200ahead of time, then clients randomly claim a free interface. That avoids per-connection device creation races and makes the mapping between interface number and/30block deterministic. - Deterministic
/30addressing — The repo maps tunnel numbers into10.250.0.0/16using/30blocks, so client and server addresses can be derived from thetunNindex. This is a practical trick for operators who hate hand-assigning IPs during onboarding. - Full-tunnel and split-tunnel modes — Linux and Windows clients can route all IPv4 traffic through the tunnel, or send only specific CIDRs through it. The full-tunnel path uses
0.0.0.0/1and128.0.0.0/1, which preserves an explicit bypass route to the server IP. - DNS and leak controls on Linux — The shell client can push DNS with
resolvectl, block IPv6 leakage with a blackhole route, and clean up stale managedtunNdevices. That is the difference between a demo tunnel and something you can leave running on a laptop. - Windows support with Wintun — The Go client uses Wintun and mirrors the Linux CLI, so admin workflows stay consistent. It also stores state in
C:\ProgramData\sshtun_pool_client\state.jsonand writes logs toC:\ProgramData\sshtun_pool_client\sshtun.log. - Host key pinning and key hygiene — The Windows client supports
--host-key-sha256, and the server-sideauthorized_keysentry can be locked down withno-pty,no-agent-forwarding,no-X11-forwarding, andno-port-forwarding. That keeps the tunnel account narrow and auditable.
VPN over SSH vs Alternatives
If you are standardizing the surrounding infrastructure, pair this with djevops for server automation, or browse all DevOps Automation tools if you are comparing adjacent deployment helpers.
| Tool | Best For | Key Differentiator | Pricing |
|---|---|---|---|
| VPN over SSH | SSH-based remote access with minimal server changes | Uses ssh -w, a prebuilt TUN pool, and a separate sshd instance | Open-Source |
| WireGuard | Low-latency site-to-site and roaming VPNs | Kernel-level crypto and smaller protocol surface | Open-Source |
| OpenVPN | Legacy enterprise VPN deployments | Mature ecosystem, TLS control plane, broad client support | Open-Source |
| Tailscale | Zero-config mesh networking for distributed teams | Managed control plane, NAT traversal, ACLs, device UX | Freemium |
Pick WireGuard when raw performance and simple encrypted routing matter more than SSH compatibility. It is the better answer for always-on tunnels, especially when you control both ends and want fewer moving parts in the dataplane.
Pick OpenVPN when you need legacy compatibility, certificate-heavy policy, or an existing operational investment in OpenVPN tooling. VPN over SSH is lighter, but OpenVPN still has the deeper enterprise footprint.
Pick Tailscale when you want identity-aware mesh networking with minimal manual routing. It trades control-plane simplicity for vendor-managed coordination, which is useful if you do not want to own the bootstrap and ACL workflow.
How VPN over SSH Works
VPN over SSH uses a very small control model: one server-side SSH endpoint, one reserved TUN pool, one NAT path to the WAN, and a client that binds a local TUN adapter to the remote SSH session. The server script creates the interfaces, enables net.ipv4.ip_forward=1, sets up forwarding rules, and keeps the tunnel service isolated from the main SSH daemon.
The important abstraction is the tunN index. The client does not need to know its address in advance, because the address pair is derived from the selected interface number inside 10.250.0.0/16. That makes onboarding deterministic, reduces config drift, and keeps the route logic simple enough to debug with ip addr, ip route, and ss -lntp.
A minimal start looks like this:
sudo bash install_server.sh
sudo bash sshtun_pool_client.sh start --host SERVER_IP --key ./id_ed25519
The first command builds the server side: user, host key, systemd units, TUN pool, and NAT rules. The second command attaches a Linux client to the tunnel, requests a free tunN, and rewrites routes so traffic flows through the encrypted SSH session.
Pros and Cons of VPN over SSH
Pros:
- No separate VPN daemon — The stack rides on OpenSSH, so you avoid another long-lived network service and another config surface to audit.
- Predictable server bootstrap —
install_server.shcreates systemd units, a privatesshdconfig, forwarding rules, and the TUN pool in one pass. - Linux and Windows parity — The same operational model exists on both clients, which reduces runbook drift across workstation types.
- Split-tunnel support — CIDR include/exclude lists make it usable for internal service access without forcing all traffic through the tunnel.
- Built-in leak handling — Linux DNS and IPv6 controls reduce the common class of accidental bypasses that break privacy or internal routing.
Cons:
- Not a high-performance VPN — SSH transport adds overhead, and the design is not trying to compete with kernel-native VPNs on throughput.
- Requires root or admin privileges — Both the server and clients need elevated permissions for TUN devices and route changes.
- Operationally IPv4-first — The repo centers on IPv4 addressing and NAT, so dual-stack environments need extra care.
- Less policy expressiveness — You get tunnel routing, host-key pinning, and restricted SSH keys, but not the identity and ACL depth of a managed mesh platform.
- Single-purpose server design — The separate SSHD instance is clean, but it is still a custom service to monitor and patch.
Getting Started with VPN over SSH
Start by installing the server side, then generate a per-device SSH key, and finally attach a client with either full-tunnel or split-tunnel routing. That flow keeps the server deterministic and keeps user onboarding as a normal SSH key distribution problem instead of a bespoke VPN enrollment workflow.
# server
sudo bash install_server.sh
systemctl status sshtun-pool-sshd.service --no-pager
systemctl status sshtun-pool-network.service --no-pager
# client
ssh-keygen -t ed25519 -f ./id_ed25519 -N '' -C user-device
sudo bash sshtun_pool_client.sh start --host SERVER_IP --key ./id_ed25519
After the server install, verify that port 65523 is listening and that tun100 and tun101 exist before you enroll real users. On Linux, the client can then run status, doctor, and cleanup to inspect routing, DNS, and stale interfaces; on Windows, the Go client builds to dist\sshtun_pool_client.exe plus dist\wintun.dll and exposes the same lifecycle commands.
Verdict
VPN over SSH is the strongest option for SSH-native remote access when you want a small, auditable setup and can accept SSH-level throughput. Its main strength is the separate sshd plus TUN-pool design, which keeps the server side simple; the caveat is that it is still an IPv4-first, root-required tunnel stack rather than a full enterprise VPN platform. Use it when operational simplicity beats feature breadth.



