Page 1 of 1

HowTo: OpenVPN through SSH tunnel

PostPosted: Mon Mar 04, 2019 10:11 pm
by peter_b
In this HowTo, I'll describe how to set up an OpenVPN connection to a server that is accessible only through an SSH port forward.
This config will only create a single point-to-point connection. No subnet routing, just 2 IPs: Server + Client.

The assumed scenario here is Ubuntu/Debian based and was tested with Xubuntu 16.04.6 (Xenial) as client and Debian 9 (Stretch) as server :D

1) Install OpenVPN packages on both: client and server:
Code: Select all
$ apt install openvpn

In our case the client was v2.3.10 and server v2.4.0. Still worked.

2) Create server config:
On the server: Store the following as "/etc/openvpn/server/main.conf"
Code: Select all
port 1194
proto tcp-server
cipher none
dev tun1

keepalive 10 120
verb 3

I've disabled VPN encryption, because the traffic is tunneled through SSH - so there's already an encryption layer.

3) Start OpenVPN server:
Code: Select all
$ openvpn --config /etc/openvpn/server/server.conf

4) Create client config:
On the client: Store the following as "/etc/openvpn/client/main.conf"
Code: Select all
remote localhost 1194

proto tcp-client
port 1194
dev tun1


socks-proxy 8080

5) Establish SSH tunnel as proxy:
See the 2 SOCKS proxy lines at the bottom of the client config?
Dynamic port forwarding of SSH will serve as SOCKS proxy 8)

I like to use "~/.ssh/config" for this.

Create a config block pointing to your SSH entrypoint that will allow you to access the OpenVPN server.
Might look something like this:
Code: Select all
Host entrypoint
    Hostname <HOSTNAME>
    Port <SSHPORT>
    # SOCKS:
    DynamicForward 8080

Now connect to the SSH server:
Code: Select all
$ ssh entrypoint

Once you're in, your local port #8080 will now act as a SOCKS proxy - which the VPN client config was configured to use.
So let's put the puzzle together:

6) Connect the OpenVPN client
Code: Select all
$ openvpn --config /etc/openvpn/client/main.conf

If all goes well, you will see something like this:
Mon Mar 4 16:52:39 2019 Connection reset, restarting [0]
Mon Mar 4 16:52:39 2019 /sbin/ip addr del dev tun1 local peer
Mon Mar 4 16:52:39 2019 SIGUSR1[soft,connection-reset] received, process restarting
Mon Mar 4 16:52:44 2019 ******* WARNING *******: all encryption and authentication features disabled -- all data will be tunnelled as cleartext
Mon Mar 4 16:52:44 2019 TUN/TAP device tun1 opened
Mon Mar 4 16:52:44 2019 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Mon Mar 4 16:52:44 2019 /sbin/ip link set dev tun1 up mtu 1500
Mon Mar 4 16:52:44 2019 /sbin/ip addr add dev tun1 local peer
Mon Mar 4 16:52:44 2019 Attempting to establish TCP connection with [AF_INET] [nonblock]
Mon Mar 4 16:52:44 2019 TCP connection established with [AF_INET]
Mon Mar 4 16:52:44 2019 TCPv4_CLIENT link local: [undef]
Mon Mar 4 16:52:44 2019 TCPv4_CLIENT link remote: [AF_INET]
Mon Mar 4 16:52:45 2019 Peer Connection Initiated with [AF_INET]
Mon Mar 4 16:52:46 2019 Initialization Sequence Completed

While the tunnel is open, you will have a "tun1" network interface, and a corresponding route entry.
For example, this is "route -n" on the client:
Code: Select all
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface UH    0      0        0 tun1

You should now be able to access the server as "" and the client as "".

Enjoy! :D