Verify that cfssl-generated client/server certificates work

We’re going to run nginx in a container and connect to it via httpie using the newly generated client certificate.

Create a new folder and copy ca.pem into it. That is the public part the root certificate. If this was very official, this would be included in browsers. We also need a server certificate, because you can’t only use client certs. Generate one with the server profile, copy the key server-key.pem and the certificate chain server.crt.

NOTE: You probably don’t want to use this certificate. LetsEncrypt is great and there’s no reason to accept the increased risk of a personally managed CA for that. It’s possible to get LetsEncrypt-certificates for VPN-only servers too.

Finally, we also need an nginx config. Here’s what I used:

server {
    listen  443 ssl;
    server_name localhost;

    ssl_certificate /etc/nginx/conf.d/server.crt;
    ssl_certificate_key /etc/nginx/conf.d/server-key.pem;

    ssl_client_certificate /etc/nginx/conf.d/ca.pem;
    ssl_verify_client on;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

Put that into a file called default.conf.

The folder should now look like this:

$ ls -1
ca.pem
default.conf
server.crt
server-key.pem

Now we can run nginx with the following command. You can replace podman with docker if you prefer.

podman run --rm -ti -p 9443:443 -v $PWD:/etc/nginx/conf.d nginx:1.21

Let’s go back to the pki directory and verify the certificates work

$ http https://localhost:9443 --verify ca/ca.pem
HTTP/1.1 400 Bad Request
< ...snip... >

$ http https://localhost:9443 --verify ca/ca.pem --cert=certs/foo.crt --cert-key=certs/foo-key.pem
HTTP/1.1 200 OK
< ...snip... >

The only thing left is to export the certificate for use in a browser.