With my new PKI and my Active Directory up and running it was finally time to integrate my OpenVPN into the infrastructure I build over the last couple of months. While I had an OpenVPN running for years now, it was not integrated into any central user database and relied entirely on password protected certificates to authenticate users.
For my new OpenVPN server I considered and tested the OpenVPN Access Server. That is the Commercial Project of OpenVPN, it has a very nice and easy web interface and it is very easy to integrate into Active Directory. I had a test VM set up and all tests went without a glitch. This is probably a very nice solution for most companies and the licensing fees are very reasonable. I was seriously considering to simply buy a couple of licenses and be done with it. In the end however there was some functionality that i missed in the web interface (or maybe have not found). Ultimately i decided to build my own solution since the paid version would not have saved me a whole lot of time.
The one hard requirement I had, that could not be realized (easily) with the OpenVPN Access Server, was my Active Directory integration. While it can authenticate against an Active Directory, it will create one certificate for all users. This was not enough for me. I wanted every user to have his own certificate and every user should only be able to use his own certificate. While this is probably overkill for a home network, I use OpenVPN also for business use. Personally I consider the one Certificate for all policy to great a risk in that scenario and I wanted to see how to implement a better policy.
Another thing that bugged me about the Access Server, was the changed configuration. The community version of OpenVPN is configured by one configuration file. Even if you use some kind of frontend to create the configuration, it is still very easy to customise the configuration beyond the options offered in the frontend. The Access Server however writes its configuration in some kind of database. I am not sure how to modify it manually, or if it is supported at all, but to me this means a loss of flexibility.
This is probably not an issue for most users though.
The last thing that bothered me was the price. To be fair 2 concurrent connections are free and the pricing is very fair compared to Other VPN products. But since I am not familiar with the manual configuration of the Access Server, I would likely need the same amount of time to achieve my goal with the Access Server as i would with the community edition. In this case the money i had to spend was a downside.
Before trying to build everything from scratch, I searched for OpenVPN web frontends, but nothing really impressed me. The OpenVPN in PFSense seems decent, but i ruled it out since there are no VirtIO drivers for PFSense. Since I had to do everything myself anyway, I might as well do it right. So I added some features I wanted and ended up with following goals for my little Project:
1. Two Factor Authentication: each User needs his Active Directory Login and a unique Certificate
2. User Certificates have to be generated and revoked automatically based on membership in an Active Directory group. Thus I essentially wanted to manage the OpenVPN from the Active Directory.
3. Multiple OpenVPN Daemons. I wanted to have the possibility to connect via UDP and TCP.
4. There had to be a convenient and reasonably secure way for users to retrieve their configuration files and certificates/keys.
5. The files had to be distributed to the users in an automated manner.
6. The installation/configuration of OpenVPN had to be as painless as possible for the users.
7. The TCP Daemon had to share a port with my web server.
8. Fairly fast reaction to added/ revoked users.
9. The ability to distribute different configurations for different use cases.
10. Easy to access statistics.
11. Every client should only be able to successfully authenticate if he uses his own certificate.
First thoughts on implementation
Before starting I came came up with a few thoughts on how to tackle all the requirements.:
1. While the OpenVPN Access Server could be integrated into an Active Directory quickly, it only used one certificate for all users. The community OpenVPN has no build in support for LDAP, but there is a plugin for LDAP support. The easiest way to manage the certificates is probably creating certificates with the username as the common name.
2. I seriously hate having to manage the users of one service in different places, this usually leads to problems. Some scripting will be required for this.
3. I prefer UDP for performance reasons, but it is extremely useful to have a TCP OpenVPN on the https port since it enables you to connect through most firewalls and proxies. This means i will have to run two different OpenVPN Servers. Since several OpenVPN Servers can share one PKI, this should not be a problem.
4. Originally I considered creating a small download page on my https server for this. After thinking it through I scrapped that idea and went with E-Mail as distribution method. In my case it is perfect: My mail server is on my internal network, so sending the keys from my VPN server to my mail server is safe. Furthermore my mail server already has a https enabled web mail in place and all outside IMAP and pop connections have to be secure. Last but not least, my web mail is authenticated and authorized by my AD, that means my users can use their OpenVPN account for the web mail as well. The last one is important, since the necessity for more then one account would lower the user acceptance. And since mails are fairly easy to script, I have a reasonably secure means of distributing my keys already in place.
5. Since I am going to script my certificate creation , this is something that will most definitely go into that script. And sending an E-Mail on a command line script should be relatively simple.
6. The script will create a configuration file, that includes all necessary keys and certificates. I did not know this option existed, but from the OpenVPN Access Server i learned about it. Basically certificates and keys can be added in a xml like style. I like this one and will probably also use this at work in the future. Especially considering, that there are people out there who have problems with instructions such as extract the file to following location.
7. This is no problem I have been testing this mode for a couple weeks on my old OpenVPN server. But it might have been one with the Access Server, because the Access Server shares its TCP port with its internal web server. I have not seen an option to change this in the web interface.
8. I will use the script to revoke user certificates and create the CRL as well. The script will be run regularly by cron. Even though such a fast revocation is not strictly required with this setup. If a user is removed from the AD group, the login will fail even if he still has a valid certificate.
9. Basically i just need to create templates for every OpenVPN configuration. My script can then personalize each config template.
10. OpenVPN keeps a status file, with the statistics of all currently connected users. It is easy to reach but not the most convenient. I will figure out a better solution for this once the server is running.
11. The OpenVPN default behaviour is to accept the connection from anyone with any valid certificate and any valid authentication. This behaviour would make the use of personalized certificates fairly useless. OpenVPN has no way of doing this on its own, but there is a way to include scripts in the authentication process. And since OpenVPN creates variables for the username and the common name of the certificate, this should be a very simple script.
I believe that this will not be too hard to implement and that my custom solution will offer me the same grade of convenience, that commercial solutions offer. My solution will allow me more flexibility than the commercial solutions I have seen so far. The next article will cover the basic installation and configuration of the OpenVPN Server.