rss logo

Setting Up an OpenSSH VPN Tunnel Between Debian 12 and Arch Linux

OpenSSH Logo

Intro

In one of my many projects, I needed to access a network that only exposed an SSH server. I knew that SSH tools were capable of creating a VPN tunnel, but I had never actually tried it before. As it turns out, it's quite simple to set up and can be really useful in a variety of situations.

In this article, I'll walk you through the steps to set up a temporary VPN using OpenSSH.

Network diagram

Diagram of an SSH VPN tunnel between a Debian 12 server and an Arch Linux client, using tun0 interfaces on both sides via OpenSSH.
SSH VPN Network Architecture Overview

Debian (Destination)

  • IP configuration:
    • eth0: 192.168.1.10/24
    • tun0: 10.110.0.100/32

Prerequisites

Edit the SSH server configuration

  • Edit /etc/ssh/sshd_config to enable root login and tunneling:
PermitRootLogin yes
PermitTunnel yes
  • Then restart the SSH service to apply the changes:
root@host:~# systemctl restart sshd

Set up NAT

We need to add a masquerade rule so that the client can access the remote network. Below are examples using either iptables or nftables.

  • First, enable IP forwarding (routing):
root@host:~# echo 1 | tee /proc/sys/net/ipv4/ip_forward
  • Using iptables:
root@host:~# iptables -t nat -A POSTROUTING -d 192.168.1.0/24 -o eth0 -j MASQUERADE
  • Using nftables:
root@host:~# nft add table ip NAT
root@host:~# nft add chain ip NAT my_masquerade '{ type nat hook postrouting priority 100; }'
root@host:~# nft add rule NAT my_masquerade ip daddr { 192.168.1.0/24 } oifname eth0 counter masquerade

Now that the Debian server is pre-configured, we can move on to starting the SSH tunnel from the client.

Source: Archlinux

  • IP configuration:
    • eth0: 192.168.2.10/24
    • tun0: 10.110.0.200/32

Commands

  • -w local_tun[:remote_tun]: Request tunnel device forwarding between client and server using tun interfaces.
  • -N: Do not execute a remote command.
  • -f: Run SSH in the background after authentication.
root@host:~# ssh -Nf -w 0:0 -p 22 root@1.1.1.1
  • Assign an IP address to the tun0 interface:
root@host:~# ip addr add 10.110.0.200/32 peer 10.110.0.100 dev tun0
  • Bring up the tun0 interface:
root@host:~# ip link set tun0 up
  • Add a route to reach the remote (server-side) network:
root@host:~# ip route add 192.168.1.0/24 via 10.110.0.100

Establishing the Tunnel (Debian)

After running the SSH command (ssh -Nf -w 0:0) on the client, a tun0 virtual interface should automatically appear on the Debian server. The final step is to bring up and configure this interface on the server side.

  • Assign an IP address to the tun0 interface:
root@host:~# ip addr add 10.110.0.100/32 peer 10.110.0.200 dev tun0
  • Bring up the tun0 interface:
root@host:~# ip link set tun0 up

That's it! The 192.168.1.0/24 network (remote side) should now be reachable from the client through the SSH tunnel.

References