OpenVPN manual states that it will trust any certificate that is descendant of the CA certificate you configured in it. So, to really separate VPNs you omit root certificate from all configurations. It won't be used anywhere, adds no value or benefit, so why bother maintaining it? Just take EasyRSA and create an separate and independent "root, single-level" CA for each VPN.
I don't know why you listed port 443 here; it is rarely used for OpenVPN because it is well known HTTPS port and often is occupied, so when it's used it's often tricky configurations involving port-share
. For that case, sslh
is superior, at least because you can use its "transparent mode" for daemons to see the real IP of the remote and not bother with the way OpenVPNs makes that information avaliable. Though I doubt you need this peculiarity for your project. Other than that, you can really use arbitrary port numbers. 1194 is listed as "official" but nothing forbids you from setting 11941 or 1195 or 5000 (which was suggested fifteen years ago) or anything else. Pick a set of ports, let's say staring with 1194 and up, and just add one for each successive VPN instance.
The rest is correct: you use separate (public) ports for independent daemons, and run them as separate SystemD units. Consider separate containers for different VPNs: while it's possible to run separate VPN instances in the single namespace, it is easier and less error-prone to just do split them (and not much more resource consuming). As I understood, your customers are unrelated entities, so this would be more straightforward way separate them. In that case VPN configurations inside containers may use the default port, but you'll forward (publish) different ports for them.
Designate some system solely for managing VPNs; it will store your CAs and only it can therefore issue certificates. That system will be also needed to to issue CRLs; by default CRLs live for 30 days, and if you configure crl-verify
(you will!), when the CRL expires the VPN will stop accepting new connections until it is valid again. So what you really need to automate is CRL reissuance and distribution. When updating the CRL file you don't need to reload the daemon, so simple scp
to the target system over the old file is enough.
It is useful to create a OpenVPN client configuration file template and generate client configurations with embedded certificates from that template; that saved me much time even without Ansible. I often customize bundled openssl.cnf
and vars
files to add several fields and remove unused, and to reorganize things and for it to run with less questions (or with no questions, for batch-processing). For your case it may be useful to have such templates and generation scripts for creating new VPNs and server configurations too. Such templates, scripts and customisations will be useful for Ansible playbooks that instantiate new customer or new IoT device of an existing customer. For the latter, it may be nice to tie certificate's CN to the serial number of the IoT device, which should simplify accounting.