gnoMint

A GTK 4 Certification Authority manager

View the Project on GitHub davefx/gnoMint

Tutorial: a small-firm PKI with OpenVPN

Adapted from the original “gnoMint tutorial” by David Marín, written circa 2008 and recovered from web.archive.org. The text has been updated for recent gnoMint releases, with fresh screenshots from the current version. The user manual covers the same actions without the worked example.

This tutorial walks you through using gnoMint to set up the Public Key Infrastructure for a small firm. We assume:

We will use a single self-contained gnoMint database to hold all certificates issued for the firm.


Planning the CA

Before launching any application, let’s think about the CA we’re going to create. In this example we want a single Root Certification Authority for the firm, so all issued certificates live in one database. The Root CA will only issue subordinate CA certificates, which will be specialised — it’s a recommended practice for a given CA to issue certificates with consistent properties.

We’ll create three subordinate CAs:

Migration note: if you already have a PKI built with OpenSSL (the openssl ca script, tinyCA, OpenVPN’s easy-rsa, etc.), gnoMint has been able to import it into a .gnomint database since version 0.6.0.


Generating the Root CA

Install the latest gnoMint (see the install guide), then launch it:

$ gnomint &

The main window opens with the default database (~/.local/share/gnomint/default.gnomint on current versions, the legacy ~/.gnomint/default.gnomint on older).

Main window after opening a database

Choose Certificates → Add → Add self-signed CA. The “new CA properties” dialog appears.

Subject step of the New-CA wizard

Press OK. Key generation runs in a worker thread; you’ll see a progress dialog. When it finishes, the new Root CA appears in the tree.

A small seal icon next to the certificate marks it as a Certification Authority (allowed to sign other certificates). A keys icon marks rows whose private key lives inside the database — that’s a security consideration we address next.


Protecting the gnoMint database

Anyone with a copy of the .gnomint file holding a private key can issue certificates with that key. gnoMint offers two complementary mitigations:

  1. Encrypt every private key in the database with a passphrase. All keys are encrypted with PKCS#8 (PKCS#12 3DES wrapper, as exposed by GnuTLS) when at rest. Without the passphrase nobody can use the key.
  2. Keep the Root CA private key in a passphrase-protected external file. For maximum security, this file lives on a removable device (USB stick) that is plugged in only when you actually need to sign something with the root.

The two are not mutually exclusive — it’s reasonable to use both. For this tutorial we’ll take the simpler option (in-database with passphrase). Choose Certificates → Change Database Password, set a new passphrase, confirm, and the database is protected.

Database password dialog


Establishing Root-CA policies

Now we configure the policies for the Root CA. Policies decide what the CA is allowed to sign and what defaults its issued certificates inherit.

Double-click the Root CA (or select it and pick Edit → Properties) and open the third tab. Configure:


Creating CSRs for the subordinate CAs

With the Root configured, we create three CSRs (certificate signing requests) — one per subordinate CA. Each CSR will be signed by the Root CA to produce the subordinate’s certificate.

Choose Certificates → Add → Add Certificate Request.

Inherit-from-CA step of the New-CSR wizard

If the database is password-protected, gnoMint asks for the passphrase before saving the CSR’s private key.

If you don’t see your CSR after creating it, check View → Certificate Signing Requests — the filter may be hiding them.

Repeat for the Employees CA and the Software Signing CA, so you end up with three CSRs in the database.


Signing the CSRs

Now sign each CSR with the Root CA to produce the subordinate CA certificates.

Select a CSR and choose Certificates → Sign (or right-click the CSR and pick Sign). The wizard appears:

  1. Confirm the CSR is the right one.
  2. Pick the signing CA (the Root, in our case).
  3. Review certificate properties. The recommended option is to use the CA policies as defaults, but you can override per-certificate. Note: you can’t escape what the policy forbids — e.g. if the Root’s policy only allows Certification Authority and CRL signing, you can’t enable Digital signature on a certificate signed by the Root.

Press OK. gnoMint asks for the database passphrase (to access the Root’s private key), signs the CSR, and adds the new subordinate CA certificate to the tree.

Repeat for the other two CSRs. You now have three subordinate CAs, each ready for its specialised job.


Defining subordinate-CA policies

Open each subordinate CA in turn and configure its policies.

Systems CA

There’s one exception: only the VPN-server node should have the TLS web server bit. You can either flip it off on each client cert at issuance time, or issue all the clients with the bit on and clear it afterwards. We’ll do the latter — easier to remember.

Employees CA

The employees need to do email signing and ciphering plus intranet TLS authentication.

Software signing CA


Issuing the VPN system certificates

The VPN will have one central server and three remote clients (the Barcelona, Madrid and Seville offices). We need four CSRs, all signed by the Systems CA.

A more secure approach is for each remote office to generate its own CSR locally and email you only the CSR — CSRs contain no private material so they can be sent over insecure channels. But for this worked example we’ll assume you (the only technical employee in the firm) are creating all of them.

For each VPN node:

  1. Certificates → Add → Add Certificate Request. Inherit from the Systems CA.
  2. Fill in the subject — CN is the hostname (vpn.example.com, client-barcelona.example.com, …). Add the DNS SAN to match.
  3. Pick a 2048-bit RSA key (or ECDSA P-256 on modern gnoMint — same security, much faster handshake).
  4. Save the CSR.

Once the four CSRs are in the database, sign them with the Systems CA (same workflow as before). You now have four VPN-node certificates plus their private keys, all wrapped inside one .gnomint file.


Exporting certificates for OpenVPN

For each VPN node, export:

Distribute the per-node certificate + key over a secure channel (SCP/SSH to each office is fine). Don’t ever copy a private key across an unencrypted link.

OpenVPN’s ca directive points at the Systems CA certificate, cert at the per-node certificate, and key at the per-node private key.


Where to go next

The original tutorial ends here (“To be continued…”), but the user manual covers the rest of the day-to-day workflow: