Setup 4096-bit OpenVPN on OpenWRT
If you want to setup OpenVPN with 4096-bit key on OpenWRT, with a few tips and tricks in addition, read on.
Reasons for setting up VPN
- To access your home network via a secure tunnel from outside.
- To avoid port forwardings which opens up a direct pipe to your home devices, a potential security hole.
- To deny others from eavesdropping on your Internet traffic when using public Wi-Fi.
- To browse the Internet as if you are in your home country when you are abroad. This is useful in circumventing geo-blocking.
OpenVPN is probably the best open source implementation of VPN at this time. It is offered by all public VPN providers that I know of but encryption strength varies.
Prior to using OpenVPN on OpenWRT, I was using OpenVPN on Network-attached Storage. I stopped using after realising that they use 1024-bit key. Then I setup OpenVPN on OpenWRT which as at time of writing this blog post defaults to 2048-bit key. While this is sufficient for today’s needs, an attacker could potentially capture the encrypted data today to be decrypted using much better hardware in future.
Installing OpenVPN on OpenWRT
openvpn-openssl. If you use OpenWRT GUI, install
luci-app-openvpn as well. Ensure that your router has sufficient free space for these packages! I am unsure how much is required but very sure that routers with 4MB flash memory is insufficient.
Increasing key size from 2048 to 4096 bit
/etc/easy-rsa/vars using your preferred editor. If you are not sure how to edit, I recommend installing
nano then edit the file by typing
You should set the following fields so that you do not have to enter them for each key creation.
export KEY_COUNTRY="[2-letter country code]" export KEY_PROVINCE="[whatever]" export KEY_CITY="[whatever]" export KEY_ORG="[whatever]" export KEY_EMAIL="[whatever]" export KEY_OU="[whatever]" export KEY_NAME="[keyname]"
For all steps below, when prompted to enter password for keys, leave them blank.
To delete everything in
/etc/easy-rsa/keys folder, run
clean-all. Be warned that this removes all existing keys! Use it only for starting afresh.
Generate Certificate Authority key
Create Certificate Authority (CA) key by running
build-ca. This step produces
ca.key. The former (certificate) is to be distributed to every client while the latter (key) must not be given out to anyone. If the key is compromised, you must recreate all keys beginning with
clean-all step in previous paragraph.
Generate Diffie Hellman key
Create Diffie Hellman (DH) key by running
build-dh. Note that this takes hours if not days on a typical router! If you want this step to complete significantly faster, install OpenSSL onto your workstation and execute:
openssl dhparam 4096 -out dh4096.pem Be patient. A modern hardware may still require more than an hour to complete this step. The output is a file
dh4096.pem. Copy this into
Generate server key
This creates a server key called ‘server’.
Generate client keys
For each client, create a key with unique name. Besides this, do not create client keys with the same name as server key.
This generates the following files: * clientname.crt * clientname.key * clientname.p12
While not required, enabling Transport Layer Security (TLS) authentication is strongly recommended. Generate TLS key by running:
openvpn --genkey --secret /etc/easy-rsa/keys/ta.key
This key is a shared secret. Therefore, must be copied to every client. If the server is set to
ta.key 0, the client must be set to
ta.key 1 or vice versa.
Copy all keys to openvpn folder
cd /etc/easy-rsa/keys cp ca.crt ca.key dh4096.pem server.crt server.key ta.key /etc/openvpn
For subsequent configuration steps, point to
/etc/openvpn for keys.
/etc/config/openvpn. Add and edit where relevant the following:
# OpenVPN instance name must be unique config openvpn 'myvpn' option enabled '1' option mode 'server' option tls_server '1' # Virtual network adapter name, must be unique option dev 'tun-local' # The default port number is 1194 option port '1194' option proto 'udp' option status '/var/log/openvpn_status.log' option log '/tmp/openvpn.log' option mute '5' option persist_key '1' option persist_tun '1' option ca '/etc/openvpn/ca.crt' option cert '/etc/openvpn/server.crt' option key '/etc/openvpn/server.key' option dh '/etc/openvpn/dh4096.pem' # Instead of using the default Blowfish algorithm option cipher 'AES-256-CBC' # Set ta.key 0 for server and ta.key 1 on client or vice versa option tls_auth '/etc/openvpn/ta.key 0' option route_gateway 'dhcp' # Allows a VPN client to talk to another option client_to_client '1' # IMHO, compression should be decided at application layer option comp_lzo 'no' # Use a subnet where no other instance of OpenVPN is using option server '10.8.1.0 255.255.255.0' option verb '0' option float '1' option keepalive '10 120' # Do not comment this line list push 'comp-lzo no' # Redirects all client traffic to go through VPN list push 'redirect-gateway def1' # Tell client to use router's DNS forwarder, change this accordingly # You must configure firewall to allow this to flow through # Otherwise use Google DNS 220.127.116.11 list push 'dhcp-option DNS 192.168.0.1'
/etc/config/network and add the following. Note that
tun-local must be replaced with whatever you have specified under
option dev in previous step:
config interface 'vpn' option proto 'none' option auto '1' option ifname 'tun-local'
Next, setup firewall by editing
/etc/config/firewall. Create a firewall zone for the VPN:
config zone option name 'vpn' option input 'ACCEPT' option forward 'ACCEPT' option output 'ACCEPT' option masq '1' option network 'vpn'
Forward traffic from VPN to WAN:
config forwarding option dest 'wan' option src 'vpn'
Forward traffic from VPN to LAN:
config forwarding option dest 'lan' option src 'vpn'
Allow incoming connections via UDP port 1194:
config rule option name 'Allow-OpenVPN-Inbound' option target 'ACCEPT' option proto 'udp' option dest_port '1194' option src 'wan' option family 'ipv4'
dev tun # Protocol to use proto udp # Certificates ca ca.crt cert clientname.crt key clientname.key script-security 3 float cipher AES-256-CBC tls-auth ta.key 1 client remote-cert-tls server # Try the first, if fail try the second automatically # Replace server-hostname with your hostname remote server-hostname 1194 remote server-hostname 53
Copy the OVPN file along with the following files to the client:
Import the OVPN file using your preferred OpenVPN client. The client should automatically recognise the other four files. If not, explicitly point to them.
Read on if you are facing issues. One of the solutions might be helpful to you.
Able to establish connection over mobile network but not from public Wi-Fi
The firewall at the public Wi-Fi network is probably blocking outgoing connections on UDP port 1194. Try using a different port instead of the default 1194. Alternatively, you could support multiple ports by adding an iptable rule per extra port. Below is an example of redirecting incoming UDP port 53 to 1194. UDP 53 is for DNS, very unlikely to be blocked:
# Redirect UDP 53 to UDP 1194 OpenVPN iptables -t nat -A PREROUTING -p udp -i pppoe-wan --dport 53 -j REDIRECT --to-port 1194
If this does not work for you, try using TCP port 443 by changing the following lines in
option port '443' option proto 'tcp'
Unable to connect to remote LAN machines via VPN
Firstly, avoid using very common subnets such as
192.168.1.x. If the source (where you are connecting to VPN from) and destination (where the VPN server is running) are on the same subnet, the destination cannot be reached. The server could push a route of that subnet explicitly overriding the client’s route. In doing so however, it prevents connecting to the source LAN when client is connected to VPN. In short, stay away from very common subnets.
Unable to ping any machine via VPN
I was having no problems connecting to VPN from my Android device but I was not able to connect from a Lubuntu notebook. After trying various settings, the setting that fixed the problem was turning on
comp-lzo on the Lubuntu notebook. This is despite the server having set the comp-lzo to ‘no’ explicitly and pushing that option to client too.