This wiki article is undergoing a major re-write and may be a bit messy for a while. The old version of this page will always be at: http://wiki.openwrt.org/doc/howto/vpn.server.openvpn.tun?rev=1401488265
This is a guide to setting up OpenVPN on an OpenWrt-based router with OpenVPN clients that are also based upon OpenWrt (although the client could easily be running on another OS, such as Windows, or *nix).
What follows has been tested on trunk (currently BB, b39757), but will likely work on the latest stable branch (currently AA, b39408). It is based upon OpenVPN v2.3, but will likely work with v2.2.
|For beginners, vpn.openvpn is probably a better place to start.|
Configuration example of multirouter setup
This is a review of the (OpenWrt-based) OpenVPN configuration used in vpn.openvpn, and specifically based upon Scenario 1 (client and server in different subnets).
You can review the network configuration by executing the following commands:
uci show network | grep vpn uci show firewall | grep zone uci show firewall | grep rule
Alternatively, some like to use (NB: there are important differences between these commands, and those used above):
cat /etc/config/network cat /etc/config/firewall
The OpenWrt-based OpenVPN client was configured similarly to the server, but it does not have the rule called Allow-OpenVPN-Inbound.
You can review the tunnel configuration by executing the following command(s):
uci show openvpn
Alternatively, some like to use (NB: there is an important difference between these commands, and those used above):
Another useful option, if the tunnel is running (i.e. it is enabled, and…):
Use-case 1 is based upon use-case 0 (the 'beginner's configuration'), with some changes for optimizations/best practice. Ensure you have use-case 0 configured correctly before you make these changes.
This server configuration change will 'break' the tunnel until you make the corresponding change (specifically comp-lzo) to the client configuration.
uci set openvpn.myvpn.persist_tun=1 uci set openvpn.myvpn.persist_key=1 uci set openvpn.myvpn.ifconfig_pool_persist=/tmp/openvpn-ipp.txt uci set openvpn.myvpn.fast_io=on uci set openvpn.myvpn.comp_lzo=adaptive ## this is definitely 'adaptive', and not 'no' uci set openvpn.myvpn.push='comp_lzo adaptive' uci commit; /etc/init.d/openvpn reload
uci set openvpn.myvpn.persist_tun=1 uci set openvpn.myvpn.persist_key=1 uci set openvpn.myvpn.fast_io=on uci set openvpn.myvpn.comp_lzo=no ## this is definitely 'no', and not 'adaptive' uci commit; /etc/init.d/openvpn reload
In this case, the server will push an instruction to the client, comp-lzo adaptive, that will overrule the client configuration, comp-lzo no.
If you execute uci show openvpn on the OpenVPN server, you should see:
openvpn.myvpn=openvpn openvpn.myvpn.enabled=1 openvpn.myvpn.dev=tun openvpn.myvpn.proto=udp openvpn.myvpn.server='10.8.0.0 255.255.255.0' openvpn.myvpn.port=1194 openvpn.myvpn.ca=/etc/openvpn/ca.crt openvpn.myvpn.cert=/etc/openvpn/my-server.crt openvpn.myvpn.key=/etc/openvpn/my-server.key openvpn.myvpn.dh=/etc/openvpn/dh2048.pem openvpn.myvpn.log=/tmp/openvpn.log openvpn.myvpn.verb=3 openvpn.myvpn.keepalive='10 120' openvpn.myvpn.persist_tun=1 openvpn.myvpn.persist_key=1 openvpn.myvpn.ifconfig_pool_persist=/tmp/openvpn-vpn0-ipp.txt openvpn.myvpn.fast_io=on openvpn.myvpn.comp_lzo=adaptive openvpn.myvpn.push='comp_lzo adaptive'
Alternatively, if you execute cat /etc/config/openvpn on the OpenWrt-based OpenVPN client, you should see:
config option 'myvpn' option enabled '1' option client '1' option dev 'tun' option proto 'udp' option remote='VPN_SERVER_ID 1194' option ca '/etc/openvpn/ca.crt option cert '/etc/openvpn/my-server.crt option key '/etc/openvpn/my-server.key option remote_cert_tls 'server' option log '/tmp/openvpn.log option verb '3' option persist_tun '1' option persist_key '1' option fast_io 'on' option comp_lzo 'no'
Use-case 2 is based upon use-case 1, but with some changes to the client configuration. Ensure you have use-case 1 configured correctly before you make these changes.
uci add_list openvpn.myvpn.push='redirect-gateway def1' uci commit openvpn; /etc/init.d/openvpn reload
This change …
Use-case 3 is based upon use-case 2, but with some changes to the configuration of the OpenVPN client. Ensure you have use-case 2 configured correctly before you make these changes.
This use-case requires that the node in the satellite network use the OpenVPN client as their default gateway.
uci add firewall zone uci set firewall.@zone[X].masq=1 uci set firewall.@zone[X].mtu_fix=1 uci commit openvpn; /etc/init.d/openvpn reload
This change enables NAT on the client's VPN interface, so that from the server's point of view, nothing has changed.
This is useful if you can SSH through a firewall that you can't negotiate an OpenVPN tunnel through.
However, if you use socks_proxy='localhost 1080', then it wont work by default.
For a work-around, see: https://forum.openwrt.org/viewtopic.php?pid=235158#p235158
What follows is the remnants of the old wiki…
If you are already familiar with OpenVPN and know how you want to use and configure it, feel free to skip the introduction. OpenVPN provides a leading Virtual Private Network solution. There are many possible configurations of OpenVPN, and this can be confusing. We will only briefly cover the most important aspects here, for comprehensive documentation please consult the projects homepage.
For routers running OpenWrt performance is often a scarce resource. This has some important implications for running OpenVPN. The most important factor is the CPU of the router, which will need to do encryption of all traffic. You will find indicators of what to expect here, basically the Atheros 680MHz CPU found in many routers is reported to give 20-25Mb/s throughput. Moreover, OpenVPN optionally provides compression of network traffic, which boosts your network bandwidth, but puts and even heavier toll on your CPU. Hence, consider whether you want to use a node in your network as OpenVPN server rather than the router. One obvious reason you may want to install OpenVPN on the router is that the router is typically always on, and hence provides excellent availability.
We will cover two common ways of configuring OpenVPN here. The main difference between the two is that the first is easier to set-up but only provides one client and one server. The second is a bit more involved to set-up, but provides full flexiblity with respect to number of servers and clients you want to connect.
The easiest way to configure OpenVPN is using static keys. The main draw-back is that it only provides single server and single client configuration. First thing you need to do is create the static key, which is done by:
cd /etc/openvpn openvpn --genkey --secret static.keyCopy the key to your client over a secure channel. Now configure openvpn by editing /etc/config/openvpn to look like this:
option 'dev' 'tun' option 'secret' '/etc/openvpn/static.key' option 'ifconfig' '192.168.2.1 192.168.2.2'This is assuming that you want your server IP address to be 192.168.2.1, and you client IP address to be 192.168.2.2.
If your client is a linux-box, simply install openvpn from your package system and set your openvpn configuration file to:
remote myremote.mydomain dev tun ifconfig 192.168.2.2 192.168.2.1 secret static.keywhere you replace myremote.mydomain with the domain name or external IP address of your OpenVPN server. If your client is an OpenWrt server, simply adjust the configuration to the
If you want your client to reach the entire subnet on you server, and your server subnet is 192.168.1.1/24, then add the following line to the client configuration:
route 192.168.1.0 255.255.255.0
if you want to reach more than one route through your server use:
list 'route' '192.168.1.0 255.255.255.0' list 'route' '192.168.2.0 255.255.255.0'
First we need to install the package for creating keys and certificates:
opkg install openvpn-easy-rsaEdit the /etc/easy-rsa/vars file and modify the default location area
cd /etc/easy-rsa vi varsat bottom, change to suit your location at will, but make sure none of them are empty:
export KEY_COUNTRY="US" export KEY_PROVINCE="TX" export KEY_CITY="Houston" export KEY_ORG="My Cool Place" export KEY_EMAIL="firstname.lastname@example.org" export KEY_OU="myorganisation"Now we need to source in the variables you just set:
source varsWe will need to generate keys and certificates for server and clients. Prime your cert database:
clean-all build-ca build-dhCreate the server key
build-key-server serverCreate as many client keys for each person who will connect.
build-key Jimmy build-key Sara build-key Soandso ...For PKCS12 Format (combines the key and ca certificate in one file), then instead do:
build-key-pkcs12 Jimmy build-key-pkcs12 Sara build-key-pkcs12 Soandso ...Copy the important files to the /etc/openvpn directory, so that they are duplicated
cd /etc/easy-rsa/keys cp ca.crt ca.key dh1024.pem server.crt server.key /etc/openvpn/
Finally, edit /etc/config/openvpn to fit your need.
vi /etc/config/openvpnThe following is an example. There are multiple examples included in the configuration file.
option 'port' '1194' option 'proto' 'udp' option 'dev' 'tun' option 'ca' '/etc/openvpn/ca.crt' option 'cert' '/etc/openvpn/server.crt' option 'key' '/etc/openvpn/server.key' option 'dh' '/etc/openvpn/dh.pem' option 'tls_auth' '/etc/openvpn/shared.key 0' option 'server' '10.8.0.0 255.255.255.0' list 'push' 'route 192.168.1.0 255.255.255.0' list 'push' 'redirect-gateway' option 'keepalive' '10 120' option 'status' '/tmp/openvpn.status'
Since OpenVPN 2.3.x, OpenVPN can be used to provision IPv6 traffic through a TUN tunnel. This is useful to access IPv6 resources from a remote IPv4 network. All one needs to do is provision IPv6 through the tunnel and enable forwarding. First, to provision IPv6, suppose your IPv6 subnet is 2001:aa:bb:cc::/64 and the LAN interface on the OpenWrt router has the IPv6 address 2001:aa:bb:cc::1/64. To provision IPv6:
Do not use the /64 IPv6 subnet deployed on your LAN. Use an additional /64 subnet split off from a larger prefix delegation (e.g., a /56 or /60).
uci set openvpn.myvpn.server_ipv6='2001:aa:bb:cc::/64' ## set the subnet that VPN clients will receive uci add_list openvpn.myvpn.push='route-ipv6 2001:aa:bb:cc::/64' ## advertise the IPv6 route uci add_list openvpn.myvpn.push='route-ipv6 2000::/3' ## route all Internet IPv6 traffic via the VPN uci commit openvpn ## save changes /etc/init.d/openvpn restart ## restart the OpenVPN daemon
Provisioning a subnet other than /64 is possible, but is more complicated. See the OpenVPN wiki for more details. The last step is to enable IPv6 forwarding to the Internet. To allow it, edit /etc/config/firewall:
config forwarding option src 'vpn' option dest 'wan' option family 'ipv6'
After editing the firewall changes, enable them by executing:
There is a bug in the /etc/init.d/openvpn. the push directives to openvpn should be encapsulated with double quotes ("), but the init script uses single quotes ('). If you want the push directives to work with openvpn you should modify the init script lines 103 and 107 to look like. There is a ticket about this ( https://dev.openwrt.org/ticket/10518 ).