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.
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 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.
This HOWTO requires that the OpenVPN server is an OpenWrt router running OpenWrt 15.05 Chaos Calmer.
opkg update opkg install openvpn-openssl openvpn-easy-rsa
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
cp /etc/easy-rsa/keys/ca.crt /etc/easy-rsa/keys/my-server.* /etc/easy-rsa/keys/dh2048.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.
uci set network.vpn0=interface uci set network.vpn0.ifname=tun0 #If you wish to use a server-bridge config, replace the tun0 with tap0 uci set network.vpn0.proto=none uci set network.vpn0.auto=1
uci set network.lan.ifname="$(uci get network.lan.ifname) tap0"
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
uci add firewall zone uci set firewall.@zone[-1].name=vpn uci set firewall.@zone[-1].input=ACCEPT uci set firewall.@zone[-1].forward=REJECT 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'
uci commit network /etc/init.d/network reload uci commit firewall /etc/init.d/firewall reload
Do the same as on the OpenWrt server above except skip step 3.
echo > /etc/config/openvpn # clear the openvpn uci config uci set openvpn.myvpn=openvpn uci set openvpn.myvpn.enabled=1 uci set openvpn.myvpn.verb=3 uci set openvpn.myvpn.port=1194 uci set openvpn.myvpn.proto=udp uci set openvpn.myvpn.dev=tun uci set openvpn.myvpn.server='10.8.0.0 255.255.255.0' 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.dh=/etc/openvpn/dh2048.pem uci set openvpn.myvpn.dh=/etc/openvpn/dh1024.pem uci commit openvpn /etc/init.d/openvpn enable /etc/init.d/openvpn start
Ensure you have changed tun0 to tap0 in the settings above.
This will create a virtual ethernet link between clients and the server, and those clients will be assigned IP addresses by the network's DHCP controller (most commonly the router that this OpenVPN server is being configured on).
Traffic by the client addressed to the local subnet of the DHCP controller (i.e. 192.168.1.XXX) will be routed by the client through the VPN and into the LAN, effectively making these clients act as local devices. PLEASE NOTE that this is a very basic setup intended for private use and is potentially insecure. Clients are being granted unrestricted access to the LAN, which represents a potential security hole if that client is malicious and/or compromised. Firewalled access is highly recommended if multiple or untrusted users are being granted access.
Traffic by the client addressed to WAN addresses (i.e. openwrt.org) will be processed normally and travel through whatever network that client is attached to rather than the VPN. This traffic can be directed through the VPN if desired by adding the appropriate routes (outside the scope of this tutorial).
It is highly recommended that you change your DHCP subnet to something other than 192.168.0.XXX or 192.168.1.XXX. These are very common and will cause routing conflicts and connectivity issues if you attempt to connect from a client attached to a router utilizing the same subnet. This can generally be done by changing the IP address of the OpenWRT/OpenVPN router to something like 192.168.7.1
echo > /etc/config/openvpn # clear the openvpn uci config uci set openvpn.myvpn=openvpn uci set openvpn.myvpn.enabled=1 uci set openvpn.myvpn.verb=3 uci set openvpn.myvpn.proto=udp uci set openvpn.myvpn.port=1194 uci set openvpn.myvpn.dev=tap0 uci set openvpn.myvpn.mode=server uci set openvpn.myvpn.tls_server=1 uci set openvpn.myvpn.push='route-gateway dhcp' uci set openvpn.myvpn.keepalive='10 120' 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.dh=/etc/openvpn/dh2048.pem uci commit openvpn /etc/init.d/openvpn enable /etc/init.d/openvpn start
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.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
Or alternatively drop an openvpn configuration file into /etc/openvpn/<vpnName>.conf. You can test it in a shell with
Create the following OpenVPN client configuration file, save it with an
.ovpn extension in the Windows or
.conf in the *nix 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
Create the following OpenVPN client configuration file, save it with an
.ovpn extension and give it to your client:
dev tap 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
cat /tmp/openvpn.log | grep "route add" ... route
route add -net 188.8.131.52 netmask 255.255.255.255 gateway 10.8.0.5 route ... traceroute 184.108.40.206
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 220.127.116.11 is the IP address of VPN_SERVER_ID, then the tunnel is working.
Congratulations! Now look to 'tune' the OpenVPN tunnel for a specific use-case.
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:
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:
uci set openvpn.myvpn.push='redirect-gateway def1' ## NB: these are single quotes uci commit openvpn /etc/init.d/openvpn restart
/etc/init.d/openvpn restart traceroute 18.104.22.168
Alternatively, in Scenario 2, the client and server are in the same subnet (useful for creating/testing an OpenVPN tunnel at home):
uci set openvpn.myvpn.push='redirect-gateway def1 local' ## NB: these are single quotes uci commit openvpn; /etc/init.d/openvpn restart
/etc/init.d/openvpn restart traceroute 22.214.171.124
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).
Another way to accomplish routing all client traffic through the tunnel via LUCI is to navigate to Network → Firewall and make the options look like this:
LAN: (lan: images) => VPN : accept accept accept (just changing this one to point to VPN instead of WAN) WAN: (wan: images) => REJECT : reject accept reject (no changes here) VPN: (vpn: image) => WAN : accept accept accept (change forwarding to accept, check masquerading option)
Once this is working, head to vpn.server.openvpn.tun for more OpenVPN 'recipes'.
If something doesn't work as expected while following this HOWTO:
ps | grep "openvpn"
ifconfig | grep "tun"
echo > /etc/config/openvpn
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
When using UCI, you need to define the client config dir differently. All OpenVPN manuals tell you write it out as client-config-dir (with dashes), but for UCI you need to call it client_config_dir (with underscores). If unsure, check the openvpn conf file that is generated in /var/etc/, as that will have client-config-dir (with dashes) when all went well.
You may create text config file, for example /etc/openvpn/server, /etc/openvpn/client and next include it in the openvpn instance in the /etc/config/openvpn:
uci set openvpn.myvpnserver.config=/etc/openvpn/myvpnserver.confYou may use included file and other tokens simultaneous, for example:
uci set openvpn.myvpnserverudp.config=/etc/openvpn/common.conf uci set openvpn.myvpnserverudp.proto=udp uci set openvpn.myvpnservertcp.config=/etc/openvpn/common.conf uci set openvpn.myvpnservertcp.proto=tcp
|: Integrate any useful information from vpn.howto.|