What's new

Tutorial [Solved] Setup for Bi-directional VPN with WRT-based Routers (e.g. ASUS)

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!


Occasional Visitor
Part 1: Context and Goal

In early 2019, Ed B. posted his Ultimate Guide to setting up a bi-directional VPN using ASUS routers. He did a fantastically thorough job describing what he did. Most of it is right, and you should use his post as a place to get started. Unfortunately, he got a critical OpenVPN setting wrong in a way that creates a serious security hole. And even more unfortunately, his solution only works because of that security hole. This stuff is hard, and I'm really impressed with Ed's effort. After playing with it for a good chunk of today I was able to get a solution running that actually works. The solution here should work for any router running WRT, but I can't speak to how the user interfaces on other routers may look. I got it working on recent ASUS WIFI routers (RT-AC3100 and RT-AC5300). I don't have any of the VPN fusion devices, so I cannot test that.

Let's start by describing what we're trying to accomplish in our case. We have four "sites" that we want to interconnect:
  • Site A: Our main facility. This will act as our "hub."
  • Site B: Our administrative offices
  • Site C: the home of one of our developers
  • Site D: a private Kubernetes cluster running at a cloud-based cluster provider. This part isn't solved by what I'm going to write here - we're still working on it.
The goal is to have all of the IP addresses at this location behave as if they were on a unified internal net. We want the routers at the client sites to route packets onto their site networks, and we want the hub router to forward packets back and forth between the connected client sites and the main site as needed.

In addition, we have a number of people who connect in from individual machines using OpenVPN client software. Once connected over OpenVPN, we want these machines to be able to reach any machine on any site, but we do not want these individual hosts spreading VPN packets on to their local networks. Extending the VPN into a random coffee shop sort of defeats the purpose of the VPN.

We want all connections to be using a client-side certificate (the one in their .ovpn file).

Bonus: We want a way to retire old certificates in a phased way, so that we can set up a new certificate configuration, migrate the client node, and then discard the old one.

Bonus: if we want to, the approach described here will let us assign different certificates to each of the dial-up users, which allows us to retire those certificates promptly when someone who has access decides to take a different job.

Bonus: It appears that this approach can be extended. If we end up with two many client simultaneous connections to our main facility router, it looks like we can use the second site as an alternative if we are willing to fiddle with the route push configurations. Since we haven't had a need for it, I haven't looked in to that. Honestly, if we hit the point where we need to support that many simultaneous client connections, it's time to go for a business-grade VPN solution.

The key to all of this is that we're going to generate distinct client certificates for each of the sites. That's the piece that Ed B. didn't do. It's why he couldn't get the site-to-site mode working without setting "Username/Password Auth Only" to "yes'. When this is done, OpenVPN "fakes" some information that it would normally get from the client certificate, which is why he was able to set up a site-to-site configuration with this enabled. Unfortunately, when Ed set that to yes, he unintentionally bypassed a key part of the OpenVPN connection security handshake.

The bad news is that the WRT interface doesn't provide a way to generate individual client certificates. The good news is that all of the tools you need to do it are sitting on the router, and it this isn't that hard if you know how to drive a text editor.

A bunch of people were trying to solve this with iptables, but it's actually an OpenVPN issue. The necessary facts are documented (after a fashion) on the OpenVPN site, but putting them together to know what to do, and then figuring out how to do them on the darned router took some doing.
Last edited:
  • Like
Reactions: Sky
Part 2: Subnets and Site-to-Site

The configuration I have described is eventually going to involve five subnets. We have a fair number of machines around, so I chose to organize our internal network using the 10.x.x.x IP address range:
  • Developer home:
  • Main site:
  • Administrative site:
  • Private kubernetes cluster:
  • VPN subnet on main site:
  • [Future] VPN subnet on admin site:
For the moment, each subnet uses a Class C network mask (126 machines). As people walk around with more and more network connected devices (cell phones, tablets, etc), that isn't very much. We chose the IP address ranges to allow us to expand each of the major sites to as many as 65,534 machines.

On the VPN subnets we don't need a huge number of IPs. At the main site (master) router, each client router will get one IP for a site-to-site connection, and each individual connection from home will need an IP. Each of those is an encrypted link; the truth is that the ASUS WIFI devices can't handle 100+ simultaneous connections in any case.

The unknown here is the private kubernetes cluster. When we set that up, we may find that it has IP address requirements that we haven't considered. The provider prefers an IPSEC VPN, which we don't currently know how to do. The good news there is that all of the current subnets are "low" in the IP address range - we have a big block from 10.9.x.x to 10.255.255.x to work with. For that matter, we can move the VPN subnets pretty easily; the only components that knows those IP ranges is the OpenVPN server itself on the main site's router. So we have some room to work, but we'll probably have to revise this at some point.

At the main site (the one all of the clients will connect to), in the advanced OpenVPN Server settings, we're going to turn Username/Password Auth. Only off, and we're going to turn both Manage Client-Specific Options and Allow Client <-> Client on. I'll talk at the bottom of these notes about Allow only specified clients. There are pros and cons with that one. In our case, the VPN Subnet/Netmask on the main server is set to I prefer AES-256-CBC for the encryption cipher and SHA-512 for HMAC Authentication. You also want to set Push LAN to clients to yes.

Now about that list of Allowed Clients.....

The tip-off that this was an OpenVPN problem was the Common Name (CN) column in that table. A lot of people believe, mistakenly, that this is the same as the Username you set up when you entered the client's login information on the General tab for the VPN server. It isn't, and that's why Ed. B ran into trouble. The "CN" here stands for "Common Name". It refers to a component of the "subject" field of the client certificate. To make this work, you need to generate a client certificate with a different common name for each site, and you need to get it signed by the certificate authority on the OpenVPN server.

The good news:
  • All of the information you need to do this is present on the router.
  • The openvpn command line tools that will do it for you are present on the router.
The bad news:
  • There is no way to generate the certificate you need using the WRT GUI.
  • You're going to have to learn how to use ssh to log in to the router.
  • You'll need to log in to the router and run some linux commands.
If you are on a modern linux or MacOS machine, you already have ssh installed. If you are on Windows, and you haven't already done so, you will need to enable the Windows 10 SSH Client. For what we are doing, you do not need the ssh server on your Windows machine. Every server that accepts outside connections is a potential security risk, so if you don't need it, don't turn the ssh server on.

If you don't already have one, you will need to generate an RSA key for ssh. Documentation for how to do this is a little thin on windows. The command you want is ssh-keygen -t rsa. Generate a key if you need to, go over to the Administration section of the WRT GUI, select the System tab, and turn Enable SSH on for LAN only. Enable password login, add the public portion of your ssh key to the Authorized Keys list, and click the "apply" button. If your WIFI router is stubborn, you may need to reboot the WIFI router before you can log in.

Assuming you are coming from the LAN side of the router, you can now log in from a command window using slogin admin@routerIP. You'll be prompted for a password. Use the password that you configured on the router for the admin acount.
  • Like
Reactions: Sky
Part 3: Details on Client Certificates

The next step - actually, the thing we've been working up to all along - will be to create individual client certificates for the sites you want to connect. Or strictly speaking, for the boundary routers associated with those sites. The requirements are:
  • Each of these certificates needs to have a different CN (Common Name) value in its certificates
  • Certain X501v3 extension fields need to be defined
  • The certificate used on the client must be signed by the CA (Certificate Authority) on the server.
Before we do that, I want to describe what we're after and where to find the pieces you will need.

Before I forget, this is a really good time to get into the WRT GUI and export a client certificate. If you're already using one successfully, that will do. It's also a good moment to create a folder or directory to work in so that you can clean up later. On my laptop, I put everything into a folder called webcerts.

We want a copy of it because once we generate the certificate we want we're going to edit that .ovpn file to put the new certificate in it. If you are on a platform that has openvpn installed, you can get a look at what we're after in the certificate as follows:
  1. Open the .ovpn file in your favorite text editor.
  2. Find the part that starts with -----BEGIN CERTIFICATE----- Extract everything from there to the END CERTIFICATE line (including the hyphens) into a separate file with a "crt" extension. I called mine good-client.crt.
  3. Run the openssl dump command: openssl xf09 -in good-client.crt -noout -test.
If you got all that right, you'll get output that looks something like this:

shap@ShapSpectre:/mnt/c/Users/shap/webcerts$ openssl x509 -in good-client.crt -noout -text
        Version: 3 (0x2)
        Serial Number: 2 (0x2)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C = TW, ST = TW, L = Taipei, O = ASUS, CN = RT-AC3100, emailAddress = me@myhost.mydomain
            Not Before: Jan 11 19:14:32 2020 GMT
            Not After : Jan  8 19:14:32 2030 GMT
        Subject: C = TW, ST = TW, L = Taipei, O = ASUS, CN = client, emailAddress = me@myhost.mydomain
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (1024 bit)
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
            Netscape Comment:
                Easy-RSA Generated Certificate
            X509v3 Subject Key Identifier:
            X509v3 Authority Key Identifier:

            X509v3 Extended Key Usage:
                TLS Web Client Authentication
            X509v3 Key Usage:
                Digital Signature
    Signature Algorithm: sha1WithRSAEncryption

About six lines down, you'll see a line that starts with "Subject:". We're going to generate a unique key for a new cert, but the key thing is that we're going to update the CN value in the subject. And yeah, you can see that when I ran my experiments I was still using a 1024 bit RSA key. These days that's too short.

Incidentally, the other parts of the subject can be changed as well. ASUS generates a self-signed CA (certificate authority) when you turn OpenVPN on. You can see the values they used in the "Issuer" field. Our certificate needs to be signed by this issuer (that is, by the CA), but it doesn't need to have the same values for country, state, and so forth if you don't want it to.

At this point, you're going to need to log in to the router using ssh and run some linux commands. Two things to say here:
  1. The router already knows how to do everything we're about to do, because it did these steps to generate the original (anonymous) client certificate. The script to do it is in there, and it's a darned shame they haven't bothered to expose a web UI for it. That said, I'm not sure that I actually found the right script. I decided not to take a chance and did some of this by hand.
  2. If you already know how X.509 certificates work, it's totally possible to extract the CA cert and key and the router's openssl.cnf file and do everything we are about to do someplace else. There are certificate management tools on Windows that can do all of this too, but I don't know them. Maybe somebody can add a post about those. Alternatively, you could enable WSL v2 (Windows Subsystem for Linux), install a copy of Ubuntu, add the openssl package, and do things that way.
From this point I'm going to show commands that you need to run on the router itseld. I'm assuming that you have already logged in to the master router (the one running the OpenVPN server) using slogin to do these steps.

Some of the ASUS routers can run more than one OpenVPN server at a time, so before we actually generate the certificate, we need to figure out where the CA certificate and key are for our server. Let's make a safe place to work and then list the choices:

# Create a scratch directory for our work:
mkdir /tmp/NewCerts

# List the available server directories:
ls /etc/openvpn
ovpn-down@     ovpn-route-up@ ovpn-up@       server1/       vpnclient5@    vpnserver1@

That one that reads server1 is the directory containing the files we need. In particular, it contains the certificate and key for the self-signed CA (certificate authority) that this server is using. If you have more than one server directory, and you aren't sure which one you need, one option is to see what is connected (perhaps you might connect from your laptop first):

cat /etc/openvpn/server1/client_status

This will list the currently connected clients. You can compare this list to the list shown in the GUI to figure out which server is which. On the routers that support multiple OpenVPN servers I'm sure there is a more direct way to do this, but I don't have one to check. If somebody can figure it out by listing these directories, I'd be glad to update this chunk of the thread.

OK. Now you have the server directory. If you list the directory, you'll find the CA files that we need:
ls /etc/openvpn/server1
ca.crt         ccd            client_status  dh.pem         server.crt     status
ca.key         client.ovpn    config.ovpn    fw.sh          server.key

You wont have the ccd/ directory if you haven't set up individual parameters for your client routers (which we haven't done yet). In the next step, we'll create the client certificate, but a brief word about legal CN values may be helpful so that you can plan.

Legal Values for CN

X.509 places very few restrictions on characters in a CN field. They have to be printable, and they can only be 64 characters long. ASUS WRT limits this to 26 characters. Hypothetically, you can use UTF-8 characters, but there are some RFCs that mandate lowercase comparisons. The standard says that the only meaningful comparisons on these field values is equality comparison, but it also says that these have to be done by a case-insensitive comparisons on these fields, and you can reliably bet that most of the low-end routers out there are not lugging the full Unicode algorithm set for converting to lower case. You can also safely bet that the router software won't be running a validity check on this stuff, because it's an obscure feature. Also a good idea to avoid:
  • : because various software out there will probably stick these things in UNIX-style text databases where fields are separated by :
  • / because the openssl tools that create the distinguished name for the subject use / as a field separator.
My advice is not to test the boundaries. We know that domain names and IP addresses are commonly stuck in these fields, so stick to things that look like a legal domain name or domain name constituent.

The reason I mention all this is that you are not restricted to legal user names in the CN field. This means that you can add things that tell you later what you are looking at. The following are legal CN values:
  • site.mainoffice
  • user.fred
Unfortunately, it doesn't look like these values are accepted by WRT. I ended up reverting to using CN values that matched the usernames I had set up for each site.
Last edited:
  • Like
Reactions: Sky
Part 4: Generating the Client Certificate and Key

Before we do this step, we need to create a small auxiliary file that has the values WRT wants to see in the client certificate for the X.509v3 extension fields. I confess that I have no idea if these are actually necessary. The "stock" client certificate has them, and I'm just matching that result. I do know that the certs I am creating here actually work, so that's something.

# Put this file in the scratch directory:
cd /tmp/NewCert
cat - > ext.cnf
nsComment                      = "Easy-RSA Generated Server Certificate"
keyUsage = digitalSignature
When you have hit ENTER on that last line, send a CTRL-D to end your input. Just one, please ("One ping only, please, Vasily" -Sean Connery).

So with all that long-winded stuff out of the way, let's generate the client-specific certificate. The first step creates the certificate and a signing request. The second step uses the certificate authority for your server to sign the certificate. On my router, server1 is the directory for the OpenVPN server configuration, but if your router has multiple VPNS you'll need to substitute the correct directory name. Once again, you need to be logged in to the router:

# Do this in the scratch directory!
cd /tmp/NewCert

# Generate the new client certificate and signing request. Use rsa:1024 or rsa:2048 according to how you
# configured the RSA Encryption setting in your router. Hint: USE 2048!!! Also, make sure to use -sha256
# or -sha512 according to which way you set up your HMAC settings on the OpenVPN server
# You'll note here that the only value I updated in the subject field is the CN value. You should feel free
# to update the others.
openssl req -newkey rsa:2048 -sha512 -nodes -out adminoffice.csr -keyout adminoffice.key -subj '/C=TW/ST=TW/L=Taipei/O=ASUS/CN=adminoffice/emailAddress=me@myhost.domain'

# Sign the key using the CA for your OpenVPN server. This is where you need to reference the ext.cnf file.
openssl x509 -in adminoffice.csr -out adminoffice.crt -req -days 3653 -sha1 -extfile ext.cnf  -CA /etc/openvpn/server1/ca.crt -CAkey /etc/openvpn/server1/ca.key -set_serial 02

You now have the certificate file and key file that you need. While you are here, you might as well generate the certificate and key pairs for any other sites you need. Once you have done so. Log out of the router, and go back the scratch directory on your local machine where you saved the "generic" version of the client certificate, and copy your files from the router to your local directory:

scp admin@ROUTER-IP:/tmp/NewCert/site."*" .

If you used the file names I gave above (you should use your own), you'll now have files adminoffice.crt (the client certificate), adminoffice.key (the client key), and adminoffice.csr (the certificate signing request - you can discard this one).

Good news: the hard part is over! Take a second to look at the crt and key files: more adminoffice.crt will work on linux, windows, and MacOS.

Copy your generic client OVPN file to a new file called adminoffice.ovpn. Open that file in your favorite text editor, which is of course VSCode;). Three more steps and you are done making the certificate:
  1. Replace the content of the <cert> section with the contents of adminoffice.crt. Preserve the BEGIN and END lines when you do.
  2. Replace the content of the <key> section with the contents of adminoffice.key. Preserve the BEGIN and END lines when you do.
  3. Save the file.
  4. You now have a valid, client-specific OVPN file. Go do something to celebrate.
After you celebrate, we'll tell the OpenVPN server about this and then install it on your client router. Since you don't want to mess that up, don't celebrate too hard just yet.
Last edited:
  • Like
Reactions: Sky
Part 5: Set Up the Server, Use the Client Certificate

OK. Finally the moment of truth. Go back to the advanced OpenVPN server settings.

On the OpenVPN Server

If you followed the instructions in my first post, you'll see a place to add individual clients at the bottom of the advanced settings page. Add your client site or sites as follows:
  • The client name must match the CN value that you put in the certificate.
  • The subnet and mask must match the values you set up for your LAN on the client-side router. What we're actually entering here is the routing rule that says "if the packet is trying to get to this IP, send it to this client."
Don't forget that you need to click on both the "+" button and the "Apply" button.

I have not yet played with the "push" setting, and I have it set to "yes". My guess is that "push" means to push the route for one site to the client routers at other sites. I'll have to experiment.

On the OpenVPN Client

Go to the OpenVPN client settings on the client router and add a new entry. There is no point discarding the old one until you have seen this work, and if you are doing all of these steps from home you might need a way back into the server without driving in to work. Add a new VPN profile, choose the OpenVPN tab, give it a descriptive name for the UI, and use your newly edited OVPN file.

This makes me realize that I skipped a step. For every client site, our main router has an OpenVPN user and password on the OpenVPN server. You may need to do that so that you have a username and password to use here when you set up the client connection.

Add your client connection and activate it. If all goes well, you'll get a connection at this point.

Final Steps

Once you see it all work, you may want to copy the working OVPN file back onto the router that is acting as the OpenVPN server. That way you'll have it if you ever need it.

If you copied the client key file or the CA key to your local machine while you were working on this, you'll want to delete them so that they don't get stolen. Same deal for the new OVPN files you made, since an OVPN file contains the client key.
  • Like
Reactions: Sky
Part 6: Other Things to Consider

Various idle thoughts along the way:

The OpenVPN server on WRT is happy to permit multiple connections using the same certificate. You may want to consider creating one more certificate with a CN name of "homeuser20201011", and use that one for all of your individual client host machines that might be roving. If somebody leaves your organization, you can simply create a homeuser20201012, enable it, and delete the old entry. If you have the Only Allow Specified Clients setting enabled, this will ensure that roving users need to have the current version of the certificate. It gives you a way to deal with leaks and/or terminations, and it also gives you a way to deal with updates when the client or the server certificate expire. If you decide to create these, add the certificates to the Allowed Clients list, but leave the subnet and mask fields blank. That way you won't push data out to whatever network the roaming happens to be sitting on.

For the site certificates, it's a little easier. OpenVPN checks expiration dates, so you'll still need to rotate those out on the clients when they expire. But the site-to-site routing check only relies on the value of CN. When the time comes that your site certificates are expiring, you can simply generate a new one (along with a new key), drop it in to a new OVPN file, and install it on the client router. If you manage to do this before the client certificate expires, you'll be able to test the new configuration before you're committed by switching back and forth with activate/deactivate on the client.

It doesn't look to me like OpenVPN is checking that the login name and the CN name are the same. Since you are issuing distinct certificates to each client router, you can probably let them all log in using the same login and password. Do be sure to generate that password as a long random string, and don't enable the Username/Password Auth. Only option - that will bypass the requirement for a client certificate.

Once I had all of this set up, I checked the client routers. It appears to me that the network routes for all of the sites end up getting configured on all of the client routers. I definitely need to test it, but it appears to me that we could allow roaming OpenVPN connections from individual laptops to the client sites, and those connections would end up having access to the entire cross-site network cloud.

At this point, I'll be switching my attention to figuring out whether we can somehow arrange an OpenVPN connection to our cloud cluster provider. That would be my preference, mainly because it's a lot easier than bringing up IPSEC, but I guess we'll see. If I have to do IPSEC, I'll try to remember to add a reply here describing what changes were needed on the OpenVPN server to get all of the routing to work.
  • Like
Reactions: Sky
In Closing

I really hope that this series of posts will be useful to others who have been trying to solve this problem. It's one of those topics that has been showing up on SNBForums for years, and I've been starting at these WIFI routers for a long time thinking there had to be a way. The need to deal with routing to a private cluster finally forced me to go in and clean things up.

Please don't hesitate to add questions or offer corrections. This was a lot to type, and I'm quite sure there are errors somewhere.

Your mission, should you choose to accept it, is to get this working for your business or home. Good luck, Jim.
  • Like
Reactions: Sky
Wow, great work, I understand this is a complex task to get VPN up and running between offices. After reading the start I don't know what settings should be left in the server and what in the client?
No list of parameters and their settings, nor pictures of the starting point. Setting changes are included in long sentences. Looks like this is going to take a loooooong time to get this up and running, not to talk about the amount of trips between the offices.
Wow, great work, I understand this is a complex task to get VPN up and running between offices. After reading the start I don't know what settings should be left in the server and what in the client?
No list of parameters and their settings, nor pictures of the starting point. Setting changes are included in long sentences. Looks like this is going to take a loooooong time to get this up and running, not to talk about the amount of trips between the offices.
One of the problems with some of the previous descriptions is that people weren't sure which settings mattered and which did not. They posted pictures, and then people were wondering which parts of the pictures were significant. I don't know, maybe (probably) this would be clearer with pictures. I'll see what I can do. The only real settings on the client are the usual ones you need when you install a client-side OVPN file. All of the interesting stuff here is happening on the server.

If you are using an OpenVPN client, it may be true that the client runs a newer version of OpenVPN than your router, and newer versions want different keywords in the OVPN file. OVPN files are just text files; you can open them in an editor to fix them. But this is completely separate from the issues around setting up a federated VPN.

As to time, the first connection took me several hours, but only because it wasn't coherently documented anywhere and I had to do lots and lots of forensics to figure this stuff out. Then there was more work to make sure I had it repeatable so that these posts would be correct. Once I had the first one done and repeatable, the next two took me about five minutes.

In regards to trips to the office, I got all of this working from my home, using a previous (simple, non-federated) OpenVPN setup. As long as you do not check the "Allow only specified clients" under advanced settings, your existing OpenVPN configuration will continue to work fine while you are getting this going. I did have the advantage that I had set the local LAN IP ranges up correctly back when we started, because I knew this was coming.

The mechanics of this really isn't that bad as long as you chose your LAN IP ranges ahead of time to avoid overlap. That's why we did each location as 10.<location number>.x.x. We also chose to start the location numbers from 0 and keep them close together so that we'll be able to allocate a large block when we federate to our private cloud. If your current local LAN IP numbers were not chosen in this sort of way, then yes, you may need to make changes at each location. Here's how to do that:
  1. Back up your current router configuration to a file, so that you have a quick way to recover. Never hurts to have the option.
  2. At each location, take note of your current DHCP lease time (that number is in seconds). It's not uncommon for these to be set to something like 24 hours (86400 seconds) out of the box.
  3. Change the DHCP lease time to something small, like 600 (a.k.a. 5 minutes). As your various clients and machines hit the ends of the leases they already have, they will re-acquire, and they will learn that the lease times are now shorter.
  4. Go home, grab a beer, and wait 86400 seconds for all of the machines at your location to learn about the shorter lease time.
  5. Very Important: If you have machines that are getting static IP addresses from your router, export the list to a file. When you change the LAN IP, the static IP allocations will not be updated, and you will need to update them by hand. When the time comes to do that, you'll really appreciate having a list of the machine names and MAC addresses handy.
  6. Wait until everyone else goes home, or you can afford to cut them off of the internet for ten minutes.
  7. Change the LAN IP range. Do this when you are physically present at the site, in case something goes wrong.
  8. Fix the static IP addresses that are being allocated by DHCP.
  9. Let 601 seconds pass (this is why you set the short DHCP lease timeout) before you tell everyone they can go back to work.
  10. Confirm that your laptop can still connect using OpenVPN.
  11. Raise the DHCP lease timeout if you choose to. For a small office or home, 600 seconds actually isn't a problem, so you may just want to leave it alone.
Murphy just loves it when people play with IP numbers. Expect that two or three machines will need to be physically rebooted because they don't know what to do when their IP number changes. You'll also discover that somebody installed a printer driver using the old IP number, and that printer needs to be deleted and re-installed.
  • Like
Reactions: Sky
Oh. I completely forgot to mention that dyndns is your friend. If you have that set up, you can change the IP number at the top of the OVPN file to the dyndns domain name of the router, which will save you the hassle of re-generating the certificates every time your ISP changes your WAN-side IP number. Just change the IP number in the line that starts with "remote" to the DNS name supplied by your dynamic DNS provider. Be careful not to change the port number (typically 1194).
  • Like
Reactions: Sky
God, impressive write up yet crazy complicated! Check out other ways such as Ananda Networks (https://www.ananda.net) to implement bi-directional or even full mesh VPN in about 5 minutes.
Assuming you don't mind releasing control of your VPN to a third party provider, and if you desire the higher-end options, you don't mind paying for it Ananda looks interesting.

Hi, I have a question regarding operations on the router file system via ssh:
When logging on I have noted that the file system when doing listings starts with tmp like in cd /tmp/NewCert
This became a red flag for me and before I start using the tutorial I want to know if this file system is actually just temporary such that if the router is power cycled it gets replaced by a new copy loaded from some obscure flash location?
In that case whatever work one does here will later be erased....

After logging on I see this:

admin@RT-AC86U:/tmp/home/root# ls -la /
drwxr-xr-x   21 admin    root          1840 Sep 11  2018 .
drwxr-xr-x   21 admin    root          1840 Sep 11  2018 ..
-rw-r--r--    1 admin    root             0 Sep 11  2018 .init_enable_core
drwxr-xr-x    2 admin    root          7856 Sep 11  2018 bin
drwxr-xr-x    4 admin    root             0 Jan  1  1970 bootfs
drwxr-xr-x    2 admin    root           160 Sep 11  2018 cifs1
drwxr-xr-x    2 admin    root           160 Sep 11  2018 cifs2
drwxr-xr-x    3 admin    root             0 Jan  1  1970 data
lrwxrwxrwx    1 admin    root            16 Sep 11  2018 debug -> sys/kernel/debug
drwxr-xr-x    6 admin    root             0 Jan 15 21:07 dev
lrwxrwxrwx    1 admin    root             7 Sep 11  2018 etc -> tmp/etc
lrwxrwxrwx    1 admin    root             8 Sep 11  2018 home -> tmp/home
drwxr-xr-x    8 admin    root             0 Jan 17 09:43 jffs
drwxr-xr-x    4 admin    root          4032 Sep 11  2018 lib
lrwxrwxrwx    1 admin    root             9 Sep 11  2018 media -> tmp/media
drwxr-xr-x    2 admin    root           160 Sep 11  2018 mmc
lrwxrwxrwx    1 admin    root             7 Sep 11  2018 mnt -> tmp/mnt
drwxr-xr-x    3 admin    root           800 Sep 11  2018 opt
dr-xr-xr-x  117 admin    root             0 Jan  1  1970 proc
drwxr-xr-x    6 admin    root          2488 Sep 11  2018 rom
lrwxrwxrwx    1 admin    root            13 Sep 11  2018 root -> tmp/home/root
drwxr-xr-x    2 admin    root         10728 Sep 11  2018 sbin
dr-xr-xr-x   12 admin    root             0 Jan  1  1970 sys
drwxr-xr-x    2 admin    root           160 Sep 11  2018 sysroot
drwxrwxrwx   15 admin    root             0 Jan 17 10:14 tmp
drwxr-xr-x   10 admin    root           816 Sep 11  2018 usr
drwxr-xr-x   17 admin    root             0 Jan 17 09:44 var
drwxr-xr-x   14 admin    root         22192 Sep 11  2018 www

# ls -la /etc/openvpn/server1/
drwx------    2 admin    root             0 Jan 15 21:07 .
drwx------    3 admin    root             0 Jan 15 21:07 ..
-rw-------    1 admin    root          1172 Jan 15 21:07 ca.crt
-rw-------    1 admin    root           912 Jan 15 21:07 ca.key
-rw-rw-rw-    1 admin    root          3561 Jan 15 21:07 client.ovpn
-rw-rw-rw-    1 admin    root          3561 Jan 15 21:07 client.ovpnr
-rw-rw-rw-    1 admin    root           546 Jan 15 21:07 config.ovpn
-rw-------    1 admin    root           830 Jan 15 21:07 dh.pem
-rwx------    1 admin    root           195 Jan 15 21:07 fw.sh
-rw-------    1 admin    root          1306 Jan 15 21:07 server.crt
-rw-------    1 admin    root           916 Jan 15 21:07 server.key
-rw-------    1 admin    root           436 Jan 17 10:18 status

Notice how several important locations are symlinked to /tmp!!!
/etc is actually on the tmp tree too, how can this work reliably?
Specifically the openvpn main directory where the configuration work is being done in subdir server1 is there!

How stable is the /tmp dir content?
God, impressive write up yet crazy complicated!
Just for completeness:
1) The complications are probably due to trying to forge the ASUS OpenVPN implementation into something it is not...
This VPN server is unable to issue more than one single unique certificate ovpn file so in essence it is using user/password combinations to authenticate all connections using the same exact ovpn file. Bad!

2) My issue with the tmp file system
Well apparently it is loaded in RAM on start and sometimes during operation the new/changed content is written back to flash memory by some kind of daemon. So it is semi-persistent. Not good anyway.

Finally, I have skipped the use of the ASUS router built-in *server*, it simply is too broken.
Instead I have used my own OpenVPN server running on a Linux Ubuntu server on my home LAN as the connection point for the remote ASUS router.
Using a standard OpenVPN installation makes it much easier to get this LAN <==>LAN connectivity working!
Here is a howto document at the OpenVPN site that tells it all!
Well done @jsshapiro, For this guide to the inner workings of AsusWRT and OpenVPN features..
From back in the day, I used to have a bash script which was triggered by .grunt|.gulp task on. /build which was used to config openssl.conf and basically, slit-out self-signed .crt's used in a WebApp dev proj during compile/build when deployed. Part of the prerequisites of secure applets Based on NW.js (webkit V8 sandbox/applet) to secure the backend Client/App <=> Server Layer.
I managed to automate a lots of the steps in this process, ill be happy to share what snippets I have which could be useful to make this an "almost" click and forget process. Anyway, slightly off topic..
More to the point, Im in the process of the configuration of my X89X Router to be the other end of a NordVPN<>Router<>ClientsABCD Endpoint for SOHO setup... The information on this subject, specifically, is lacking to say the least and what is available online make assumptions or miss out key steps.
This guide is really helpful and clears up a lot of the overall processes of openvpn and WRT procedures in general..

./Easy-RSA will be what i'll use to maintain a PKI db/ live backup and working copy of AsusWRT internals and cp the generated CA /server certs to destination directories off my machine onto the router.. Failing that and if any problems i will follow your guide and ssh over LAN into device, use Asus's automatically generated CA key/certs config..

I Look forward to put this guide to practice when i have a bit of spare time to pull my network apart and reconfigure it all.

Nice work!
Lots of stuff.
Awesome write-up, thank you!

A couple of notes for things that tripped me up, or weren't clear:
# Create a scratch directory for our work:
mkdir /tmp/NewCerts

# List the available server directories:
ls /etc/openvpn
ovpn-down@     ovpn-route-up@ ovpn-up@       server1/       vpnclient5@    vpnserver1@
In this section, you use the path /tmp/NewCerts, but later in the guide it's (consistently) /tmp/NewCert.

  1. Open the .ovpn file in your favorite text editor.
  2. Find the part that starts with -----BEGIN CERTIFICATE----- Extract everything from there to the END CERTIFICATE line (including the hyphens) into a separate file with a "crt" extension. I called mine good-client.crt.
  3. Run the openssl dump command: openssl xf09 -in good-client.crt -noout -test.
For 2: I would include a note here to say that the part you want to extract is the second certificate - the one with the <cert> tags.
For 3: If on Windows, you can use the built-in certutil from command or powershell:
certutil -dump <certificate full path>
Last edited:
When trying to run the command (with my values)
openssl req -newkey rsa:2048 -sha512 -nodes -out adminoffice.csr -keyout adminoffice.key -subj '/C=TW/ST=TW/L=Taipei/O=ASUS/CN=adminoffice/emailAddress=me@myhost.domain'
I get the following error
Error Loading extension section v3_ca
1024:error:22098080:lib(34):func(152):reason(128):NA:0:name=subjectAltName, value=@alt_names

I'm using an ASUS RT-AC68U.
Any ideas on how to get it to work?

Edit: I seemed to fix it by copying openssl.cnf from /rom/etc/ssl to /tmp/newcerts
Then opening the copied cnf file and removing the line subjectAltName = @alt_names
Then I added -config openssl.cnf to the command as below
openssl req -newkey rsa:2048 -sha512 -nodes -out adminoffice.csr -config openssl.cnf -keyout adminoffice.key -subj '/C=TW/ST=TW/L=Taipei/O=ASUS/CN=adminoffice/emailAddress=me@myhost.domain'

I also modified the second command to use sha256 instead of sha1 as below as my openVPN client was throwing errors with SHA1.
openssl x509 -in adminoffice.csr -out adminoffice.crt -req -days 3653 -sha256 -extfile ext.cnf  -CA /etc/openvpn/server1/ca.crt -CAkey /etc/openvpn/server1/ca.key -set_serial 02
Last edited:

Similar threads

Latest threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!