User Tools

Site Tools


doc:howto:vpn.openvpn

OpenVPN Setup Guide for Beginners

This is a beginner's guide to setting up OpenVPN on a server and a client where, in this instance, both are running OpenWrt (although the OpenVPN client could easily be running on another OS, such as Windows or Linux).

For non-beginners or real-world tunnels, vpn.server.openvpn.tun may be a better place to start.

The primary goal of this HOWTO is to get a working OpenVPN tunnel; the strategy used by this HOWTO is to keep it simple. Because of that, this is a very basic OpenVPN tunnel configuration that will not suit most people's needs without further configuration. However, once the basic tunnel is working, additional recipes for other use-cases can be found at vpn.server.openvpn.tun.

For an overview of all VPN-related articles (including other VPN technologies), see vpn.overview.

Use Case (the beginner's configuration)

The user wants a client to access their OpenWrt router without the possibility of being snooped. That is, the user can already access the router, but over a public network, such as the Internet.

The end result will be a private connection directly between the OpenVPN client and server. Mostly, it is as if the two end-points are on the same subnet (but not on the same subnet as your router's LAN).

To facilitate configuration/testing, this HOWTO permits two distinct scenarios for this use-case:

  • Scenario 0: the OpenVPN client can ping the OpenWrt router via the router's LAN interface. Specifically, they are on the same subnet (e.g. the client is a DHCP client of the OpenWrt router).
  • Scenario 1: the OpenVPN client can ping the OpenWrt router via the router's WAN interface. Specifically, they are not on the same subnet (e.g. they are separated by the Internet).

Scenario 0 takes out much of the complexity of real-world configurations, such as the vagaries of the Internet, or your OpenWrt firewall configuration. Scenario 0 allows you to easily implement an OpenVPN tunnel, which can then be switched to Scenario 1, which itself is the basis for most real-world OpenVPN configurations. You can either start with Scenario 0, and switch to Scenario 1 when you've got it working, or start directly with Scenario 1 and switch back to Scenario 0 for troubleshooting.

Prerequisites

This HOWTO requires that the OpenVPN server is an OpenWrt router running OpenWrt 14.07 Barrier Breaker.

Install the required software

opkg update
opkg install openvpn-openssl openvpn-easy-rsa

Create the certificates

build-ca
build-dh
build-key-server my-server
build-key-pkcs12 my-client

The above creates a server certificate named my-server and a client certificate named my-client. You can create multiple client certificates by running build-key-pkcs12 multiple times and specifying different names.

You can create a new set of certificates by running clean-all and then the above commands again.ls

Distribute the certificates

cp /etc/easy-rsa/keys/ca.crt /etc/easy-rsa/keys/my-server.* /etc/easy-rsa/keys/dh1024.pem /etc/openvpn
scp /etc/easy-rsa/keys/ca.crt /etc/easy-rsa/keys/my-client.* root@CLIENT_IP_ADDRESS:/etc/openvpn

The above assumes that you can connect to the client from the server, that the client has a SSH server and that you can login as root. If you can't, transfer the client certificate some other way, such as using an USB stick.

Configure the network on the OpenWrt server

  1. Create the VPN interface:
    uci set network.vpn0=interface
    uci set network.vpn0.ifname=tun0
    uci set network.vpn0.proto=none
    uci set network.vpn0.auto=1
  2. Allow inbound VPN traffic:
    uci add firewall rule
    uci set firewall.@rule[-1].name=Allow-OpenVPN-Inbound
    uci set firewall.@rule[-1].target=ACCEPT
    uci set firewall.@rule[-1].src=*
    uci set firewall.@rule[-1].proto=udp
    uci set firewall.@rule[-1].dest_port=1194
  3. Allow OpenVPN tunnel utilization:
    uci add firewall zone
    uci set firewall.@zone[-1].name=vpn
    uci set firewall.@zone[-1].input=ACCEPT
    uci set firewall.@zone[-1].forward=ACCEPT
    uci set firewall.@zone[-1].output=ACCEPT
    uci set firewall.@zone[-1].network=vpn0
    uci add firewall forwarding
    uci set firewall.@forwarding[-1].src='vpn'
    uci set firewall.@forwarding[-1].dest='wan'
  4. Commit the changes:
    uci commit network
    /etc/init.d/network reload
    uci commit firewall
    /etc/init.d/firewall reload

Configure the network on the OpenWrt client

Do the same as on the OpenWrt server above except skip step 2.

Configure the OpenVPN server

echo > /etc/config/openvpn
uci set openvpn.myvpn=openvpn
uci set openvpn.myvpn.enabled=1
uci set openvpn.myvpn.dev=tun
uci set openvpn.myvpn.port=1194
uci set openvpn.myvpn.proto=udp
uci set openvpn.myvpn.log=/tmp/openvpn.log
uci set openvpn.myvpn.verb=3
uci set openvpn.myvpn.ca=/etc/openvpn/ca.crt
uci set openvpn.myvpn.cert=/etc/openvpn/my-server.crt
uci set openvpn.myvpn.key=/etc/openvpn/my-server.key
uci set openvpn.myvpn.server='10.8.0.0 255.255.255.0'
uci set openvpn.myvpn.dh=/etc/openvpn/dh1024.pem
uci commit openvpn
/etc/init.d/openvpn enable
/etc/init.d/openvpn start

Configure the OpenWrt client

echo > /etc/config/openvpn
uci set openvpn.myvpn=openvpn
uci set openvpn.myvpn.enabled=1
uci set openvpn.myvpn.dev=tun
uci set openvpn.myvpn.proto=udp
uci set openvpn.myvpn.log=/tmp/openvpn.log                
uci set openvpn.myvpn.verb=3
uci set openvpn.myvpn.ca=/etc/openvpn/ca.crt
uci set openvpn.myvpn.cert=/etc/openvpn/my-client.crt
uci set openvpn.myvpn.key=/etc/openvpn/my-client.key
uci set openvpn.myvpn.client=1
uci set openvpn.myvpn.remote_cert_tls=server
uci set openvpn.myvpn.remote="SERVER_IP_ADDRESS 1194"
uci commit openvpn
/etc/init.d/openvpn start

Configure other clients

Create the following OpenVPN client configuration file, save it with an .ovpn extension and give it to your client:

dev tun
proto udp

log openvpn.log
verb 3

ca /etc/openvpn/ca.crt
cert /etc/openvpn/my-client.crt
key /etc/openvpn/my-client.key

client
remote-cert-tls server
remote SERVER_IP_ADDRESS 1194

Test the tunnel

  1. The tunnel should have made a change to the client's route table (so you can access the tunnel end-point, should be 10.8.0.1):
      cat /tmp/openvpn.log | grep "route add"
         ...
      route
  2. You should be able to ping the tunnel end-point (i.e. the OpenVPN server):
      traceroute 10.8.0.1
  3. You should still be able to ping hosts on the Internet via your default gateway:
      traceroute 8.8.8.8
  4. You should be able to ping hosts on the Internet via the tunnel:
      route add -net 8.8.8.8 netmask 255.255.255.255 gateway 10.8.0.5
      route
         ...
      traceroute 8.8.8.8

In particular, look at hops 1 and 2 of the traceroute; hop 1 should be one of the gateways from your route table. If hop 2 of traceroute 8.8.8.8 is the IP address of VPN_SERVER_ID, then the tunnel is working.

:-D Congratulations! Now look to 'tune' the OpenVPN tunnel for a specific use-case.

Route Only Local LAN Client Traffic Through the Tunnel

If all that is needed is to allow clients access to the local subnet (e.g., to access a server at home from work), and to leave Internet access as-is, all one needs to do is advertise the local subnet and configure the firewall to allow traffic through. First, to advertise the route:

uci set openvpn.myvpn.push='route 192.168.1.0 255.255.255.0'
uci commit openvpn
/etc/init.d/openvpn restart

In this example the subnet is 192.168.1.0/24. Adjust your configuration accordingly for your LAN. Now, the firewall has to be enabled to allow traffic from the VPN clients to the local LAN. To allow it, edit /etc/config/firewall:

## NB: this zone should have already been created in the previous setup step; just add the masq option as noted below
config zone
	option name 'vpn'
	option masq '1' ## NB: this option was added to enable forwarding out of the VPN zone
	option input 'ACCEPT'
	option forward 'ACCEPT'
	option output 'ACCEPT'
	option network 'vpn0'

## NB : this section was added
config forwarding
	option src 'vpn'
	option dest 'lan'

After editing the firewall changes, enable them by executing:

/etc/init.d/firewall reload

Route All Client Traffic Through the Tunnel

If the OpenVPN server can access the Internet, then the client has the option of routing all its IP traffic via the tunnel rather than through it's local gateway. If the tunnel is merely provide access to other subnets (e.g. to access a server at home from work), but Internet access is to remain as-is, then this is not your answer. Instead, see Routing Only Local LAN Client Traffic Through the Tunnel.

Before you do this, you should know whether your network is Scenario 1 (client and server in different subnets), or Scenario 2 (client and server in the same subnet).

In Scenario 1, the client and server are in different subnets:

  1. On the OpenVPN server, execute the following
      uci set openvpn.myvpn.push='redirect-gateway def1'        ## NB: these are single quotes
      uci commit openvpn
      /etc/init.d/openvpn restart
  2. On the OpenVPN client, execute the following:
      /etc/init.d/openvpn restart
      traceroute 8.8.8.8

Alternatively, in Scenario 2, the client and server are in the same subnet (useful for creating/testing an OpenVPN tunnel at home):

  1. On the OpenVPN server, execute the following:
      uci set openvpn.myvpn.push='redirect-gateway def1 local'  ## NB: these are single quotes
      uci commit openvpn; /etc/init.d/openvpn restart
  2. On the OpenVPN client, execute the following:
      /etc/init.d/openvpn restart
      traceroute 8.8.8.8  

:!: If your OpenVPN client is not to route all it's traffic via the server (and therefore continue to use it's existing default gateway), then you should not push the redirect-gateway option at all.

You might need to make OpenWrt route traffic from vpn to wan. Add to /etc/config/firewall:

config forwarding
	option src 'vpn'
	option dest 'wan'
This worked for BB RC2 (uci commands would be better).

Once this is working, head to vpn.server.openvpn.tun for more OpenVPN 'recipes'.

Troubleshooting

If something doesn't work as expected while following this HOWTO:

  • Check that the client can ping the server:
    ping SERVER_IP_ADDRESS
  • Check that the OpenVPN daemon is running:
    ps | grep "openvpn"
  • Check that there is a TUN interface:
    ifconfig | grep "tun"
  • Check the log:
    cat /tmp/openvpn.log
  • You can try temporarily disabling the firewall on the OpenVPN server:
    /etc/init.d/firewall stop
  • You can clear the OpenVPN configuration and start again from scratch:
    echo > /etc/config/openvpn

Asking for help

You can ask for help on the OpenWrt forum: https://forum.openwrt.org/.

When asking for help, you should at a minimum include the contents of the following files:

cat /tmp/openvpn.log
cat /etc/config/network
cat /etc/config/firewall
cat /etc/config/openvpn

References and examples

doc/howto/vpn.openvpn.txt · Last modified: 2015/08/09 15:12 by wutje