Setting up your own PKI - the simple way

Most of you that are reading this will either have their own lab, or a corporate lab environment, and - most likely - regularly install a variety of vendor products to try out new products, test new features, create demo environments for customers, study for certifications, and more.

And what is the thing each and every one of those environments have in common?

That's right. Unsigned certificates everywhere. Now if you're just testing products it's mostly an inconvenience, but if there's one thing i can't stand it's customer demos with self-signed certificates.

Now obviously you can import each and every one of the self-signed certificates, but that's mostly inconventient, risky and hard to manage, so why not set up your own PKI?

Normally, setting up a full-fledged PKI can be quite complicated, so i'm going to show you how you can set up a simple PKI in less than 15 minutes using nothing but a single linux server.

First of all, start off with deploying a linux server (or use one you've already got) and make sure git and openssl are installed. Next, download OpenVPN's easy-rsa through the following command

git clone https://github.com/OpenVPN/easy-rsa

Change into your cloned directory and the subdirectory easyrsa3 (cd easy-rsa/easyrsa3) and run the following commands:

Building the root

./easyrsa init-pki ./easyrsa build-ca

Enter a passphrase for your CA certificate and store it somewhere securely as you'll need this later. This will initialise your PKI infrastructure and generate a root CA certificate.

Note: if you want an offline root CA and an intermediary signing CA you can run the command ./easyrsa build-ca subca to generate a CA certificate and signing request which you can sign with your root CA just as we will be doing in the rest of the tutorial below. For now, we'll just focus on a 1-tier PKI.

Generating the request

Depending on what system you want to sign certificates for, you can either run this command on the CA server (for appliances that can't generate their own requests) or on a different linux system).

If you're requesting the certificate on the CA, you don't need to do anything else. Otherwise, install easy-rsa on your client system as described above. Then, run the following command either on the CA or on the client:

./easyrsa gen-req alias

where alias is the name under which you want to store it in the PKI. Personally i prefer to use the FQDN of the system. This will ask you for the common name, as well as a passphrase. this should be different from your CA passphrase for obvious reasons!

When ran on a client, copy it to a location accessible by the CA and run ./easyrsa import-req /path/to/cert.req alias. This imports it into the PKI.

Next, sign the request:

./easyrsa sign-req server alias

Enter your CA passphrase and your certificate has been generated. You can find the certificate in ./pki/issues/ under the alias you've given at request time. Your private key can be found under ./pki/private/ under the same alias.

If you need a full chain you can generate it as normal by concatenating the certificate files together. If you need to convert your private key to a RSA private key (required for quite a few tools such as NSX loadbalancers and vRealize Automation) , you can use openssl rsa -in /path/to/private/key which will convert it to a RSA format.

Now the only thing you need to do on your systems is to import the root certificate (found under ./pki/ca.crt) and you've got fully signed and validated certificates in under 15 miutes! Finally you won't have an excuse to use unsigned certificates anymore, and you can endlessly mock those that do.

Advanced features

As i'm running a vRA distributed lab i am required to use SAN certificates. As you may have noticed, easy-rsa only generated single CN certificates by default. But fortunately, through some simple commands you can extend your certificates with any features openSSL supports.

For example, to generate a SAN certificate for a clustered vRealize Automation deployment, run the following before generating the request:

/easyrsa --subject-alt-name="DNS:host1,DNS:host1domain.tld,DNS:lbhostname,DNS:lbhostname.domain.tld" gen-req alias

And that's it!

Some other advanced features and customization options can be found in https://github.com/OpenVPN/easy-rsa/blob/master/doc/EasyRSA-Advanced.md, including setting various certificate flags, expiration times, key lengths, and more.