DD-WRT reverse proxy and HTTPS

IoT devices on the home network rely on the router to be accessible from the internet. It functions as a remote proxy and translates between HTTPS used on the internet and HTTP on the local area network.

Reverse proxy messages

Reverse proxy

Wildcard CNAME record

A CNAME record maps a domain name to another domain name. In this case the “other” domain name is the DDNS name of our router. By using a wildcard CNAME, such as *.home.domain.com, we can match requests for non-existent sub-domain domain names to home.domain.com. If we would open https://ir.home.domain.com in a browser, the DNS server will give the IP address of home.domain.com to the browser. The browser will then sent an HTTP request to that IP address requesting the page ir.home.domain.com.

Add the CNAME records to your DNS configuration

home.domain.com   3600 IN CNAME dyndns.com
*.home.domain.com 3600 IN CNAME dyndns.com

Remember to replace domain.com with your domain name, and dyndns.com with the dynamic DNS address of your router.

Access Router (pound)

The wildcard CNAME is only part of the equation. Since we configured home.domain.com to map to the IP address of the access router, this router will need to forward HTTP requests to the real IR device on our home network. We do this using a reverse proxy.

Reverse proxy

A reverse proxy uses the Host: field from the HTTP header, to determine where to forward the request to. This allows a server may use a single IP address or interface to accept requests for multiple DNS host names.

We choose the pound implementation because it seemed versatile. We installed pound on the /jffs partition, so that it will survive firmware updates. This guide is written for a Kong build of DD-WRT, but should work with any firmware that has access to lighttpd. You will need a JFFS partition and need to use command line tools via ssh/telnet.

To get up and running, we need the binaries, a script that starts it and configuration files. These files are available through this GitHub page. The scripts are based on Frater’s post.

  1. Enable JFFS partition. From the router’s GUI, enable JFFS (Administration » Management). On first use, check the box to “clean internal flash storage”. Reboot as needed.
  2. Pound binaries. Our router’s firmware didn’t include pound binaries, so we copied it from an older firmware (kongac’s r33010M)
    scp rtr2:/usr/sbin/pound rtr2:usr/sbin/poundctl /jffs/sbin/
    scp rtr2:/usr/lib/libssl.so.1.0.0 rtr2:/usr/lib/libcrypto.so.1.0.0 /jffs/lib
  3. Install startup script. Copy the script /jffs/sbin/pound.sh and its helper write_pound_cfg from GitHub.
  4. Configure port to listen on. The file /jffs/etc/pound/pound.pt1 specifies what port to listen at. The example below uses port 81 since port 80 is already in use for the DD-WRT UI.
    TimeOut     120 
    Alive       30 
    Control     "/tmp/pound.ctl" 
    
    ListenHTTP
        Address 0.0.0.0 
        Port 81
    
  5. Configure forward rules. The file /jffs/etc/pound/pound.pt2 specifies where to forward the HTTP request to. In the example below, we do route both on URL and Host.
            Service "ir-url"  # route home.domain.com/ir to 10.0.1.234:80
                    Url "/ir.*"
                    BackEnd 
                            Address 10.0.1.234
                            Port 80
                    End 
            End 
            Service "ir-host"  # route ir.home.domain.com to 10.0.1.234:80
                    HeadRequire "Host:.ir.home.domain.com.*"
                    BackEnd 
                            Address 10.0.1.234
                            Port 80 
                    End 
            End 
    End 
  6. Start pound using /jffs/sbin/pound.sh start
  7. Give it a spin by pointing a web browser to either
    • http://home.domain.com:81/ir
    • http://ir.home.domain.com:81/

Transport Layer Security

With a way to contact our IR device from the internet, let’s secure the connection using TLS with a free certificates from Let’s Encrypt by loosely following Neilpang’s instructions. We use a slightly modified acme.sh script that fixes a mistake in the regular expression [ticket968] and to avoid problems with binding to a non-existing IPV6 address, we added -4 to the call to openssl. The modified script can be found here.

  1. Get CA certificates using opkg
    mkdir /jffs/opt; mount --bind /jffs/opt /opt  # mount /opt on /jffs/opt
    ( nvram get rc_startup; echo "mount --bind /jffs/opt /opt" ) \
        > /tmp/a; nvram set rc_startup="$(cat /tmp/a); nvram commit"
    bootstrap                                     # install opkg (for CA-certificates)
    opkg update; opkg install ca-certificates     # install CA certificates
  2. Make port 443 available. Disable the existing service on that port (Administration » Web Management » disable HTTPS for web access), and open port 443 on the firewall (Administration » Commands » Firewall » Edit; add the line “iptables -I INPUT 1 -p tcp -m state –state NEW -m tcp –dport 443 -j ACCEPT”).
  3. Try to request a certificate. Remember to replace domain.com with your domain name.
    cd /jffs/usr/ssl
    ./acme.sh --issue --tls -d home.domain.com \
        --home /jffs/usr/ssl --ca-path /opt/etc/ssl/certs \
        --pre-hook "/jffs/sbin/pound.sh stop" \
        --post-hook "/jffs/sbin/pound.sh start" --test
    If all goes well, remove the --test parameter and request the certificate for real.
  4. Automatically renew the certificate, by setting up a cron job to update the certificate before it expires (Administration » Management » Additional Cron Jobs).
    # sundays @2:02am, renew/install SSL certificates if necessary (restarting pound)
    2 2 * * 0 root /jffs/usr/ssl/acme.sh --cron --home /jffs/usr/ssl >/jffs/usr/ssl/cron.log 2>&1
    
  5. Create host.pem by Combine the SSL Private Key, the signed x.509 certificate, and all the certificates in the chain of trust in /jffs/etc/pound/host.pem so that pound can use them
    ./acme.sh --install-cert -d home.domain.com --home /jffs/usr/ssl \
        --cert-file /jffs/etc/pound/host.crt \
        --key-file /jffs/etc/pound/host.key \
        --fullchain-file /jffs/etc/pound/fullchain.crt \
        --reloadcmd "cat /jffs/etc/pound/host.key /jffs/etc/pound/host.crt \
                        /jffs/etc/pound/intermediate-ca.pem \
                        > /jffs/etc/pound/host.pem ; \
                    /jffs/sbin/pound.sh restart"
    
  6. Configure pound for HTTPS instead of HTTP, by modifying the configuration file /jffs/etc/pound/pound.pt1.
    TimeOut   120 
    Alive     30 
    Control   "/tmp/pound.ctl" 
    
    ListenHTTPS
        Address 0.0.0.0 
        Port 443
        Cert "host.pem"
    
  7. Restart pound using /jffs/sbin/pound.sh restart
  8. Give it a spin by pointing a web browser to either
    • https://home.domain.com/ir
    • https://ir.home.domain.com/

DD-WRT leading two separate networks (Asus RT-AC68)

This post shows how a $180 consumer class router can support two different networks. Besides the usual primary network, it will create a secondary network supporting both wireless and wired connections. The secondary network could be used to provide internet access to customers or visitors. The secondary network consists of a 2.4G and 5G radios and two LAN ports. If you only need one radio, you should read Ric’s article instead.seperate-networks2

The router is assumed to be flashed with open source DD-Wrt firmware. This firmware adds some business class features to your router. The configuration will take advantage of two features that allow network traffic to be separated:

  • VLANs, allows wired LAN ports to be grouped and each group to be treated differently.
  • multiple SSIDs, allows multiple wireless network names (SSID) and security settings. The traffic over each SSID can be treated differently.

Before we start

The router is assumed to be running open source DD-Wrt firmware and configured for a single wired and wireless network. The router should also be configured for shell access (ssh) or telnet. Further, the reader should have a basic understanding of

  • the web based user interface (WebGUI)
  • networking concepts such as IP addresses, sub nets, routing, bridging and network interfaces. Some of the more specific terminology used in this article is:
    • A broadcast domain, is a network segment, in which all nodes can communicate directly by layer-2 broadcasts. Examples are a wired GigE network, or a wireless network.
    • A switch, handles frames at the data link layer (layer 2).
    • A router, handles packets at the network layer (layer 3). A router forms a boundary between broadcast domains.
    • A bridge, connects two or more network segments into a single broadcast domain (layer 2).
    • A virtual LAN (VLAN), creates distinct broadcast domains within one ore more physical networks. A VLAN is a switched network that is logically segmented by functions, project teams, or applications without regard to the physical location of users.

The configuration presented here has been tested on an Asus RT-AC68U router running DD-Wrt kongac build 23770M . For the Asus RT-N16 refer to my older article. The approach outlined might also apply to other routers or builds, albeit with minor changes.

Inside the router

To create a secondary network, we need to separate the four LAN ports and create an virtual wireless network. The following section builds a basic understanding of the default data paths in the router. The following section describes how the software configuration

Hardware block diagram

The Asus RT-AC68U router that is build around:

  • System-on-Chip BCM4708, provides the CPU, USB, WAN port and four LAN ports
  • Wireless NIC BCM4360, provides the radio transceiver

This GigE routers has the port number assigned as illustrated below.

RT-AC68-block-before
RT-AC58 block before

The block diagram above shows the data paths within the router. Note:

  • the LAN port numbers on the case may not correspond to the port numbers on the switch;
  • the WAN port connects to a special interface on the switch and can’t be reassigned;
  • port 5 connects the VLAN trunk from the switch to interface eth0 on the CPU.

The switch tags incoming frames with a VLAN identifier. Frames arriving on the WAN port are tagged as VLAN2, while frames from the LAN ports are tagged as VLAN1. The frames destined for the CPU are sent on CPU internal port 5.

The CPU receives the frames over port eth0. Frames with a VLAN2 tag are treated as WAN traffic. Frames with a VLAN1 tag are combined (bridged) with frames from the wireless module (eth1) and treated as LAN traffic.

Firmware mapping

The configuration for the DD-Wrt is stored in nonvolatile memory (nvram). The configuration can be shown as described in the DD-Wrt document Switched Ports. An excerpt:

The tagging configuration is stored in vlan#ports variables where ‘*’ symbolizes the default path. Note that the vlan0ports variable is unused on GigE routers. For the switch to move frames outside of any vlan, it needs to include port 5. This allows the SoC to route the packet. The vlan with the default is used for packets that do not have a vlan tag (see here). SSH/Telnet into the router and: nvram show | grep vlan.*ports | sort vlan1ports=1 2 3 4 5* vlan2ports=0 5

An other important variable is port5vlans. It identifies every active VLAN plus the number 16 that indicates that tagging is enabled. The other variables appear only for the WebGUI. nvram show | grep port.*vlan | sort port0vlans=2 port1vlans=1 port2vlans=1 port3vlans=1 port4vlans=1 port5vlans=1 2 16

Every active VLAN needs to have its name set to et0. nvram show | grep vlan.*hwname | sort vlan1hwname=et0 vlan2hwname=et0

Creating to separate networks

To create a second network, we need to introduce an additional VLAN and an additional SSID for the wireless. The two can then be bridged together and given an unique subnet address. Before you start, I highly recommend making a backup of your current configuration.

RT-AC68-block-after
RT-AC68 block after

Create a virtual wireless network (wl0.1, wl1.1)

Using a web browser, connect to the router and bring up the WebGUI.

  1. Create the WiFi virtual interfaces
    • Wireless » wl0 » Virtual Interfaces
      • Click Add
        • Specify the basic wireless settings.
        • For the network configuration, choose bridged.
        • Do not select Network Isolation
        • Click Save.
    • Wireless » wl1 » Virtual Interfaces
      • Click Add
        • Specify the basic wireless settings.
        • For the network configuration, choose bridged.
        • Do not select Network Isolation
        • Click Save.
  2. Set the WiFi security for the virtual interfaces
    • Wireless » Wireless Security » Virtual Interface wl0.1
      • Specify the security settings
      • Click Apply Settings.
    • Wireless » Wireless Security » Virtual Interface wl1.1
      • Specify the security settings
      • Click Apply Settings.

Create a virtual local area network (vlan3)

We will use the shell (ssh) interface to configure the VLANs (because the GUI on Broadcom based routers have some related bugs). Login using SSH/Telnet, and run the following commands: nvram set vlan3hwname=et0 # enable VLAN3 nvram set vlan1ports=’1 2 5*’ # assign LAN1/LAN2 to VLAN1 nvram set vlan2ports=’0 5u’ # assign WAN to VLAN2 nvram set vlan3ports=’3 4 5*’ # assign LAN3/LAN4 to VLAN3 nvram set port0vlans=2 # WAN is part of VLAN2 nvram set port1vlans=1 # LAN1 is part of VLAN1 (for GUI only) nvram set port2vlans=1 # LAN2 is part of VLAN1 (for GUI only) nvram set port3vlans=3 # LAN3 is part of VLAN3 (for GUI only) nvram set port4vlans=3 # LAN4 is part of VLAN3 (for GUI only) nvram set port5vlans=’1 2 3 16′ # CPU receives tagged VLAN1/VLAN2/VLAN3 nvram commit reboot

Bridge vlan3 and wl0.1 (br1)

To make the new wired and wireless network to behave as one, we logically combine interfaces vlan3 and wl0.1 using a new bridge interface br1:

  1. Bridge the vlan3, wl0.1 and wl1.1 interfaces together as br1
    • Setup » Networking » Bridging » Create Bridge
      • Click Add
        • enter br1 in the first field (optionally disable MSTP)
        • apply settings.
      • For br1 enter a
        • private IP address (e.g. 10.1.1.1), and
        • subnet mask (e.g. 255.255.255.0)
        • apply settings.
    • Setup » Networking » Bridging » Assign to bridge
      • Click Add twice. You should now have 3 assignment entries.
        • br1, interface vlan3 (LAN3 and LAN4)
        • br1, interface wl0.1 (the virtual 2.4G WiFi i/f)
        • br1, interface wl1.1 (the virtual 5G WiFi i/f)
      • Click Apply Settings
  2. Verify that vlan3, wl0.1 and wl1.1 are set to default (we’ll enable NAT later on the bridge)
    • Setup » Networking » Port Setup
      • Network Configuration vlan3 = Default
      • Network Configuration wl0.1 = Default
      • Network Configuration wl1.1 = Default
  3. Enable DHCP server for bridge br1
    • Setup » Networking » DHCPD » Multiple DHCP Server
      • Click Add
        • Select br1 and fill in the first address, maximum number of DHCP addresses and lease time in minutes. E.g. 200, 50 and 1440.
      • Click Apply Settings.

Separate the networks

Now that we have the two networks up and running, it is time to separate them. The firewall rules listed below added to Administration > Commands > Save Firewall. If you use an USB memory stick, the rules can also be stored in an executable /jffs/etc/config/*.wanup script. Such a script runs automatically each time the WAN link and firewall are up (see Script Execution).

Enable NAT for br1 (use “iptables -nvL -t nat” to verify) iptables -t nat -I POSTROUTING -o `get_wanface` \ –src `nvram get br1_ipaddr`/`nvram get br1_netmask` -j SNAT \ –to `nvram get wan_ipaddr`

To restrict br1 from accessing br0 and visa versa, iptables -I FORWARD -i br0 -o br1 -m state –state NEW -j DROP iptables -I FORWARD -i br1 -o br0 -m state –state NEW -j DROP

Optionally, restrict br1 from accessing the management interface of the router. iptables -I INPUT -i br1 -m state –state NEW -j DROP iptables -I INPUT -i br1 -p udp –dport 67 -j ACCEPT iptables -I INPUT -i br1 -p udp –dport 53 -j ACCEPT iptables -I INPUT -i br1 -p tcp –dport 53 -j ACCEPT

Test

To test the interfaces, configure a space computer interface for DHCP and connect it to each of the LAN ports. Then verify that the assigned IP address matches the subnet of the network. Do the same with the wireless networks.

DD-WRT leading two separate networks (Asus RT-N16)

Shows how you can use a $75 consumer class router and dd-wrt to support 2 networks. It will create a secondary network for guests and visitors. Besides the usual primary network, it will create a secondary network supporting both wireless and wired connections. The secondary network could be used to provide internet access to customers or visitors.

The router is assumed to be flashed with open source DD-Wrt firmware. This firmware adds some business class features to your router. The router will be configured by taking advantage of two features that allow network traffic to be separated:

  • VLANs, allows wired LAN ports to be grouped and each group to be treated differently.
  • multiple SSIDs, allows multiple wireless network names (SSID) and security settings. The traffic over each SSID can be treated differently.

Before we start

The router is assumed to be running open source DD-Wrt firmware and configured for a single wired and wireless network. The router should also be configured for shell access (ssh) or telnet. Further, the reader should have a basic understanding of

  • the web based user interface (WebGUI)
  • networking concepts such as IP addresses, sub nets, routing, bridging and network interfaces. Some of the more specific terminology used in this article is:
    • A broadcast domain, is a network segment, in which all nodes can communicate directly by layer-2 broadcasts. Examples are a wired GigE network, or a wireless network.
    • A switch, handles frames at the data link layer (layer 2).
    • A router, handles packets at the network layer (layer 3). A router forms a boundary between broadcast domains.
    • A bridge, connects two or more network segments into a single broadcast domain (layer 2).
    • A virtual LAN (VLAN), creates distinct broadcast domains within one ore more physical networks. A VLAN is a switched network that is logically segmented by functions, project teams, or applications without regard to the physical location of users.

The configuration presented here has been tested on an Asus RT-N16 router running DD-Wrt mega build 15943. The approach outlined might also apply to other routers or builds, albeit with minor changes.

Inside the router

To create a secondary network, we need to separate the four LAN ports and create an virtual wireless network. The following section builds a basic understanding of the default data paths in the router. The following section describes how the software configuration

Hardware block diagram

Many consumer class routers are based on a chipset consisting of a IP switch and System-on-Chip. For example, the Asus RT-N16 router that is build around:

  • System-on-Chip BCM4718, provides the CPU, WiFi and USB.
  • Switch Fabric BCM53115, provides the WAN and four LAN ports

Other GigE routers such as the Cisco/Linksys E2000 or E3000 are very similar. I you have an Asus RT-AC68, refer to my updated post.

Block diagram before

The block diagram above shows the data paths within the router. Note:

  • the LAN port numbers on the case do not correspond to the port numbers on the switch;
  • the WAN port connects to a special interface on the switch and can’t be reassigned;
  • port 8 connects the VLAN trunk from the switch to interface eth0 on the CPU.

The switch tags incoming frames with a VLAN identifier. Frames arriving on the WAN port are tagged as VLAN2, while frames from the LAN ports are tagged as VLAN1. The frames destined for the CPU are sent on port 8.

The CPU receives the frames over port eth0. Frames with a VLAN2 tag are treated as WAN traffic. Frames with a VLAN1 tag are combined (bridged) with frames from the wireless module (eth1) and treated as LAN traffic.

Firmware mapping

The configuration for the DD-Wrt is stored in nonvolatile memory (nvram). The configuration can be shown as described in the DD-Wrt document Switched Ports. An excerpt:

The tagging configuration is stored in vlan#ports variables where ‘*’ symbolizes the default path. Note that the vlan0ports variable appears to be unused on GigE routers. For the switch to move frames outside of any vlan, it needs to include port 8. This allows the SoC to route the packet. The vlan with the default is used for packets that do not have a vlan tag (see here).

nvram show | grep vlan.*ports | sort
vlan0ports="1 2 3 4 5*"
vlan1ports="4 3 2 1 8*"
vlan2ports="0 8

An other important variable is port5vlans. It identifies every active VLAN plus the number 16 that indicates that tagging is enabled. The other variables appear only for the WebGUI.

nvram show | grep port.*vlan | sort
port0vlans=2
port1vlans=1
port2vlans=1
port3vlans=1
port4vlans=1
port5vlans=1 2 16

Every active VLAN needs to have its name set to et0.

nvram show | grep vlan.*hwname | sort
vlan0hwname=et0
vlan1hwname=et0
vlan2hwname=et0

Creating to separate networks

To create a second network, we need to introduce an additional VLAN and an additional SSID for the wireless. The two can then be bridged together and given an unique subnet address. Before you start, I highly recommend making a backup of your current configuration.

Block diagram after

Create a virtual wireless network (wl0.1)

Using a web browser, connect to the router and bring up the WebGUI.

  1. Wireless > Virtual Interfaces > Add. Specify the basic wireless settings. For the network configuration, choose bridged. Click Save.
  2. Wireless > Wireless Security > Virtual Interface wl0.1. Specify the security settings. Click Apply Settings, to save and apply the changes.

Create a virtual local area network (vlan3)

We will use the shell (ssh) interface to configure the VLANs (because the GUI on Broadcom based routers have some related bugs). Login using ssh, and run the following commands:

nvram set vlan3hwname=et0       # VLAN3 is enabled
nvram set vlan1ports="3 4 8*"   # assign LAN1/LAN2 to VLAN1
nvram set vlan3ports="1 2 8*"   # assign LAN3/LAN4 to VLAN3
nvram set port4vlans="1 18 19"  # LAN1 is part of VLAN1 (GUI only)
nvram set port3vlans="1 18 19"  # LAN2 is part of VLAN1 (GUI only)
nvram set port2vlans="3 18 19"  # LAN3 is part of VLAN3 (GUI only)
nvram set port1vlans="3 18 19"  # LAN4 is part of VLAN3 (GUI only)
nvram commit
reboot

Bridge vlan3 and wl0.1 (br1)

To make the new wired and wireless network to behave as one, we logically combine interfaces vlan3 and wl0.1 using a new bridge interface br1:

  1. Bridge the vlan3 and wl0.1 interfaces together as br1
    • Setup > Networking > Bridging > Create Bridge > Add. Enter br1 in the first field and click Apply Settings.
    • Setup > Networking > Bridging > Create Bridge > For br1 enter a private IP address and subnet mask. E.g. 10.0.4.1 and 255.255.255.0. Click Apply Settings.
    • Setup > Networking > Assign to bridge > Add. Select br1, interface vlan3 (LAN3 and LAN4) and click Apply Settings.
    • Setup > Networking > Assign to bridge > Add. Select br1, interface wl0.1 (the virtual wireless interface) and click Apply Settings.
  2. Configure the DHCP server for br1
    • Setup > Networking > DHCPD > Multiple DHCP Server > Add. Select br1 and fill in the first m maximum number of DHCP addresses and lease time in minutes. E.g. 200, 50 and 1440. Click Apply Settings.

Separate the networks

Now that we have the two networks up and running, it is time to separate them. The firewall rules listed below added to Administration > Commands > Save Firewall. If you use an USB memory stick, the rules can also be stored in an executable /jffs/etc/config/*.wanup script. Such a script runs automatically each time the WAN link and firewall are up (see Script Execution).

To restrict br1 from accessing br0 and visa versa,

iptables -I FORWARD -i br0 -o br1 -m state --state NEW -j DROP

iptables -I FORWARD -i br1 -o br0 -m state --state NEW -j DROP

Optionally, to restrict br1 from accessing the management interface of the router.

iptables -I INPUT -i br1 -m state --state NEW -j DROP
iptables -I INPUT -i br1 -p udp --dport 67 -j ACCEPT
iptables -I INPUT -i br1 -p udp --dport 53 -j ACCEPT
iptables -I INPUT -i br1 -p tcp --dport 53 -j ACCEPT

Test

To test the interfaces, configure a space computer interface for DHCP and connect it to each of the LAN ports. Then verify that the assigned IP address matches the subnet of the network. Do the same with the wireless networks.

DD-WRT and OpenVPN (without nvram footprint)

In a virtual private network (VPN) a group of two or more computer systems communicate securely over the public internet.  Security is provided by authentication and encryption.  Computers that connect through a VPN have access to private network as if they were physically connected to it.

This article focuses on the OpenVPN implementation as it is included in the DD-Wrt router firmware.  Besides security, one of its prominent features is that its traffic can traverse network address translators (NAT) and firewalls.

Two examples are given that describe the typical configurations:

  • remote access, providing remote users access to a private network, and
  • site-to-site, connecting a remote network to a private network.

These examples have been tested on two Asus RT-N16 routers running DD-Wrt mega build 15943.  The approach outlined here might apply to other routers or builds that support OpenVPN and a writable file system such as JFFS, albeit with minor changes.

Before you start

This article assumes that readers possess a prior understanding of basic networking concepts such as IP addresses, DNS names, sub nets, routing, bridging, network interfaces, LANs and firewall rules.

Prior to configuring OpenVPN, we need to gain shell access to the routers, give the server a domain name, and create writable storage, keys and certificates.

Writable storage

The most obvious method of configuring OpenVPN is through the DD-Wrt web interface (WebGUI).  This stores the configuration, certificates and keys in nonvolatile memory (nvram).  In many routers, there may not be enough nvram to store all this information.  To show the amount of nvram available, use the command “nvram show | grep size:”.

The approach presented here, has no nvram footprint.  Instead it stores the configuration, keys and certificates on an USB memory stick.  To format this memory stick, use the WebGUI as described in the DD-Wrt JFFS Wiki.  An excerpt:

  1. Insert the memory stick into any available USB port on the back of your DD-Wrt router.
  2. In the WebGUI:
    • Administration >! JFFS2 Support > Enable = true, click Save
    • Wait a few seconds, the click Apply, wait a few seconds
    • Administration > JFFS2 Support > Clean JFFS = true, click Apply
    • Wait for the router to finish formatting the memory stick and brings up the WebGUI again.
    • Administration > JFFS2 Support > Clean JFFS = true, click Save
  3. Reboot the router (just to make sure)
  4. The memory stick will auto mount at /jffs.

Certificates and keys

OpenVPN uses bidirectional authentication with X.509 certificates.  In this model the Certifying Authority (CA) is a third party that is trusted by the owner of the certificate and the party verifying the certificate.

To establish  mutual trust, the client authenticates the server certificate, and the server authenticates the client certificate.  It first ensures that the presented certificate was signed by a certifying authority (CA) , and verifies the common name (CN) and certificate type (client or server).  For details refer to the OpenVPN Howto.

In the example below, we will setup our own CA and generate self signed certificates using a Windows host.  The procedure of generating the certificates is similar for the Other flavors of OpenVPN.

  1. Create vars
    set_var EASYRSA_REQ_COUNTRY	"US"
    set_var EASYRSA_REQ_COUNTRY	"US"
    set_var EASYRSA_REQ_PROVINCE	"California"
    set_var EASYRSA_REQ_CITY	"San Francisco"
    set_var EASYRSA_REQ_ORG	        "Copyleft Certificate Co"
    set_var EASYRSA_REQ_EMAIL	"[email protected]"
    set_var EASYRSA_REQ_OU		"My Organizational Unit"
    set_var EASYRSA_CERT_EXPIRE	7300
    set_var EASYRSA_CERT_EXPIRE	7300
    set_var EASYRSA_NS_SUPPORT	"yes"
    set_var EASYRSA_NS_COMMENT	"Generated by EasyRSA"
  2. Edit easyrsa to extend the case "$cmd" in statement with
    	build-code-signing-full)
    		build_full code-signing "$@"
    		;;
  3. Using the POSIX Shell in Windows
    EasyRSA-Start.bat
    1. Clear the key store
      ./easyrsa init-pki
    2. Create Certifying Authority (CA)
      ./easyrsa build-ca nopass
    3. Create server certificate(s)
      ./easyrsa build-server-full "Example Name" nopass
    4. Create code signing certificate(s)
      ./easyrsa --req-email="[email protected]" build-client-full "Client Name" nopass
    5. If you plan to use OpenVPN, create Diffie Hellman parameters and shared secret key for tls-auth:
      ./build-dh
      openvpn --genkey --secret keys/ta.key
    6. Show the certificate details:
      openssl x509 -in keys/ca.crt -noout -text
  4. In a Linux environment (only because ssh-keygen didn’t play well with the Windows’ file permission system and spit out UNPROTECTED PRIVATE KEY FILE!
    1. If you plan to use the key pair in Windows, you need to convert it to PKCS12 format
      mkdir pki\pkcs12
      openssl pkcs12 -export -in "pki/issued/Client Name.crt" \
          -inkey "pki/private/Client Name.key" \
          -out "pki/pkcs12/Client Name.p12" -certfile "pki/ca.crt"
      

      You can then import the certificates in windows by running certmgr.msc and importing the ca.crt to the Trusted Root Certificate Authority, and the client.p12 to the Personal certificates.

    2. If you plan to use SSH
      mkdir pki\ssh
      cp "pki/private/Client Name.key" pki/ssh/
      ssh-keygen -y -f "pki/ssh/Client Name.key" > "pki/ssh/Client Name.pub"
    3. If you plan to use SSH2 (for e.g. Bitvise SSH)
      mkdir pki\ssh2
      ssh-keygen -e -f "pki/ssh/Client Name.pub" > "pki/ssh2/Client Name.pub"
      openssl rsa -in "pki/ssh/Client Name.key" > "pki/ssh2/Client Name.key"
    4. If you plan to do Java signing
      set NAME=Client Name
      set PASSWD_OUT=changeme
      openssl pkcs12 -in "pki\pkcs12\${NAME}.p12" -out pki\pkcs12\${NAME}-tmp.pem -passin pass: -passout "pass:${PASSWD_OUT}"
      openssl pkcs12 -export -in keys\temp.pem -out keys\%NAME%_passwd.p12 -passin pass:%PASSWD_OUT% -passout pass:%PASSWD_OUT%
      keytool -importkeystore -srckeystore keys\%NAME%_passwd.p12 -destkeystore keys\%NAME%.jks -srcstoretype pkcs12 -srcstorepass %PASSWD_OUT% -deststorepass %PASSWD_OUT%
      del keys\temp.pem

      The JKS keypair can then be imported in e.g. Android Studio.

The previous method:

In the examples below, we will setup our own CA and generate self signed certificates using a Linux host.  The procedure of generating the certificates is similar for the Windows version of OpenVPN.

  1. Copy the easy-rsa directory and initialize:
    cp -R /usr/share/openvpn/easy-rsa/2.0 ~/openvpn-ca  # easy-rsa may be elsewhere
    cd ~/openvpn-ca
    vi vars
      # update the fields at the end of the file
      # change KEY_SIZE value to 2048
    vi openssl-1.0.0.cnf
      # change default_md value to sha512
    vi pkitool
      # change the two occurrences of -sha1 to -sha512
    . ./vars
    ./clean-all
  2. While we’re at it, assign extended key usage that will allow you to use the client certificates for other purposes such as code signing and email.
    vi .`whichopensslcnf`  # open openssl-1.0.0.cnf with Notepad under Windows
    # under [ usr_cert ]
    #  extendedKeyUsage=clientAuth, emailProtection, codeSigning
    #  keyUsage=digitalSignature

    later if so desired, you can convert client certificates to PKCS12 format usi

  3. (optional) To use the key pair on Windows, you need to convert it to PKCS12 format
    openssl pkcs12 -export -in "pki/issued/Client Name.crt"
        -inkey "pki/private/Client Name.key" 
        -out "pki/pkcs12/Client Name.p12"
        -certfile "pki/ca.crt"

    You can then import the certificates in windows by running certmgr.msc and importing the ca.crt to the Trusted Root Certificate Authority, and the client.p12 to the Personal certificates.

  4. (optional) To use the key pair for SSH or SSH2
    ssh-keygen -y -f keys/username.key > keys/username_openssh.pub
    ssh-keygen -e -f keys/username_openssh.pub > keys/username_ssh2.pub
    openssl rsa -in keys/username.key > keys/username_ssh2.key

    The SSH2 keypair (username_ssh2.key) can then be imported in e.g. Bitvise SSH.

  5. (optional) To use the key pair for Java signing, from a cmd prompt in Windows
    set NAME=changeme
    set PASSWD_OUT=changeme
    openssl pkcs12 -in keys\%NAME%.p12 -out keys\temp.pem -passin pass: -passout pass:%PASSWD_OUT%
    openssl pkcs12 -export -in keys\temp.pem -out keys\%NAME%_passwd.p12 -passin pass:%PASSWD_OUT% -passout pass:%PASSWD_OUT%
    keytool -importkeystore -srckeystore keys\%NAME%_passwd.p12 -destkeystore keys\%NAME%.jks -srcstoretype pkcs12 -srcstorepass %PASSWD_OUT% -deststorepass %PASSWD_OUT%
    del keys\temp.pem

    The JKS keypair can then be imported in e.g. Android Studio.

  6. Create a certifying authority certificate and corresponding secret key.  Use your name followed by CA as the common name:
    ./build-ca
  7. Create Diffie Hellman parameters and shared secret key for tls-auth:
    ./build-dh
    openvpn --genkey --secret keys/ta.key
  8. Show the certificate details:
    openssl x509 -in keys/ca.crt -noout -text

Real-time clock

Certificates have introduction and expiration dates, and therefore require the real-time clock and time zone to be set correctly.

The Network Time Protocol (NTP) can be used to automatically set the clocks.  To configure NTP on the DD-Wrt server and clients:

  • Setup > Basic Setup > Time Settings.  For my locality the settings are:
    • Time Zone = UTC-08:00
    • Summer Time = 2nd Sun Mar – first Sun Nov
    • Server IP/Name = 0.north-america.pool.ntp.org

Domain name

Usually the client will find the server by its public DNS name.  If your router gets a dynamic WAN address, you should configure a Dynamic DNS (DDNS) service on the router used as OpenVPN server.  This will give the router a public domain name whose address is automatically updated.

  • Setup > DDNS > Dynamic Domain Name System (my personal favorite is afraid.org)
    • DDNS Service = freedns.afraid.org
    • Host Name = yourhostname,hash (the hash value can be obtained as described in DD-Wrt and freedns.afraid.org).

SSH and emacs

The examples below assume that routers are accessible using secure shell (ssh).  This also enable ssh features in an editor such as emacs. For example, on the Linux host used as the certifying authority:

emacs /rtr:/jffs/etc/config/rtr-server.wanup

Where rtr corresponds to an entry in  your ~/.ssh/config file.

Routing versus Bridging

OpenVPN can connect clients using network routing or bridging.  For a comparison between routing and bridging, refer to Bridging vs. Routing.  An excerpt:

  • Routing uses the kernel device TUN to simulate a network layer device.  It operates at the network layer where it handles IP packets.  As a result, it:
    • has a low overhead, because it does not support broadcasts or require Ethernet headers;
    • for IPv6, OpenVPN version >=2.3 is required.
    • devices such as Android only support TUN.
  • Bridging uses the kernel device TAP to simulates a link layer device.  It operates at the link layer and handles Ethernet frames.  Consequently it:
    • supports non-IP based traffic;
    • supports Windows network neighborhood discovery without using WINS;
    • broadcasts and Ethernet headers cause overhead (for examples, you need to tell DHCP server not to respond to request coming over TAP).

Routing example: Site-to-Site

OpenVPN can be used to connect two local area networks (LANs).  In this example, two DD-Wrt routers are used.  One serves as the server, and the other as the client.  Note that the private network numbers are fairly arbitrary.  They were chosen to match my existing networks.

  • rtr, the server, with
    • WAN address rtr.yourdomain.com
    • LAN network 10.0.1.0/24
  • rtr2, the client.
    • LAN network 10.0.2.0/24

The server will use network 10.0.3.0/24 for the VPN.  Of that allocates the first address (10.0.3.1) for itself.  Clients will be allocated one of the remaining addresses.

rtr-server
srtr-erver

The examples presented here, do not use the WebGUI nor NVRAM.  Instead they use bash scripts store on an memory stick and mounted as /jffs.  The scripts are automatically started by DD-Wrt each time the WAN link and firewall are up.  For more information refer to DD-Wrt Script Execution.

Certificates

  • On the Linux host, create certificates and corresponding secret keys for the server and client.
    ./build-key-server rtr-server # common name = rtr-server, no passwd
    ./build-key        rtr2       # common name = rtr2, no passwd

OpenVPN Server

  • From the Linux host, copy the certificates/keys files to /jffs/etc/openvpn on the server.
    ssh rtr mkdir -p /jffs/etc/config
    ssh rtr mkdir -p /jffs/etc/openvpn/ccd
    scp ca.crt dh2048.pem ta.key rtr-server.crt rtr-server.key rtr:/jffs/etc/openvpn/
  • Create a startup script /jffs/etc/openvpn/config/rtr-server.wanup on the server.  Make the script executable (chmod 755).  DD-Wrt will call this script each time the WAN link comes up.
    #!/bin/sh
    
    DEV=tun0
    PORT=1194
    PROTO=udp
    
    BASE=$(basename $0)
    NAME=${BASE%\.*}
    TMP=/tmp/$NAME
    PID=$TMP/pid
    LOG=$TMP/log
    #LOG=/dev/null
    DIR=$(dirname $0)/../openvpn
    
    [ -d $TMP ] || mkdir -p $TMP
    
    if [ -e $PID ] ; then
        kill -0 `cat $PID`
        if [ $? -eq 1 ] ; then
    	rm $PID  # remove false PID
        fi
    fi
    
    if [ -e $PID ] ; then
        kill -HUP `cat $PID`  # restart
    else
        rm $PID
        ln -s /usr/sbin/openvpn $TMP/openvpn
        $TMP/openvpn \
    	--daemon --writepid $PID --log-append $LOG \
    	--cd $DIR --config $NAME.ovpn \
    	--dev $DEV --port $PORT --proto $PROTO \
    	--up "$DIR/$NAME.helper $DEV $PORT $PROTO up" \
    	--down "$DIR/$NAME.helper $DEV $PORT $PROTO down" \
    	--ifconfig-pool-persist $TMP/ip-pool 86400
    fi
  • Create an helper script /jffs/etc/openvpn/rtr-server.helper on the server. Make the script executable (chmod 755).
    #!/bin/sh
    DEV=$1
    PORT=$2
    PROTO=$3
    case "$4" in
        'up')
            iptables -I INPUT -p $PROTO --dport $PORT -j ACCEPT
            iptables -I INPUT   -i $DEV -j ACCEPT
            iptables -I FORWARD -i $DEV -j ACCEPT
            iptables -I FORWARD -o $DEV -j ACCEPT
    	;;
        'down')
            iptables -D INPUT -i $DEV -j ACCEPT
            iptables -D INPUT -p $PROTO --dport $PORT -j ACCEPT
            iptables -D FORWARD -i $DEV -j ACCEPT
            iptables -D FORWARD -o $DEV -j ACCEPT
    	;;
        *)
    	exit 1
    esac
    exit 0
  • Create the configuration file /jffs/etc/openvpn/rtr-server.ovpn on the server
    server 10.0.3.0 255.255.255.0
    ca ca.crt
    cert rtr-server.crt
    key rtr-server.key
    dh dh2048.pem
    tls-auth ta.key 0
    tls-server
    keepalive 10 120
    cipher bf-cbc
    auth sha1
    mtu-disc yes
    topology subnet
    fast-io
    verb 4
    mute 5
    management 127.0.0.1 5002
    management-log-cache 50
    push "route 10.0.1.0 255.255.255.0"
    client-config-dir ccd                  # run client script matching CN
    route 10.0.2.0 255.255.255.0 10.0.3.1  # kernel to OpenVPN server
    client-to-client
  • Create the client specific configuration file /jffs/etc/openvpn/ccd/rtr2 on the server
    iroute 10.0.2.0 255.255.255.0  # OpenVPN server to remote clients
  • Start the OpenVPN server
    /jffs/etc/config/rtr-server.wanup
  • See how it is going.  Note that you can also use the WebGUI (Status > OpenVPN) to inspect the OpenVPN log messages.
    more /tmp/rtr-server/log  # a treasure trove of debug information
    netstat -lu               # should be listening on port 1194
    iptables -nvL             # INPUT chain should have port 1194 open

OpenVPN Client

  • From the Linux host, copy the certificates/keys files to /jffs/etc/openvpn
    ssh rtr2 mkdir -p /jffs/etc/config
    ssh rtr2 mkdir -p /jffs/etc/openvpn
    scp ca.crt ta.key rtr2.crt rtr2.key rtr2:/jffs/etc/openvpn/
  • Create a startup script /jffs/etc/openvpn/config/rtr2-to-rtr.wanup on the server.  Remember to make the script executable (chmod 755).  DD-Wrt will call this script each time the WAN link comes up.
    #!/bin/sh
    
    DEV=tun0
    PORT=1194
    PROTO=udp
    
    BASE=$(basename $0)
    NAME=${BASE%\.*}
    TMP=/tmp/$NAME
    PID=$TMP/pid
    LOG=$TMP/log
    #LOG=/dev/null
    DIR=$(dirname $0)/../openvpn
    
    [ -d $TMP ] || mkdir -p $TMP
    
    if [ -e $PID ] ; then
        kill -0 `cat $PID`
        if [ $? -eq 1 ] ; then
    	rm $PID  # remove false PID
        fi
    fi
    
    if [ -e $PID ] ; then
        kill -HUP `cat $PID`  # restart
    else
        rm $PID
        ln -s /usr/sbin/openvpn $TMP/openvpn
        $TMP/openvpn \
    	--daemon --writepid $PID --log-append $LOG \
    	--cd $DIR --config $NAME.ovpn \
    	--dev $DEV --port $PORT --proto $PROTO \
    	--up "$DIR/$NAME.helper $DEV up" \
    	--down "$DIR/$NAME.helper $DEV down"
    fi
  • Create an helper script /jffs/etc/openvpn/rtr2-to-rtr.helper on the server. Remember to make the script executable (chmod 755).
    #!/bin/sh
    DEV=$1
    case "$2" in
        'up')
            iptables -I INPUT   -i $DEV -j ACCEPT
            iptables -I FORWARD -i $DEV -j ACCEPT
            iptables -I FORWARD -o $DEV -j ACCEPT
    	;;
        'down')
            iptables -D INPUT -i $DEV -j ACCEPT
            iptables -D FORWARD -i $DEV -j ACCEPT
            iptables -D FORWARD -o $DEV -j ACCEPT
    	;;
        *)
    	exit 1
    esac
    exit 0
  • Create the configuration file /jffs/etc/openvpn/rtr2-to-rtr.ovpn on the client
    client
    remote rtr.yourdomain.com
    ns-cert-type server
    ca ca.crt
    cert rtr2.crt
    key rtr2.key
    tls-auth ta.key 1
    tls-client
    cipher bf-cbc
    auth sha1
    resolv-retry infinite
    nobind
    persist-key
    persist-tun
    mtu-disc yes
    fast-io
    verb 4
    mute 5
    management 127.0.0.1 5001
    management-log-cache 50
  • Start the OpenVPN client
    /jffs/etc/config/rtr2-to-rtr.wanup
  • See how things are going.  Note that you can also use the WebGUI (Status > OpenVPN) to inspect the OpenVPN log messages.
    more /tmp/rtr2-to-rtr/log

Bridging example: Remote Access

OpenVPN can also be used to connect remote computers to a local area network.  The VPN gives the remote computers access to resources on the local area network such as files, printers, databases or internal websites.

In this example, one DD-Wrt router is configured as an OpenVPN server.  Road warrior clients can connect to this router to gain access to the server’s LAN.  The systems are:

  • rtr2, the server with:
    • LAN network 10.0.2.0/24
    • WAN address rtr2.yourdomain.com
  • client, connecting from a public IP address, running either
rtr2-server
rtr2-server

Certificates

  • On the Linux host, create certificates and corresponding secret keys for the server and clients.
    ./build-key-server rtr2-server  # common name = rtr2-server, no passwd
    ./build-key        username1    # common name = username1, no passwd
    ./build-key        username2    # common name = username2, no passwd

OpenVPN Server

  • From the Linux host, copy the certificates/keys files to /jffs/etc/openvpn on the server.
    ssh rtr mkdir -p /jffs/etc/config
    ssh rtr mkdir -p /jffs/etc/openvpn/ccd
    scp ca.crt dh2048.pem ta.key rtr-server.crt rtr-server.key rtr:/jffs/etc/openvpn/
  • Create a startup script /jffs/etc/openvpn/config/rtr2-server.wanup on the server. Make the script executable (chmod 755). DD-Wrt will call this script each time WAN link comes up.
    #!/bin/sh
    
    BR=br0
    DEV=tap0
    ETHDEV=eth0
    PORT=1194
    PROTO=udp
    
    BASE=$(basename $0)
    NAME=${BASE%\.*}
    TMP=/tmp/$NAME
    PID=$TMP/pid
    LOG=$TMP/log
    #LOG=/dev/null
    DIR=$(dirname $0)/../openvpn
    
    [ -d $TMP ] || mkdir -p $TMP
    echo "$(date) $NAME: WAN up" >$LOG
    
    if [ -e $PID ] ; then
        kill -0 `cat $PID`
        if [ $? -eq 1 ] ; then
    	rm $PID  # remove false PID
        fi
    fi
    
    if [ -e $PID ] ; then
        kill -HUP `cat $PID`  # restart
    else
        rm $PID
    
        ln -s /usr/sbin/openvpn $TMP/openvpn
        $TMP/openvpn \
    	--daemon --writepid $PID --log-append $LOG \
    	--cd $DIR --config $NAME.ovpn \
    	--dev $DEV --port $PORT --proto $PROTO \
    	--up "$DIR/$NAME.helper $BR $DEV $PORT $PROTO up" \
    	--down "$DIR/$NAME.helper $BR $DEV $PORT $PROTO down" \
    	--ifconfig-pool-persist $TMP/ip-pool 86400
    fi
  • Create an helper script /jffs/etc/openvpn/rtr2-server.helper on the server. Make the script executable (chmod 755).
    Note that the tap interface will get a random MAC address and the bridge (br0) picking up the lowest address.  This confuses Windows Network Discovery in Windows 7, triggering a “Set Network Location” dialog.  To prevent this, you can take the last random MAC address and reuse it for subsequent tap interfaces.  (More details here.)

    #!/bin/sh
    BR=$1
    DEV=$2
    PORT=$3
    PROTO=$4
    case "$5" in
        'up')
    	#ifconfig $DEV hw ether enter_your_last_mac_address
            ifconfig $DEV 0.0.0.0 promisc up 
            brctl addif $BR $DEV 
            iptables -I INPUT -p $PROTO --dport $PORT -j ACCEPT
    	iptables -I INPUT   -i $DEV -j ACCEPT
    	iptables -I FORWARD -i $DEV -j ACCEPT
    	iptables -I FORWARD -o $DEV -j ACCEPT
    	;;
        'down')
    	brctl delif $DEV
    	ifconfig $DEV down
    	iptables -D INPUT -i $DEV -j ACCEPT
    	iptables -D INPUT -p $PROTO --dport $PORT -j ACCEPT
    	iptables -D FORWARD -i $DEV -j ACCEPT
    	iptables -D FORWARD -o $DEV -j ACCEPT
    	;;
        *)
    	exit 1
    esac
    exit 0
  • Create the configuration file /jffs/etc/openvpn/rtr2-server.ovpn on the server. Note that port 5002 is used by the /etc/openvpn*.shscripts.
    server-bridge 10.0.2.1 255.255.255.0 10.0.2.150 10.0.2.159
    ca ca.crt
    cert rtr2-server.crt
    key rtr2-server.key
    dh dh2048.pem
    tls-auth ta.key 0
    keepalive 10 120
    cipher bf-cbc
    auth sha1
    mtu-disc yes
    topology subnet
    client-to-client
    push "route 10.0.1.0 255.255.255.0 10.0.2.1" # optional across other VPN
    fast-io
    verb 4
    mute 5
    management 127.0.0.1 5002
    management-log-cache 50
  • Start the OpenVPN server
    /jffs/etc/config/rtr2-server.wanup
  • See how it is going. Note that you can also use the WebGUI (Status > OpenVPN) to inspect the OpenVPN log messages.
    more /tmp/rtr2-server/log  # a treasure trove of debug information
    netstat -lu                # should be listening on port 1194
    iptables -nvL              # INPUT chain should have port 1194 open

OpenVPN Server (using WebGUI)

Alternatively, the server can be configured using the DD-Wrt WebGUI.  The config will be stored in nvram, except for the large certificates and key files that are stored on a memory stick.  In this configuration, DD-Wrt generate matching files in /tmp/openvpn/.

  • Copy the certificates/keys files.  Remember to limit access to the key files (chmod 600).
    • ca.crt
    • rtr2-server.crt
    • rtr2-server.key
    • dh2048.pem
    • ta.key
  • Services > VPN > OpenVPN Server.  These values will be used to create the configuration file /tmp/openvpn/openvpn.conf
    • Start OpenVPN Server = enable
    • Start Type = WAN up (after domain resolver is up)
    • Switch Server config = new Style
    • Pool IP = 10.0.2.150 .. 10.0.2.159
    • Gateway = 10.0.2.1
    • Netmask = 255.255.255.0
    • Port = 1194
    • Tunnel Protocol = UDP
    • Encryption Cipher = Blowfish CBC
    • Hash Algorithm = SHA1
    • Advanced Options = disable
    • The Cert, Key fields are left blank.  Instead use the Additional Config field to refer to the files on the USB stick  (see OpenVPN with key and certificate files via WebGUI).
      cert /jffs/rtr2.crt
      ca /jffs/ca.crt
      key /jffs/rtr2.key
      dh /jffs/dh2048.pem
      tls-auth /jffs/ta.key 0
      push "route 10.0.2.0 255.255.255.0"

OpenVPN Client, running Windows 10

  • Import Certificates (from paragraph 6.4.1 in my document SISO).
    • From the start menu run certmgr.msc
    • Under the Certificates, right-click on Trusted Root Certification Authorities. From All Tasks choose Import.
      • Click Next
      • Browse to select the Personal Information Exchange certificate CAcert.crt.
      • Click Next
      • Type in the password, and Mark this key as exportable
      • Click Next
      • Place all certificates in Personal Certificates Store
      • Click Next; Click Finish
      • Verify that the certificate is listed under the Root Certification Authorities
    • Under the Certificates, right-click on Personal. From All Tasks choose Import.
      • Click Next
      • Browse to select the Personal Information Exchange certificate (yourname.p12).
      • Click Next
      • Type in the password, and Mark this key as exportable
      • Click Next
      • Place all certificates in Personal Store
      • Click Next; Click Finish
      • Verify that the certificate displays correctly, and the Root CA is known.
  • Use explorer to show the directory “C:\Program Files (x86)\OpenVPN\config\”
    • Populate the directory with the certificate and key files from the Linux host:
      • ca.crt
      • username1.crt
      • username1.key
      • ta.key
    • Create the configuration file rtr2.ovpn in that same directory

      remote rtr2.yourdomain.com 1194
      client
      ca ca.crt 
      cert username1.crt 
      key username1.key 
      tls-auth ta.key 1
      ns-cert-type server
      dev tap
      proto udp 
      nobind 
      resolv-retry infinite 
      persist-key 
      persist-tun 
      remote-cert-tls server 
      float
      script-security 2
      cipher BF-CBC
      auth SHA1
      verb 3
      mute 5
  • With OpenVPN running, right-click on its icon in the task area (bottom right) > connect > rtr2.

OpenVPN Client, running OS X

  • Create folder rtr2.yourdomain.com on your Desktop.  (details can be found in the wiki)
    • Copy the certificate/key files to that folder
      • ca.crt
      • username2.crt
      • username2.key
      • ta.key
    • In that folder, create configuration file rtr2.ovpn
      remote rtr2.yourdomain.com 1194  # update me
      client
      ca ca.crt 
      cert username2.crt 
      key username2.key 
      tls-auth ta.key 1
      ns-cert-type server
      dev tap
      proto udp 
      nobind 
      resolv-retry infinite 
      persist-key 
      persist-tun 
      remote-cert-tls server 
      float
      script-security 2
      cipher BF-CBC
      auth SHA1
      verb 3
      mute 5
  • Append the extension .tblk to the folder name. This will change the folder icon into a Tunnelblick VPN Configuration.
  • Double-click the folder’s new icon to install it. Choose private configuration when asked.
Copyright © 1996-2022 Coert Vonk, All Rights Reserved