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.