User Tools

Site Tools


docs:guide-user:services:vpn:openvpn:server.setup

OpenVPN (Server Setup)

Degree of difficulty: Intermediate. This guide assumes you can:

The OpenVPN server running on your router can provide a secure connection back to your home network while you're away. If you need to access the router itself or any of your home network devices from afar, the OpenVPN server is a great and secure solution. This article provides a concise and correct procedure for setting up an OpenVPN server on your router.

You will need to perform these steps:

  • Install OpenVPN and other required packages to your router.
  • Generate certificates necessary for both OpenVPN Server running on your router and the OpenVPN Client running on the (remote) client device you will be connecting from.
  • Edit configuration files on your router to enable OpenVPN Server.
  • Generate an .ovpn file for client devices.
  • Copy an .ovpn file from your router to your clients.

This procedure has been tested on LEDE 17.01.4. It should work with earlier LEDE and OpenWrt versions.

Prerequisites

Install OpenVPN and Other Packages

Install the following packages either from Web UI or SSH into your router and run:

opkg update && opkg install openvpn-openssl openssl-util luci-app-openvpn

Generate Certificates

The OpenVPN Server (running on your router) and your OpenVPN Client device (running remotely) need certificates to secure the communication. This procedure covers generating the certificates on the router itself. Be aware that this process might take a long time - 20 minutes or even many hours on older routers.

Copy-paste the following commands into your router via the SSH session:

  • PLEASE NOTE:
    • Preferred way to garnish scripts is to utilize wget:
      cd /tmp && wget https://openwrt.org/_export/code/docs/guide-user/services/vpn/openvpn/server.setup?codeblock=3
       
      mv server.setup?codeblock=3 create-certs.sh && chmod 754 ./create-certs.sh && ./create-certs.sh

Additional Info

If Downloading via Windows

create-certs.sh
#!/bin/sh
 
printf "\n\n  # Creating Directory Structure #\n\n"
printf %b "------------------------------------------------------------\n"
 
  PKI_DIR="/etc/openvpn/ssl"
 
    [ -d ${PKI_DIR} ] && rm -rf ${PKI_DIR}
      mkdir -p ${PKI_DIR} && chmod -R 0600 ${PKI_DIR}
      cd ${PKI_DIR}
 
    touch index.txt && touch index && echo 1000 > serial
    cp /etc/ssl/openssl.cnf ${PKI_DIR}
 
printf "\n\n  # Customizing openssl.cnf #\n\n"
printf %b "------------------------------------------------------------\n\n"
 
  PKI_CNF=${PKI_DIR}/openssl.cnf
 
    sed -i 's/\\\\/\//g'				       ${PKI_CNF}
    sed -i '/^dir/   s:=.*:= /etc/openvpn/ssl:'                ${PKI_CNF}
    sed -i '/^new_certs_dir/   s:=.*:= /etc/openvpn/ssl:'      ${PKI_CNF}
    sed -i '/.*Name/ s:= match:= optional:'                    ${PKI_CNF}
    sed -i '/organizationName_default/    s:= .*:= WWW Ltd.:'  ${PKI_CNF}
    sed -i '/stateOrProvinceName_default/ s:= .*:= London:'    ${PKI_CNF}
    sed -i '/countryName_default/         s:= .*:= GB:'        ${PKI_CNF}
    sed -i '/default_days/   s:=.*:= 3650:'                    ${PKI_CNF}
    sed -i '/default_bits/   s:=.*:= 4096:'                    ${PKI_CNF}
 
    cat >> ${PKI_CNF} <<"EOF"
[ my-server ] 
  keyUsage = digitalSignature, keyEncipherment
  extendedKeyUsage = serverAuth
 
[ my-client ] 
  keyUsage = digitalSignature
  extendedKeyUsage = clientAuth
EOF
 
printf "\n\n  # Generating Server PSK and CA, Server, & Client Certs #\n\n"
printf %b "------------------------------------------------------------\n"
 
  printf "\n\n  ...Generating Certifcate Authority Cert & Key...\n"
  printf %b "------------------------------------------------------------\n\n"
    openssl req -batch -nodes -new -keyout "ca.key" -out "ca.crt" -x509 -config ${PKI_CNF} -days 3650
 
  printf "\n\n  ...Generating Server Cert & Key...\n"
  printf %b "------------------------------------------------------------\n\n"
    openssl req -batch -nodes -new -keyout "my-server.key" -out "my-server.csr" -subj "/CN=my-server" -config ${PKI_CNF}
 
  printf "\n\n  ...Signing Server Cert...\n\n"
    openssl ca  -batch -keyfile "ca.key" -cert "ca.crt" -in "my-server.csr" -out "my-server.crt" -config ${PKI_CNF} -extensions my-server
 
  printf "\n\n  ...Generating Client Cert & Key...\n"
  printf %b "------------------------------------------------------------\n\n"
    openssl req -batch -nodes -new -keyout "my-client.key" -out "my-client.csr" -subj "/CN=my-client" -config ${PKI_CNF}
 
  printf "\n\n  ...Signing Client Cert...\n"
  printf %b "------------------------------------------------------------\n\n"
    openssl ca  -batch -keyfile "ca.key" -cert "ca.crt" -in "my-client.csr" -out "my-client.crt" -config ${PKI_CNF} -extensions my-client     
 
  printf "\n\n  ...Generating OpenVPN TLS PSK...\n"
  printf %b "------------------------------------------------------------\n\n"
    openvpn --genkey --secret tls-auth.key
 
  printf "\n  ...Generating Diffie-Hellman Cert...\n"
  printf %b "------------------------------------------------------------\n\n"
    printf "    # May take a while to complete (~25m on WRT3200ACM) #\n\n\n"
    openssl dhparam -out dh2048.pem 2048
 
printf "\n\n  ...Correcting Permissions...\n"
printf %b "------------------------------------------------------------\n"
  chmod 0600 ca.key dh2048.pem my-server.key my-client.key tls-auth.key
 
printf "\n\n  # Copying Certs & Keys to /etc/openvpn/ #\n"
printf %b "------------------------------------------------------------\n"
  cp ca.crt my-server.* my-client.* dh2048.pem tls-auth.key /etc/openvpn
 
printf "\n\n  . . .  DONE  . . .  \n\n\n"

Edit Configuration Files

The script below edits the following files inside the /etc/config directory: network, firewall, openvpn.

Copy-paste the following commands into your router via the SSH session:

create-configs.sh
#!/bin/sh
 
# Modify /etc/config/network
  uci set network.vpnserver='interface'
  uci set network.vpnserver.proto='none'
  uci set network.vpnserver.ifname='ovpns0'
  uci set network.vpnserver.auto='1'
uci commit network
 
# Modify /etc/config/firewall
  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='tcpudp'
  uci set firewall.@rule[-1].dest_port='1194'
 
  uci add firewall zone
  uci set firewall.@zone[-1].name='vpnserver'
  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].masq='1'
  uci set firewall.@zone[-1].network='vpnserver'
 
  uci add firewall forwarding
  uci set firewall.@forwarding[-1].src='vpnserver'
  uci set firewall.@forwarding[-1].dest='wan'
 
  uci add firewall forwarding
  uci set firewall.@forwarding[-1].src='vpnserver'
  uci set firewall.@forwarding[-1].dest='lan'
uci commit firewall
 
# Modify /etc/config/openvpn
  uci set openvpn.vpnserver='openvpn'
  uci set openvpn.vpnserver.enabled='1'
  uci set openvpn.vpnserver.dev_type='tun'
  uci set openvpn.vpnserver.dev='ovpns0'  
  uci set openvpn.vpnserver.proto='udp'
  uci set openvpn.vpnserver.port='1194'
  uci set openvpn.vpnserver.topology='subnet'
  uci set openvpn.vpnserver.tls_server='1'
  uci set openvpn.vpnserver.mode='server'
  uci set openvpn.vpnserver.server='192.168.200.0 255.255.255.0'
  uci set openvpn.vpnserver.route_gateway='dhcp'
  uci set openvpn.vpnserver.comp_lzo='yes'
  uci set openvpn.vpnserver.keepalive='10 120'
  uci set openvpn.vpnserver.persist_key='1'
  uci set openvpn.vpnserver.persist_tun='1'
  uci set openvpn.vpnserver.ca='/etc/openvpn/ca.crt'
  uci set openvpn.vpnserver.cert='/etc/openvpn/my-server.crt'
  uci set openvpn.vpnserver.key='/etc/openvpn/my-server.key'
  uci set openvpn.vpnserver.dh='/etc/openvpn/dh2048.pem'
  uci set openvpn.vpnserver.tls_auth='/etc/openvpn/tls-auth.key 0'
  uci set openvpn.vpnserver.client_to_client='1'
  uci set openvpn.vpnserver.log='/tmp/openvpn.log'
 
  uci add_list openvpn.vpnserver.push='topology subnet'
  uci add_list openvpn.vpnserver.push='redirect-gateway def1'
  uci add_list openvpn.vpnserver.push='route-gateway dhcp'
  uci add_list openvpn.vpnserver.push='route 192.168.200.0 255.255.255.0'
  uci add_list openvpn.vpnserver.push='dhcp-option DNS 192.168.1.1'
  uci add_list openvpn.vpnserver.push='comp-lzo yes'
  uci add_list openvpn.vpnserver.push='persist-key'
  uci add_list openvpn.vpnserver.push='persist-tun'
uci commit openvpn

After running the script above, the /etc/config/... files will contain:


Server

Enable & Start

Now start your own OpenVPN Server. You can either enable/start it from the Web UI (if you have installed the luci-app-openvpn) or from the command line on the router by running:

/etc/init.d/openvpn enable && /etc/init.d/openvpn start

Wait a few seconds and then you can verify if the OpenVPN Server has successfully started by running the command below. If it produces any output, that means your OpenVPN Server is running.

 ps | grep "[o]penvpn(vpnserver)"

Clients

Generate .ovpn

Your OpenVPN Client will need an .ovpn-file to connect to your OpenVPN server. This section generates a my-server.ovpn file on your router so you can later copy it to your client devices.

To connect to your router remotely (from the internet) you will need to know the router's IP address or DNS name.

  • If you have a static IP from your ISP, copy/paste the script below as-is into your router.
  • If your ISP assigns a dynamic IP, you will need to use a DDNS Client service, then uncomment the wanIP=“dynamic.dns.name” line, replacing dynamic.dns.name with your router's Dynamic DNS name.

Copy-paste the following commands into your router via the SSH session:

create-ovpn.sh
#!/bin/sh
 
source /lib/functions/network.sh
network_find_wan wanIf
network_get_ipaddrs wanIP $wanIf
# wanIP="dynamic.dns.name"
 
OVPN_FILE="/etc/openvpn/my-server.ovpn"
 
cat >> ${OVPN_FILE} <<EOF
  client
  dev tun
  proto udp
  fast-io
  remote $wanIP 1194
  remote-cert-tls server
  nobind
  persist-key
  persist-tun
  comp-lzo no
  verb 3
  key-direction 1
EOF
 
echo '<ca>'         >> ${OVPN_FILE}
cat                 >> ${OVPN_FILE} < /etc/openvpn/ca.crt        
echo '</ca>'        >> ${OVPN_FILE}
 
echo '<cert>'       >> ${OVPN_FILE}
cat                 >> ${OVPN_FILE} < /etc/openvpn/my-client.crt 
echo '</cert>'      >> ${OVPN_FILE}
 
echo '<key>'        >> ${OVPN_FILE}
cat                 >> ${OVPN_FILE} < /etc/openvpn/my-client.key 
echo '</key>'       >> ${OVPN_FILE}
 
echo '<tls-auth>'   >> ${OVPN_FILE}
cat                 >> ${OVPN_FILE} < /etc/openvpn/tls-auth.key 
echo '</tls-auth>'  >> ${OVPN_FILE}
 
# Display the generated OVPN_FILE
  printf "----- Generated .ovpn file ------\n\n"
  cat ${OVPN_FILE}
 
printf "\n\n\n  . . .  DONE  . . .  \n\n\n"

Copy an .ovpn File From Router

The script above displays the generated /etc/openvpn/my-server.ovpn file as its final step. Now copy it to your computer. The easiest way is to copy that text from the screen, and paste it into a new file on your computer named my-server.ovpn.

After you have transferred or saved the my-server.ovpn file to your computer, you can distribute it to your computers/devices that will use the OpenVPN client. The way you connect to your OpenVPN Server depends on the operating system you use, you can find some reference points at OpenVPN Support Guide.

Post-Setup Notes

If you want your files to remain on router after upgrades (this is recommended), run the following:

copy-certs.sh
#!/bin/sh
 
echo /etc/openvpn/ca.crt       > /lib/upgrade/keep.d/openvpnserver
echo /etc/openvpn/my-server.* >> /lib/upgrade/keep.d/openvpnserver
echo /etc/openvpn/my-client.* >> /lib/upgrade/keep.d/openvpnserver
echo /etc/openvpn/dh2048.pem  >> /lib/upgrade/keep.d/openvpnserver
echo /etc/openvpn/tls-auth.*  >> /lib/upgrade/keep.d/openvpnserver

Additional Information

For a complete reference material on the OpenVPN Server setup, please visit OpenVPN Server (Reference).

Troubleshooting

If asking for help in a forum, please perform the following steps to include in your initial post:

  1. OpenWrt:
    1. /etc/config/openvpn
      • verb 5
      • proto tcp
    2. /etc/config/firewall:
      • Change OpenVPN rules to proto 'tcp udp'
        cd /etc/init.d && ./firewall reload && ./openvpn restart
  2. Client:
    1. client.ovpn
      • verb 7
      • proto tcp
    2. Disconnect client, then reconnect

  3. Once client connect attempt fails, please post your client and server logs, as well as the configs for each
    • Ensure WAN IP, DDNS, and port # are removed from configs and logs
      • Server Log: /tmp/openvpn.log
      • Client Log:
        • Windows: Right click on OpenVPN tray icon → View Log
        • BSD/Linux: Refer to client.ovpn

ToDo

  • (maybe) link to sources of OpenVPN clients for various operating systems (Win7, Win10, macOS, Linux, Chromebooks, etc). Actually, this info also belongs on an OpenVPN Client page…
  • Add information on pfx creation
    openssl pkcs12 -export -out my-client.pfx -inkey my-client.key -in my-client.crt -certfile ca.crt
docs/guide-user/services/vpn/openvpn/server.setup.txt · Last modified: 2018/06/20 13:02 by jw0914