Host to LAN Tunnel HowTo

About

This document provides an example of how to connect to a network using OpenVPN with certificates for authentication, and a username/password pair for an extra layer of security.

Introduction

Picture a road traffic monitoring system with a control center and a number of mobile stations that should be able to connect to the control center over a public network to report vehicle data and receive configuration information.

       .-------.  .-------.
       | HostA |  | HostB |
       '---+---'  '---+---'
         .2|          |.2
           '---.  .---'
10.0.1.0/24    |  |    10.0.2.0/24
             .1|  |.1
            .--+--+--.                         .---------.
            |        |    OpenVPN L3 Tunnel    |         |
            | Server +=========================+ Client1 |
            |        | ssl0               ssl0 |         |
            '----+---' 10.0.3.1                '----+----'
      Public IP: |                                  |
    198.18.19.20 |             .--.-.               |
                 |             ( (    )__           |
                 '------------(_,  \ ) ,_)----------'
Control Center                  '-'--`--'
                                   |       Mobile Stations
                                   |       .--------.
                                   `-------+        |-.
                                           | ClientN| |
                                           '--------' |
                                             '--------'

Client1 represents a mobile station, running the OpenVPN client who wants to reach HostA and HostB in the control center. Server is the gateway to the control center as well as the device where the OpenVPN server is running.

The example assumes that certificates and CA-certificates have already been imported to the client and server respectively.

Server Tunnel Setup

On the server device, begin by setting up the basic tunnel.

server:/#> configure
server:/config/#> tunnel ssl 0
server:/config/tunnel/ssl-0/#> server
server:/config/tunnel/ssl-0/#> method cert
server:/config/tunnel/ssl-0/#> certificate server1
server:/config/tunnel/ssl-0/#> ca-certificate server1
server:/config/tunnel/ssl-0/#> type tun
server:/config/tunnel/ssl-0/#> pool start 10.0.3.100 num 100 netmask 255.255.255.0
server:/config/tunnel/ssl-0/#> leave
server:/#>

A few comments on the above sequence:

  • The certificate and CA-certificate both have the label server1 but they are two different certificates. When importing a PKCS-bundle into WeOS, all included certificates and keys are assigned the same label. WeOS makes sure the correct certificate is used.

  • The tunnel type is set to tun as we have no use for link layer (Ethernet) signalling in this scenario.

  • The pool setting enables dynamic IP address assignment of connecting clients from the specified range. The tunnel is now ready and waiting for connections.

Ensure that the tunnel ssl0 is listed as UP using:

server:/#> show tunnel ssl
TUNNEL   DESCRIPTION     STATUS   UPTIME
0        ssl0            UP       0 Days 0 Hours 0 Mins 7 Secs

Next, assign an IP address to the local tunnel interface.

server:/#> configure
server:/config/#> iface ssl0
server:/config/iface-ssl0/#> inet static 10.0.3.1/24
server:/config/iface-ssl0/inet-static-10.0.3.1/#> end
server:/config/iface-ssl0/#> no inet ssl
server:/config/iface-ssl0/#> leave
server:/#>

Verify that the interface named ssl0 is UP and has the IP address/netmask which was just configured:

server:/#> show iface
INTERFACE         OPER  ADDRESS/LENGTH      SOURCE      MAC/PTP ADDRESS
lo                UP    127.0.0.1/8         static      00:00:00:00:00:00
ssl0              UP    10.0.3.1/24         static      N/A
vlan1             UP    10.0.1.1/24         static      00:07:7c:1c:cf:a0
                        169.254.71.83/16    link-local
vlan2             UP    10.0.2.1/24         static      00:07:7c:1c:cf:a0
vlan3             UP    198.18.19.20/24     static      00:07:7c:1c:cf:a0
server:/#>

Client Tunnel Setup

On the client device, begin by setting up the basic tunnel.

client1:/#> configure
client1:/config/#> tunnel ssl 0
client1:/config/iface-ssl0/#> no server
client1:/config/iface-ssl0/#> method cert
client1:/config/iface-ssl0/#> certificate client1
client1:/config/iface-ssl0/#> ca-certificate client1
client1:/config/iface-ssl0/#> type tun
client1:/config/iface-ssl0/#> peer 198.18.19.20
client1:/config/iface-ssl0/#> leave
client1:/#>

The client config is similar to that of the server. The main differences are:

  • The no server command is used inform WeOS that this is a client.
  • Different certificates are used for client (as compared to the server).
  • A peer command identifies the public IP address of the server.

This should be enough to make the tunnel come up (it might take a few seconds). Run:

client1:/#> show tunnel ssl
TUNNEL   DESCRIPTION     STATUS   UPTIME
0        ssl0            UP       0 Days 0 Hours 0 Mins 46 Secs
client1:/#> show iface
client1:/#> show iface
INTERFACE         OPER  ADDRESS/LENGTH      SOURCE      MAC/PTP ADDRESS
lo                UP    127.0.0.1/8         static      00:00:00:00:00:00
ssl0              UP    10.0.3.100/24       ssl0        N/A
vlan1             UP    198.18.19.55/24     static      00:07:7c:6e:3e:c0
client1:/#>

And verify that tunnel ssl0 is UP and the corresponding interface has received an IP address from the pool configured on the server.

It should now be possible to ping the server across the tunnnel:

client1:/#> ping count 3 10.0.3.1
Press Ctrl-C to abort PING 10.0.3.1 (10.0.3.1): 56 data bytes
64 bytes from 10.0.3.1: seq=0 ttl=64 time=1.124 ms
64 bytes from 10.0.3.1: seq=1 ttl=64 time=1.014 ms
64 bytes from 10.0.3.1: seq=2 ttl=64 time=0.888 ms

--- 10.0.3.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.888/1.008/1.124 ms
client1:/#>

Server Hardening

With the tunnel operational we can now “harden” it with additional authentication.

On the server device, start by defining a username and password to be used for client identification.

server:/#> configure
server:/config/#> aaa
server:/config/aaa/#> local-db 1
server:/config/aaa/local-db-1/#> username client1 password qwerty
server:/config/aaa/local-db-1/#> leave
server:/#>

This sets up username client1 and associates it with the password qwerty. In this case the credentials are stored on the local device but other options are available. See WeOS AAA for details.

Now add a user authentication method to the tunnel configuration.

server:/#> configure
server:/config/#> tunnel ssl 0
server:/config/tunnel/ssl-0/#> aaa-method local-db 1
server:/config/tunnel/ssl-0/#> leave
server:/#>

This configuration change causes the OpenVPN server to restart. The client eventually detects that it has lost connection (it might take up to a minute) and try to re-connect, but will not be allowed to do so as it is not yet configured with the correct user credentials.

Client Hardening

On the client device, check tunnel status.

client1:/#> show tunnel ssl
TUNNEL   DESCRIPTION     STATUS   UPTIME
0        ssl0            Down

The ssl0 tunnel should be DOWN. If it is still up, it means the broken connection due to the server restart has not been detected yet. (See the keepalive option for more details on this mechanism.)

Now add the username and password to the tunnel configuration:

client1:/#> configure
client1:/config/#> tunnel ssl 0
client1:/config/tunnel/ssl-0/#> identity client1 password qwerty
client1:/config/tunnel/ssl-0/#> leave
client1:/#>

This change causes another restart of the tunnel. Follow steps from part 1 to verify that the tunnel is UP and that pinging the other end works.

Server Push Routes

The final part is to configure the server to automatically push routes to the internal networks that the client needs to access. This simplifies client administration as the needed routes are created automatically on the client.

server:/#> configure
server:/config/#> tunnel ssl 0
server:/config/tunnel/ssl-0/#> push-network 10.0.1.0/24
server:/config/tunnel/ssl-0/#> push-network 10.0.2.0/24
server:/config/tunnel/ssl-0/#> leave
server:/#>

The OpenVPN server restarts again, dropping all connections.

Client Push Routes

The OpenVPN client eventually detects the connection loss and restarts the tunnel once more. If you want to speed up the process, you can manually force a tunnel restart by executing:

client1:/#> tunnel ssl restart

Note

If you have multiple tunnels, this restarts all of them.

Wait a few seconds for the tunnel to be re-established. Then check the routing table:

client1:/#> show ip route
S - Static | C - Connected | K - Kernel route  | > - Selected route
O - OSPF   | R - RIP       | [Distance/Metric] | * - FIB route

s>* 10.0.1.0/24 [1/0] via 10.0.3.1, ssl0, weight 1, 00:00:18
s>* 10.0.2.0/24 [1/0] via 10.0.3.1, ssl0, weight 1, 00:00:18
C>* 10.0.3.0/24 is directly connected, ssl0, 00:00:18
C>* 198.18.19.0/24 is directly connected, vlan1, 00:31:23
client1:/#>

There should be routes to the 10.0.1.0 and 10.0.2.0 networks with the tunnel interface as gateway. With the routes in place it should be possible to ping HostA and HostB on the control center internal network (example for HostA below):

client1:/#> ping count 3 10.0.1.2
Press Ctrl-C to abort PING 10.0.1.2 (10.0.1.2): 56 data bytes
64 bytes from 10.0.1.2: seq=0 ttl=63 time=1.552 ms
64 bytes from 10.0.1.2: seq=1 ttl=63 time=1.416 ms
64 bytes from 10.0.1.2: seq=2 ttl=63 time=1.643 ms

--- 10.0.1.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.416/1.537/1.643 ms

Note

If you are trying this example in a real network, you must configure Host A and B to reach the 10.0.3.0 network (for example by assigning the server as their default gateway), otherwise they will not be able to respond to the ping.