Automating Network Privacy: Tunneling Watchdog Scripts and Asuswrt-Merlin
This is an informative guide detailing how to configure, monitor, and automate failure resolution (i.e. watchdog) OpenVPN tunnel connections on a home router. Additional information on some of the mathematics behind modern cryptography, such as a comparison of paradigms between Rivest–Shamir–Adleman (RSA) and Elliptic-Curve Cryptography (ECC), and a list of privacy-enhancing technologies are also provided.
This article is expected to be about a 29 minute read.
It has always been my belief that freedom is sacrosanct. The more restrictions there are placed upon us, the more problems we suffer through in our finite existence. The more prying eyes there are upon us, the more this freedom splinters off into eroded fragments, ever susceptible to the whims of secretive overzealous surveillance legislation.
Privacy is a prerequisite to a true sense of freedom in the human condition. It is the elixir to our personal lives, securing the bonds between friends and family and our individualism. It is an irrevocable and self-evident human right. To say otherwise - that one has nothing to hide - is nothing more than a deprecated folly (if you disagree, please head over to my /contact/ page and send me your bank account numbers, street address, date of birth, browser history, and copies of every text message and email you have ever sent or received).
In the digital age, technology has enabled the implementation of widespread, sweeping surveillance in such depth that the ideas of privacy and anonymity, by default, have been outright replaced with tracking persistent identity. Unless extra measures are proactively taken to evade it, user activity is automatically monitored, ingested and cataloged without the user’s knowledge or consent on an unprecedented global scale. The motives and methods may vary, but the act itself, disturbingly, is unwavering and trending predominantly in one direction.
Despite this reality, you may be asking yourself why it matters, and what can be done about it even if it did matter. You may truly believe you have “nothing to hide” and that large corporations, media outlets, your Internet service provider (ISP) and political leaders collecting, selling and disseminating your data mean you no harm and is not cause for concern. You may believe you are a good person with good intentions and thus you do not fear the possibility of retribution when no crimes have been committed. You may believe that privacy-enhancing legislation is a sufficient solution to this growing problem.
I do not hold you totally accountable for this mistake. Whether through sheer ignorance, willful disregard, or political chicanery, complacency tends to weave its way in over time without announcing itself and without provocation. If you simply allow bad actors to do bad things, they will do bad things. In an ever increasingly distracted world (I prefer the nomenclature Huxleian), the bad actors tend to get away with it. Should you be blamed too? Well, maybe.
The lessons of history have shown ad nauseum the evils of unrestrained hegemonic domination, of which the gathering of intelligence is a common precursor. You need not look far to be reminded. Therefore, in any instance where any measure can be taken to limit surveillance, the avenue to do so should at the very least be scrutinized and hopefully thoroughly examined. Complacency is the sole alternative and proceeds the most severe atrocities ever known.
Fortunately, technology also provides a means to safeguard our lives from silent observers. Encryption, while better when combined with obscurity and technically vulnerable to time and newer emerging threats, currently provides the best protection from eavesdropping bar none and is widely and freely available for anyone to use. To quote Jacob Applebaum:
“One must acknowledge with cryptography no amount of violence will ever solve a math problem.”
This sentiment is shared among privacy advocates and believers in the 1980s and 1990s Cypherpunk movement - myself included - and lives within privacy-enhancing technologies like Tor and Bitcoin, the latter of which whose inventor(s), Satoshi Nakamoto, remain(s) unidentified 14 years later despite the release of a complete white paper.
In a time when persistent identity runs rampant, a growing necessity for such technology becomes evident. As Jacob states above, we can simply allow cryptography to set the rules, regardless of any legislation or attempts to intervene.
In succinct verbiage, unlike humans, the physical laws of the universe are not vulnerable to extortion. No amount of legislation - in either direction - will ever solve a math problem.
This post serves as a reference guide for one easy step anyone can take to utilize technology in this opposite direction: to enhance their privacy and security through an automated and efficient home network solution. I will conclude with a list of privacy-enhancing technology software and update it over time in the hope that someone will find it useful. The steps outlined below target one specific platform for the sake of instruction, but are likely applicable to others. Do not feel limited or discouraged because of the prerequisites.
VPN
Most of us have heard the acronym “VPN” thrown around even if we are not too involved with data privacy, security or technology. Chances are, if you have worked from home at all during the COVID-19 pandemic, you have used a VPN with or without realizing it.
Virtual Private Networks (VPNs) provide one way of establishing secure communication between computers and networks, or between two networks themselves, over an insecure medium such as the public Internet. The term “computer” applies generally here, and includes other modern devices used by consumers on a daily basis such as smartphones and routers. VPN security is provided through the use of cryptography.
Employers utilize VPNs for a myriad of reasons, one of which is to allow employees to remotely connect to their company’s network as if they were physically in the office. Employers can rest assured that the cryptographic algorithms used to secure employee connections through a VPN are safe from tampering and eavesdropping through the implementation of tunneling protocols and encapsulation. This makes working from home safe and secure.
Common consumer uses of VPNs include:
Accessing home, school, and work networks from any physical location
Avoiding targeted bandwidth throttling and online shopping price discrimination
Bypassing web filters to access normally blocked content (e.g. TV streaming services)
Preventing upstream data collection and network activity monitoring
Protecting network activity in untrusted or hostile environments or on public access points
For the general consumer, there are a few decisions to make when electing to use a VPN. The first decision is determining which VPN provider to trust, and this can be difficult to do as there are recommendations for basically every single option available. There are also new VPN providers showing up every single year as it tends to be a lucrative business.
Many people do not trust any VPN provider service and instead set up their own VPN server on a virtual private server (VPS) or dedicated server, as doing so means complete control over the local filesystem on their own VPN server (which includes user activity logs). I have done this myself only as a proof of concept, but in my mind, this alternative is actually less private than pursuing a well-regarded commerical VPN provider since paying the rental fees for a VPS implies personally identifiable information (PII) being attached to an approval process with the hosting company. This is undeniably true unless they allow anonymous payment systems like Bitcoin or other cryptocurrencies, in which case, it’s a different story.
Setting up a VPN server requires extra steps that are out of scope for this post. It can be done - I have done it myself - but for the purposes of this post, I will be recommending Proton VPN, a Swiss-based VPN service operating out of Sweden, Iceland, and Switzerland. These countries are notable for their strong privacy laws and exist outside high-risk jurisdictions and restrictive Internet regulations present in countries like Russia, Iran, and Turkey, and also outside of countries with broad surveillance powers like the Five Eyes (FVEY).
Explaining how to set up an account with a VPN provider is also technically out of scope, but nonetheless, if one decides to trust Proton VPN in this specific case, they can do so by clicking here. I personally recommend also setting up and migrating over to Proton Mail to protect your email service privacy, thus signing up for “Proton Unlimited” on their pricing page, but this too is out of scope. The remainder of this post will assume that the reader has either elected to set up their own VPN server or pay for a VPN providing service, whether through Proton VPN or some other service, and thus has access to VPN client configurations as explained below.
VPN providers tend to provide configurations for VPN clients, the devices which connect to VPN servers. As mentioned previously, this would include computers, smartphones, routers and other types of devices supporting VPN software. They also sometimes provide commercial desktop or mobile applications for Windows, Linux, MacOS, iOS, and Android. If the VPN provider does not provide a desktop or mobile application to download and install on end devices, the alternative is to provide VPN client configurations, which are usually just text files. The end devices will need to support installation of these configurations or they cannot connect to the VPN directly.
Many people do not want to install commercial applications or VPN client configurations on every single device they wish to protect. One alternative method, which is the focus of this post, is to install a VPN client configuration on a home router. With this method, all devices connected to the local area network (LAN) will be tunneled through the VPN connection that exists between the router and the VPN server instead of between each specific device and the VPN server. This also reduces the number of active tunnels if the provider sets a limit.
VPN providers are not commonly able to provide commercial software applications for specific consumer-grade routers, but many routers support the installation of VPN client configurations. Two common and often supported VPN protocol software solutions are the older OpenVPN and newer WireGuard. Both of these, but especially OpenVPN, are recommended in this post.
OpenVPN
OpenVPN is a widely supported VPN system used to create secure point-to-point or site-to-site connections by implementing both server and client applications. In the context of this post, the server side of the application refers to the VPN provider (e.g. Proton VPN) whereas the client side of the application refers to the connecting device - in this case, as already mentioned above, a home router (or any other end device).
Security
In order to facilitate secure communication, OpenVPN extensively utilizes the OpenSSL encryption library for its data and control channels as well as the TLS protocol for key exchange. It offers several ways to authenticate peers with each other, including pre-shared keys (PSK), certificate-based and username/password-based authentication.
As is the case with any asymmetric cryptographic authentication mechanism, certificate-based (or public/private key file infrastructure) will always be preferable and more robust than using PSKs or username/password combinations as the latter two are more susceptible to modern attacks. Certificates also provide configuration advantages over the other available options.
Despite being 22 years old, OpenVPN is still widely regarded as the most secure VPN protocol available. More accurately (or empirically), it is the most widely used and supported protocol available. This dominance is beginning to be challenged by WireGuard.
OpenVPN implements two channels to transfer data: the control channel and the data channel. The control channel establishes a TLS connection between the VPN client and server, which uses a symmetric key cipher (AES-256), but the actual key exchange itself requires an asymmetric encryption system (RSA-4096 to ensure secure key exchange, HMACSHA-384hash authentication to verify certificates, and the Diffie-Hellman key exchange (DHE) to provide forward secrecy). Once the TLS connection is established, OpenVPN transfers encrypted data over the data channel using AES-256.
CBC operates simply by XORing each block - fixed-length groups of bits - with the previous block and cannot be written in parallel. CBC is also vulnerable to padding oracle attacks, which exploit the tendency of block ciphers to truncate arbitrary bits onto the end of the last block in a sequence to meet block size specifications. All ciphertext blocks in CBC mode therefore depend upon on all previous plaintext blocks processed up to that point, beginning with an initialization vector (IV) to make each message unique.
GCM, in contrast, combines CBC with Galois field multiplication to essentially transform what would normally be a block cipher into a stream cipher, where each block is encrypted with a pseudorandom value from a keystream. This is achieved by using successive values of an incrementing counter such that every block is encrypted with a unique value that is unlikely to reoccur. The Galois field multiplication component takes this to the next level by conceptualizing each block as its own finite field for the use of encryption.
Given the use of AES-256, it should come as no surprise, as the name suggests, that OpenVPN provides up to 256-bit encryption. For observation, the United States government entrusts AES-192 to secure all top secret (TS) information. AES-256 is a data security standard which may be best understood and visualized through this video by 3Blue1Brown on YouTube:
Correction
Minor correction at 0:32: Brute-force of a 2n key space requires 2n/2 = 2n-1 guesses on average, but 2n guesses in the worst case scenario. This becomes obvious with smaller key sizes. For example, when given that 24 = 16 and 25 = 32, an attacker would only need, on average, 16/32 guesses but could need 32/32 guesses to find the key. This is less clear when dealing with 256-bit security (2256/2 = 2255).
OpenVPN capitalizes on its use of AES even further with the Advanced Encryption Standard New Instructions (AES-NI) set - an AES instruction set built directly into many modern processors - which greatly improves the speed at which AES computation is processed. This means that when used with AES, OpenVPN benefits from cryptographic hardware acceleration.
256-bit symmetric encryption with AES is highly robust and ideal for securing data over the VPN connection, but there must also be a secure way to agree on a key before this data is transmitted. To handle key exchange and authenticate between the VPN client and server, OpenVPN uses RSA-4096 and DHE to secure the TLS key exchange.
DHE is technically vulnerable to logjam attacks at smaller key sizes due to its reuse of a limited set of prime numbers, making its use to secure the TLS key exchange process somewhat controversial. Despite this, however, DHE provides forward secrecy in that it generates new encryption keys for every single VPN session. Without forward secrecy, adversaries capable of obtaining VPN session encryption keys - such as APTs - will be able to decrypt all historic sessions secured using that key.
RSA is also used to secure TLS key exchanges in OpenVPN, but it does not provide forward secrecy like DHE. Fortunately, OpenVPN had the foresight to implement RSA and DHE together in its protocol: RSA to secure the TLS key exchange and DHE to provide forward secrecy.
The use of HMAC SHA (or GCM mode, as mentioned previously) to verify certificates and authenticate data helps to ensure that data has not been tampered with in the VPN connection. HMAC SHA and AES-GCM can actually both be used with OpenVPN: HMAC SHA to authenticate the connection itself and AES-GCM to authenticate data for the rest of the session.
In summary, OpenVPN implements the following:
RSA-4096 and DHE for its key exchange
AES-256 for its symmetric encryption
CBC as its mode of operation OR
GCM as its AEAD
HMAC SHA-384 (or AES-GCM) for hash authentication
OpenVPN’s configuration files can be adjusted and hardened to the user’s preferences, especially if the user is operating their own VPN server. Examples include adjusting the ciphernegotiation, the auth hash authentication algorithm, the proto protocol to UDP or TCP, and default key sizes. Given this post is more or less aimed at the use of a commercial VPN provider - namely, Proton VPN - configuration settings are limited to the client’s .ovpn file and will need to be compatible with what the provider allows.
OpenVPN can be configured to operate over the User Datagram Protocol (UDP) or Transmission Control Protocol (TCP) transport protocols, which use ports 1194-UDP and 443-TCP respectively. UDP is the recommended default configuration due to its speed and performance advantages over TCP, but TCP is often recommended if outbound UDP VPN traffic is being blocked by a firewall, ISP, or any other sort of network traffic filtering system.
Outbound TCP on port 443 is typically more difficult to filter because it blends in with normal web traffic and is thus not often blocked in firewall policy. The widespread use of deep packet inspection (DPI) techniques will challenge this statement, however. TCP will be more reliable than UDP, but slower, which can be problematic on lower tier bandwidth services.
Compatibility
Most notably for this post, OpenVPN is compatible with a number of firmware packages used on consumer-grade routers, including but not limited to DD-WRT, Gargoyle, OpenWrt, OPNsense, pfSense, and Tomato. It is likely that at least one of these packages (or derivatives thereof) can operate on a router that the general consumer has installed in their home.
WireGuard is a newer and extremely simple yet modern VPN system which has seen widespread adoption over the 8 years it has existed (compare this to OpenVPN’s 22 years) designed to offer high-performance, state of the art security and a minimal attack surface.
It accomplishes these feats through the implementation of high-speed cryptographic primitives based on Elliptic-curve cryptography (ECC), as well as a small codebase, allowing for comprehensive review and making it easily auditable. Impressively, for example, it is possible to implement WireGuard on Linux in less than 4000 lines of code.
Because of its lightweight nature, WireGuard maintains efficiency outside of just its smaller codebase. Its improved performance metrics on lower-end hardware translates to longer battery life when running on end devices such as mobile phones, computers and routers.
Like Bitcoin, WireGuard has its own white paper, authored by its creator, Jason A. Donenfeld. In the document, Donenfeld mentions its advantages over alternative solutions (especially IPsec and TLS-based implementations like OpenVPN):
Security
WireGuard’s small codebase helps to minimize its attack surface in comparison to IPsec or OpenVPN, which is based upon the goliath of the OpenSSL library. OpenSSL has been historically susceptible to vulnerabilities on a regular basis (looking at you, Heartbleed).
Essentially, this means that the attack surface is reduced to any vulnerabilities found in the cryptographic primitives used by WireGuard rather than those routinely found in a supermassive cryptographic library. In this manner, Donenfeld labels WireGuard cryptographically opinionated in that it “intentionally lacks cipher and protocol agility.” Consequently, if WireGuard is impacted by weaknesses found in the primitives it uses, it will need to be updated directly.
Specifically, WireGuard implements the following:
X25519 (also called Curve25519) for its key exchange
For the math nerds out there (and to relate back to the “math problem” statement above), the use of ECC - i.e., X25519 - allows WireGuard to achieve the same level of security as e.g. RSA but with much smaller key sizes. This is because ECC is based upon the difficulty associated with finding the discrete logarithm of a random elliptic curve element with respect to a publicly known base point whereas RSA is based upon the intractability of the prime factorization of large integers composed of two or more large prime integers.
The mathematics of RSA - the hardness of prime factorization - date back roughly 2500 years and have therefore been subjected to intense scrutiny spanning millennia. The mathematics of ECC - the hardness of finding the discrete logarithm of elliptic curves over finite fields - date back only 25 years, which is 100 times “newer” than RSA.
Both of these problems are examples of the P versus NP problem, which ponders whether answers to questions in polynomial time (P) can also be solved in polynomial time (NP). The security provided by all modern cryptography (and the mathematics behind it) relies on the inability to solve this problem. Translated to English, it simply poses the following question:
“If the solution to a problem is easy to check, is it also easy to find?”
It is our current conjecture that P != NP (!= signifies “not equals”), meaning that we believe the answer to this question is “No”, but we lack the evidence to definitively prove it. Likewise, we lack the evidence to definitively prove the answer is “Yes”, which would state that P = NP, of which we observe no evidence of at least in the context of cryptography. It is important to note here that absence of evidence is not evidence of absence, and it is generally accepted that we, as humans, are quite limited in our capacity to understand the universe.
We believe based on observation alone that P != NP, and we believe it enough to trust that our data is secure through cryptography. The easiest example I can think of to visualize this behavior would be a cryptographic hash function; solutions are easy to check, but not find.
If I instructed someone to find the text which produces the bcrypt digest $2a$15$zXk/lim.CeVN.muaREk5ROV.i07hr7uRl.t7vdyg7b0fN9J0VU8jG, there is no known way to find it other than guessing random (or sequenced) texts until this digest is produced. There is also no known way to use this digest to compute the text. However, if I simply told someone that the text is MY0tH70!gVFV6q^42^y*FbgQoi#v!M, verifying whether this is true or false is as trivial as computing bcrypt("MY0tH70!gVFV6q^42^y*FbgQoi#v!M", 15) (assuming a known cost factor) and comparing the result to the above digest. In this manner it is clear that finding the solution is impractically difficult relative to verifying a solution.
Should a definitive proof be found for eitherP != NP or P = NP, there will be profound implications for not only all of modern cryptography but also for mathematics, philosophy, economics and essentially reality itself as we understand it. In the context of security, a definitive proof for P = NP seems much more frightening to me than one for P != NP (modern cryptography would most certainly be irrevocably broken).
This relevant tangent aside, ECC is notable for its use in WireGuard as it is one of many contributing factors to its advertisement as being “designed to be faster than OpenVPN” as a VPN protocol. X25519 is used by the Elliptic-curve Diffie-Hellman (ECDH) protocol to secure the TLS key exchange process, ensuring that the connection to the VPN server is secure.
WireGuard also provides an optional “future-proofing” pre-shared key mode in an attempt to thwart emerging threats in cryptography - namely, quantum computing - in the event that the security provided by X25519 is ever defeated. PSKs are generally more difficult to manage given that they must be stored (and are thus vulnerable to theft, compromise, or extortion). Should the PSK be compromised, there is still ECC to defeat.
While WireGuard does not benefit from the same hardware acceleration advantage as OpenVPN with AES-NI, it still manages to offer speeds comparable to hardware accelerated AES due to its ability to leverage generalized hardware support for vectorized operations (SSE and AVX are two examples). The use of ChaCha20-Poly1305 is comparable to how OpenVPN can use AES-GCM in that they are both AEAD ciphers, and it is expected that the performance gap between ChaCha20-Poly1305 and AES-NI will become smaller in time (it is speculated that AES-NI may even be surpassed by ChaCha20-Poly1305 in the future).
The use of SipHash, a XOR-based pseudorandom hash function used to securely map hash table keys, BLAKE2s, a cryptographic hash function used for data verification, and HKDF, a key derivation function, follow the same logic outlined above in regards to ECC and the selection of X25519 in that they were all selected for use in WireGuard because they offer the same level of security but with speed and efficiency in mind. White papers for each follow below.
Perhaps one of the more distinguishing design decisions of WireGuard is its adoption of a variant of the Noise protocol, a framework used for building crypto systems promising mutual and optional authentication, identity hiding, forward secrecy, and zero round trip encryption (0-RTT). Specifically, WireGuard implements the “IK” pattern of Noise, which is labeled Noise_IK. Noise also has its own white paper, authored by its creator, Trevor Perrin:
Similar to the SWEET32 and OpenSSL library disclaimers I made about OpenVPN, it would be an injustice not to reiterate common security concerns with WireGuard.
It should be noted that, technically speaking, the security provided by WireGuard is impressive only on paper, not by trial. The mathematics governing the protocols used in OpenVPN, for the most part, have withstood the tests of time and scrutiny. WireGuard has simply not had the same opportunity to prove itself, because not only is it younger, but so to are the mathematics behind its cryptographic primitives. In addition, while initially only theorized but later confirmed, there have been instances where deliberate attempts to standardize the undermined security of ECC have been successful (the kleptographicbackdoor in Dual_EC_DRBG, or Dual Elliptic Curve Deterministic Random Bit Generator, comes to mind).
In short, WireGuard is on par with OpenVPN only in theory, not in practice. Time will ultimately determine whether theory survives implementation through experimentation, as is the case with all valid scientific inquiry. Should it survive time and scrutiny, it is plausible that when combined with its efficiency and performant design, it will see more widespread adoption than OpenVPN.
Networking
WireGuard is only offered in UDP and does not maintain any built-in anti-censorship capabilities. In most environments, this will not be an issue. In some environments, especially those which are subjected to extensive monitoring or controlled traffic filtering systems, WireGuard is typically easily identifiable and is thus susceptible to being blocked by policy. In these types of pro-censorship environments, WireGuard may not be suitable in comparison to TLS VPNs operating over TCP, like OpenVPN.
It has been announced that obfuscation techniques may be implemented into WireGuard to improve its resistance to censorship, but this has not yet occurred. The closest example would be Proton VPN’s Stealth protocol, which is essentially WireGuard over TLS.
Compatibility
Fortunately, WireGuard was designed with extensibility in mind, including for implementation in third-party programs and scripts. It uses an even more simplified configuration file than OpenVPN, and has been supported by many router firmware packages.
Implementations of the WireGuard protocol include availability in C, Go, Rust and others targeting many different environments such as OpenBSD, NetBSD, OPNsense, pfSense and there is even an implementation provided by Mikrotik for all modern routers.
The aforementioned compatibilities of OpenVPN and WireGuard - specifically, their support of common router firmware - include support for Asuswrt, the firmware installed by default on ASUS routers. The ASUS brand is a popular choice for consumers in the computer, phone, network equipment, and electronics hardware space to name only a few. ASUS is recognized for its premium quality and especially its development of intuitive user interface design to support its varied products (examples include BIOS and router admin panels).
Asuswrt is originally based on Tomato (Tomato-RT/Tomato-USB) but has been modified so extensively by ASUS over the years as they added their own features to it that it ultimately needed its own name. ASUS first used Asuswrt on the RT-N66U Dark Knight (2011), but they migrated some of their previous models over to it as well, including the DSL-N55 and RT-N56.
Falling under the GPL license, almost all the source code and necessary build tools for Asuswrt are available directly from the ASUS website. Aside from some of the proprietary drivers (i.e. Broadcom and Ralink), it is therefore possible to recompile a working firmware from source, opening the door to derivative projects. ASUS designed Asuswrt as a unified firmware, which means that only one central codebase is maintained to support all of their routers.
Asuswrt-Merlin
For most consumers, the features provided by Asuswrt are more than enough to configure secure and well-performing home network settings. For consumers seeking additional customization, robust forks like Asuswrt-Merlin (sometimes called MerlinWRT) seek to improve upon the original Asuswrt (and yes, there are even forks of forks). Asuswrt-Merlin is a prominent downstream project of Asuswrt and offers improvements over the original including performance optimizations, scheduled tasks with Cron, monitoring with SNMP, support for third-party software, and varied security updates and bug fixes (for a complete list, click here).
In terms of relevancy to this post, Asuswrt-Merlin provides functionality for user scripts on its /jffs/scripts/ partition. Usage is documented thoroughly on the project’s wiki, available at RMerl/asuswrt-merlin.ng on GitHub (see the User-scripts section). The importance of the ability to run scripts on a home router for basic automation purposes cannot be emphasized enough by any system or network administrator worth their own salt; it simply opens up too many capabilities, all of which would have been previously impossible with Asuswrt alone.
Installation of Asuswrt-Merlin is not technically out of scope for this post, but rather than rewriting the process here, I recommend following the instructions provided on the project’s wiki. Flashing Asuswrt-Merlin to an ASUS router is essentially comparable to flashing Asuswrt, as the consumer normally would, in the admin panel (one caveat being the dependency of Asuswrt 380.61 or newer before flashing Asuswrt-Merlin). Once installed, and once all normal settings are configured to the user’s liking (wireless, LAN, DHCP, DNS, WAN, NAT, firewall etc.), the user is ready to begin configuration of the router’s VPN settings.
VPN Settings
Recall that the home router will be configured as a VPN client, not a VPN server. The router, using Asuswrt-Merlin, can be set up as a VPN server, but this guide is focused around configuring it as a client. This way, all LAN traffic will egress to the WAN through the VPN tunnel(s) between the router and the VPN server, taking the burden away from having to set up OpenVPN (or WireGuard) connectivity on each device on the LAN.
To make things easier, I recommend configuring DHCP reservations in Advanced Settings > LAN > DHCP Server, which are essentially layer 2 to layer 3 (MAC to IPv4) mappings comparable to static IPs. This step is not required, but it can be useful for configuring specific VPN rules for specific LAN devices in following steps, if this functionality is desired.
OpenVPN Clients
In Advanced Settings > VPN > VPN Client, Asuswrt-Merlin provides three sub-tabs for OpenVPN, PPTP/L2TP, and WireGuard (PPTP/L2TP will be completely ignored in this post). Each type provides up to 5 client instances, meaning that 10 VPN connections can be configured between OpenVPN and WireGuard. To configure an OpenVPN client instance, click Choose File and upload the .ovpn file provided by Proton VPN (or other VPN provider).
For the example below, I have configured ch-us-01.protonvpn.net.udp.ovpn with Asuswrt-Merlin (Proton VPN Secure Core UDP connectivity out of Switzerland), which uses the following settings (notice that some settings have already been extensively mentioned above):
client
dev tun
proto udp
server-poll-timeout 20
remote-random
resolv-retry infinite
nobind
cipher AES-256-GCM
auth SHA512
verb 3
setenv CLIENT_CERT 0
tun-mtu 1500
tun-mtu-extra 32
mssfix 1450
persist-key
persist-tun
reneg-sec 0
remote-cert-tls server
auth-user-pass
pull
fast-io
The .ovpn file may contain multiple remote <ip> <port> lines in it. From the image, it appears at first glance that Asuswrt-Merlin allows the entry of only one IP and port, but this is actually not true. At the very bottom of the page, there is a section header Custom Configuration where the user can put as many remote <ip> <port> entries that they want (simply copy all of these lines from the .ovpn file and paste them in this field). The Address: and Port: fields above can be filled with any of these from the file.
WireGuard Clients
Configuration of WireGuard client instances in Asuswrt-Merlin is just as simple when working with Proton VPN. WireGuard client files (.conf) are arguably less complex than OpenVPN. For example, the following settings are provided in wg-CH-US-1.conf, the WireGuard equivalent of ch-us-01.protonvpn.net.udp.ovpn:
Test VPN client settings by setting Service state to ON for OpenVPN or Enable WireGuard to Yes for WireGuard. Then navigate to Advanced Settings > VPN > VPN Status to check the status of each enabled client. Asuswrt-Merlin will show live statistics (IP addresses, TUN/TAP and TCP/UDP read bytes, etc.) for each active tunnel.
VPN Director
Finally navigate to Advanced Settings > VPN > VPN Director, which is, by far, the most powerful tool available for configuration in Asuswrt-Merlin’s VPN settings. It is on this panel where the firmware allows the administrator to direct LAN traffic through specific VPN tunnels, assuming that the tunnels are active. Asuswrt-Merlin prioritizes rules in the following order:
Rules with WAN destinations
Rules with OpenVPN[1-5] destinations
Rules with WireGuard[1-5] destinations
CIDR notation is supported in this policy. This means that the entire LAN address space in the router’s DHCP server (e.g. 192.168.1.0/24) can be assigned to a specific tunnel or multiple tunnels, which will be chosen based on the above ordered priority. Likewise, specific internal IP addresses can be assigned to specific tunnels or multiple tunnels. For example, if an administrator only wants to use the 5 WireGuard connections for their entire LAN, the rule set would look like the following (if WGC1 goes down, traffic will egress via WGC2 and so on):
This same principle can be applied to the OpenVPN instances as well (naming scheme OVPN#). OVPN# interfaces will take priority over WGC#, and both are bypassed by WAN rules. This can be useful if there are specific systems on the LAN which need to bypass VPN connectivity. Asuswrt-Merlin supports a maximum of 199 VPN Director rules.
My personal recommendation is to configure all 10 tunnel instances and activate those which are desired. In my specific use case, I activate 5 OpenVPN tunnels and 5 WireGuard tunnels. The OpenVPN tunnels take priority over the WireGuard tunnels, which means that all OpenVPN tunnels would need to go down before WireGuard takes over.
It is somewhat important to note that some NAT configuration for port forwarding in VPN Director becomes required if the VPN Director policy is configured in Asuswrt-Merlin, assuming that the administrator needs any ports opened to the WAN. This is not immediately apparent given that NAT configuration is performed in the Advanced Settings > WAN > Virtual Server / Port Forwarding panel. In VPN Director, these are essentially just WAN bypasses to specific remote IP addresses, as described above and shown here:
This rule, for example, would enable connectivity between private IP address 192.168.1.3 and a configured external IP address over the WAN interface only for that specific external IP address. All other traffic from 192.168.1.3 would egress over a VPN interface if a rule to do so is configured in VPN Director. Essentially, this is just like using split tunneling, except only to allow inbound NAT policy from the WAN interface.
If VPN Director rules are applied to OVPN# and WGC#, but no VPN tunnels are active, traffic will egress through the WAN interface by default given no alternative. Naturally, this is problematic for the privacy-conscious technology enthusiasts; if all the tunnels go down, the traffic is no longer encapsulated away from the prying eyes that we all seek to keep blind.
Watchdog Script
The solution to this problem is some basic automation. As aforementioned, Asuswrt-Merlin provides user script functionality on its own dedicated partition. To enable /jffs/scripts/, navigate to Advanced Settings > Administration > System > Persistent JFFS2 partition and set Format JFFS partition at next boot to Yes and Enable JFFS custom scripts and configs to Yes (after one reboot, set the former of these to No).
SSH will also need to be enabled, at least to the LAN. Setting up SSH keys is out of scope for this post but is highly encouraged, even if accessible only to the LAN. Once SSH is enabled, the administrator will need to login to the router over SSH (or SFTP) and navigate to /jffs/scripts/. I personally recommend PuTTY (or MTPuTTY) or FileZilla.
As noted in the User-scripts section on the wiki, Asuswrt-Merlin “expects” the presence of specifically named scripts in /jffs/scripts/ the user must provide (if desired), which are executed when certain events occur. For this post, services-start is the most relevant of these events as it executes when the router is powered on and boots up.
Given that the purpose of a watchdog script is to detect and recover from unexpected malfunctions, services-start can be used to call and background such a script to automate the stability of VPN connectivity between the router and the VPN server. Without this watchdog script, it is possible for tunnels to terminate unexpectedly or become hung up in a faulted state, or worse yet, fail to recover entirely. Remember, with VPN Director rules, if no tunnels are active, the traffic will egress through the WAN interface.
Using any text editor (vim, nano, Notepad, etc.), services-start should contain the following and be placed in /jffs/scripts/:
Be sure to make services-start executable with the following command:
chmod +x services-start
Since services-start now expects the presence of merlin-ovpn-client-watchdog-vpn-director.sh, using any text editor, this file should contain the following:
#!/bin/bash#set -xINTERVAL=60
PING_HOST="1.1.1.1"PING_INTERVAL=10
PING_MAXTRY=3
_get_date_time(){echo"$(date'+%m-%d-%Y-%H-%M-%S')"}
_log(){local base="$(basename$0 .sh)"echo"[$(_get_date_time):$base] $1" | tee-a"/jffs/scripts/$base.log"}
_ping(){[[$PING_MAXTRY-gt 0 ]]||return 0
local i=1
while :;do
ping -qc1-W3-I"$1""$PING_HOST" &>/dev/null &&return 0
[[$(( i++ ))-ge$PING_MAXTRY]]&&break||sleep$PING_INTERVALdone
return 1
}until ping -qc1-W3"$PING_HOST" &>/dev/null;do sleep 10;done
while sleep$INTERVAL;do
for i in 1 2 3 4 5;do
if[["$(nvram get "vpn_client${i}_state")"=="0"]];then
continue
fi
pidof "vpnclient${i}" &>/dev/null && _ping "tun1${i}"&&continue
service "restart_vpnclient${i}">/dev/null
_log "openvpn client #${i} restarted"done
done
Be sure to make merlin-ovpn-client-watchdog-vpn-director.sh executable as well:
_get_date_time() returns a timestamp for logging purposes
_log() logs output to the same relative directory
_ping() pings a specified host and returns failure/success status
until ping -qc1 -W3 "$PING_HOST" &>/dev/null; do sleep 10; done
verifies WAN connectivity before proceeding to verify VPN connectivity
while sleep $INTERVAL; do loop
verifies VPN connectivity for all 5 OpenVPN interfaces
only for those with their state enabled
This script verifies WAN connectivity (i.e. thru ISP), and only then proceeds to start verifying VPN interface connectivity for all 5 OpenVPN interfaces, but only for those interfaces with their service states enabled. If the script sees a valid process ID for the OpenVPN client it is verifying, and it can ping across the tunnel associated with that process ID, it moves on to check the next state enabled interface. If either check fails (missing pid or unsuccessful ping), the script restarts that VPN client and logs that it did so to a file.
The provided parameters are configurable.
INTERVAL=60
verify all state enabled OpenVPN interfaces every 60 seconds
PING_HOST="1.1.1.1"
reliable external host or IP addresses which should always reply to ICMP
PING_INTERVAL=10
time between pings
PING_MAXTRY=3
max number of times to try pinging
The original credit for this script goes to @eibgrad on the SNBForums website, where I discovered a post on the topic of automating VPN tunnel recovery on Asuswrt-Merlin. Like @eibgrad, I too was surprised that this functionality is not already supported natively in the Asuswrt-Merlin firmware. I have since modified the original script to what is pasted above, but for reference, the original is available on Pastebin and pasted below.
#!/bin/sh#DEBUG= # uncomment/comment to enable/disable debug mode# name: merlin-ovpn-client-watchdog.sh# version: 3.0.1, 05-aug-2022, by eibgrad# purpose: restart failed/stopped/unresponsive openvpn clients# type(s): services-start# href: https://tinyurl.com/2p9a68ne# installation:# 1. enable jffs custom scripts and configs (administration->system)# 2. ssh to router and copy/paste the following command:# curl -kLs bit.ly/merlin-installer|tr -d '\r'|sh -s wyKu0pww# 3. modify script w/ your preferred options using nano editor:# nano /jffs/scripts/merlin-ovpn-client-watchdog.sh# 4. rebootSCRIPTS_DIR='/jffs/scripts'SCRIPT1="$SCRIPTS_DIR/merlin-ovpn-client-watchdog.sh"SCRIPT2="$SCRIPTS_DIR/services-start"mkdir-p$SCRIPTS_DIR# -------------------- begin merlin-ovpn-client-watchdog --------------------- #cat<<'EOF' > $SCRIPT1
#!/bin/sh
#set -x # comment/uncomment to disable/enable debug mode
{
# ------------------------------ BEGIN OPTIONS ------------------------------- #
# time (in secs) between checks for failed/stopped/unresponsive openvpn clients
INTERVAL=60
# internet host used for ping checks
PING_HOST='8.8.8.8'
# time (in secs) between ping checks
PING_INTERVAL=10
# maxmium number of ping checks before being considered a failure
PING_MAXTRY=3 # (3 recommended, 0 disables ping checks)
# ------------------------------- END OPTIONS -------------------------------- #
# ---------------------- DO NOT CHANGE BELOW THIS LINE ----------------------- #
# function _ping( vpn-network-interface )
_ping() {
[ $PING_MAXTRY -gt 0 ] || return 0
local i=1
# it's best to check multiple times to prevent false negatives
while :; do
ping -qc1 -W3 -I $1$PING_HOST &>/dev/null && return 0
[ $(( i++ )) -ge $PING_MAXTRY ] && break || sleep $PING_INTERVAL
done
return 1
}
# wait for *reliable* internet connection
until ping -qc1 -W3 $PING_HOST &>/dev/null; do sleep 10; done
while sleep $INTERVAL; do
for i in 1 2 3 4 5; do
# only enabled openvpn clients need to be considered
[ "$(nvram get vpn_client${i}_state)" != '0' ] || continue
# check for failed connection or unresponsive tunnel
pidof vpnclient${i} &>/dev/null && _ping tun1${i} && continue
# fall-through means failure; restart the openvpn client
service restart_vpnclient${i} >/dev/null
echo "openvpn client #$i (re)started @ $(date)"
done
done
} 2>&1 | logger -t $(basename$0 .sh)[$$]
EOF
[${DEBUG+x}]&&sed-ri'2 s/^#(set -x)/\1/'$SCRIPT1chmod +x $SCRIPT1echo"installed: $SCRIPT1"# --------------------- end merlin-ovpn-client-watchdog ---------------------- ## --------------------------- begin services-start --------------------------- #
create_script(){cat<<'EOF' > $SCRIPT2
#!/bin/sh
#set -x # comment/uncomment to disable/enable debug mode
{
nohup $SCRIPT1 &>/dev/null &
} 2>&1 | logger -t $(basename$0)[$$]
EOF
[${DEBUG+x}]&&sed-ri'2 s/^#(set -x)/\1/'$SCRIPT2sed"s:\$SCRIPT1:$SCRIPT1:g"-i$SCRIPT2chmod +x $SCRIPT2}if[-f$SCRIPT2];then
echo"error: $SCRIPT2 already exists; requires manual installation"else
create_script
echo"installed: $SCRIPT2"fi# ---------------------------- end services-start ---------------------------- #
To demonstrate how frequently OpenVPN client tunnels may need to be restarted - or, at least, how often my watchdog script decides to restart them - the following is an excerpt from my log file between 6/1/23 and 7/31/23:
37 restart events for 2 tunnels spanning a time of 2 months is, roughly, just over 1 malfunction per day. To me, this shows just how critical it is to implement an automated solution to maintain secure and private connectivity through the VPN. This means that the watchdog script detected faulted tunnel clients and restarted them, whether that was due to a missing pid or no reply from ICMP, or for VPN provider related issues such as the forced AUTH FAIL error.
Fortunately, WireGuard clients do not have this problem, and it is for this reason and the caveats noted above that I opted to configure a total of 10 tunnel interfaces between OpenVPN and WireGuard in my own home router. The 5 OpenVPN clients are “watchdogged” with merlin-ovpn-client-watchdog-vpn-director.sh and the 5 WireGuard clients sit ready to take over, in number order, if all of the enabled OpenVPN clients manage to go down simultaneously.
VPN Fail Safe
One final and very relevant footnote here would involve setting up a “fail safe” VPN client connection which is either completely separate from the VPN provider of the others configured, or at the very least, is a different region than of the others configured. It is always possible that VPN providers experience an outage. Therefore, if all the configured clients in Asuswrt-Merlin rely upon one VPN provider (or region), connectivity may pass through directly to the WAN.
Mullvad is an excellent secondary option to configure as a backup VPN connection. To configure Mullvad OpenVPN clients in Asuswrt-Merlin, be sure to refer to the guide provided by Mullvad. Specifically, in your .ovpn files from Mullvad, be sure to modify the following lines:
proto udp
tun-ipv6
To the following:
proto udp4
pull-filter ignore "route-ipv6"
pull-filter ignore "ifconfig-ipv6"
comp-lzo no
Privacy-Enhancing Technology
Following is a list of technology I personally trust to maintain a certain degree of freedom in the modern digital age. Please feel free to reach out to me with any questions about any of these and why I decided to trust them vs. their competitors. For a comprehensive list of other notable privacy tools, I recommend visiting privacytools.io, or its newer version, privacyguides.org.
iptables (UFW) - IP packet filter chain rules for the Linux kernel
pg2ipset - native solution to firewall PG2 IP blocklists
PeerBlock - blocks packets to and from a maintained list of blacklisted hosts
Supports filtering for anti-P2P orgs, spyware and adware servers, advertising and data trackers, and educational institutions
Blocks 949,620,888 IPs as of the date and time of this post (this is approx. 25.6% - one fourth (!!!) - of the entire public 32-bit IPv4 address space)
Frontends
FreeTube - alternative YouTube frontend to block ads, sponsorships, and promotions
Free, open-source, anonymized communication supporting onion routing
This site operates its own v3 hidden service, check it out!
Web Browser Extensions (except with Tor):
Adblock - block ads and pop-ups on YouTube, Facebook, Twitch, etc.
Adblock Plus - block YouTube ads, pop-ups and fight malware
Decentraleyes - block free and centralized content delivery
SponsorBlock - skip sponsor segments in YouTube videos
uBlock Origin - wide-spectrum content blocker with CPU and memory efficiency
Changelog
Update: Feb 25, 2025 (DNS)
In the “OpenVPN Clients” and “WireGuard Clients” sections above, I made no mention of DNS settings. If something like Pi-hole is being used for DNS, make sure to set Accept DNS Configuration for OpenVPN clients to Disabled and DNS Server (Optional) for WireGuard clients to a blank field to avoid using the VPN’s DNS servers. More information on this can be read here. Otherwise, I recommend the Exclusive setting for OpenVPN and leaving the WireGuard setting default.