Public & Private Keys

Each peer in a WireGuard network has a unique public-key pair (aka “public-private key pair”, “asymmetric key pair”, or just “key pair”), which is used both to uniquely identify the peer, as well as to encrypt communication with the peer.

A public-key pair is composed of two parts: a public key, and a private key (aka “secret key”). WireGuard uses X25519 (aka Curve25519) key pairs, where both the public key and the private key are 256-bit values. The public key can be calculated trivially from the private key (which is why if you know the private key, you typically store only the private key, and not both parts of the pair).

There is no practical way of calculating the private key from the public key, so the public key may be shared freely without compromising the secrecy of the private key. The security of a WireGuard connection depends solely on keeping the private key secret.

When configuring WireGuard, you should supply keys in base64-encoded form. When base64 encoded, both the public key and the private key will appear as 44 alphanumeric characters, ending with an equals sign.

On Linux, you can generate a random private key with the following WireGuard command:

$ wg genkey
yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=

And you can calculate the matching public key for a private key using the following WireGuard command:

$ echo yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk= | wg pubkey
HIgo9xNzJMWLKASShiTqIybxZ0U3wGLiUeJ1PKf8ykw=

Copy and paste the output of the first command into the Private Key field in Pro Custodibus (or as the “PrivateKey” setting in a wg-quick-style configuration file); copy and paste the output of the second command into the Public Key field in Pro Custodibus (or as the “PublicKey” setting in a wg-quick-style configuration file).

Peer Identity

The public key of a WireGuard public-key pair uniquely identifies a peer. All peers that can connect to a given peer identify the peer by its public key. Only the peer itself knows its own private key, however. A peer can cryptographically prove that it knows the private key matching its public key, without revealing the private key, thereby proving its identity.

In Pro Custodibus, we often use the term “Peer Identity”, or just “Peer”, as a synonym for “Public-Key Pair”. A peer has a unique public-key pair, and the public key of this pair globally and uniquely identifies the peer.

Each WireGuard interface is configured with its own peer identity, using the private key of the peer, representing the peer locally on the host on which the interface resides. It’s also configured with the peer identities of the multiple other peers to which it can connect, using the public keys of those other peers, representing those peers as remote endpoints of the interface.

In general, each WireGuard interface should have its own, globally unique, peer identity — in other words, you shouldn’t set up a new interface with a peer identity used anywhere else. There are some exceptions to this rule (such as when running redundant WireGuard gateways in certain high-availability scenarios), but the best practice is to use a given peer identity to configure just one WireGuard interface on just one WireGuard host.

Key Rotation

The easy way to rotate a public-key pair is to use the Bulk Rotation tool, which allows you to update all the monitored hosts that use the key pair with one click.

The hard way is to update each interface that uses the key pair as its own local peer identity, and then individually update each endpoint that can connect to the peer remotely. To do it the hard way, follow these steps:

  1. Click the Hosts link in the app header.

  2. Find the host containing the interface of the old peer identity you want to rotate in the list, and click the host’s name to view the host’s main status page (if more than one interface uses this peer, repeat this and the following steps for each interface).

  3. Find the interface in the Interfaces panel, and click its name to view the interface’s main status page.

  4. Click the “pencil” icon on the right side of the Interface panel to modify the interface’s properties.

  5. Select the new peer identity, either by entering the name of a peer already added to Pro Custodibus in the Peer field, or by adding a new peer by clicking the New button next to the Peer field. See the Edit an Interface documentation for full details.

  6. Click the Update button at the bottom of the form to submit it and queue the changes for the interface.

  7. In the Endpoints panel, click the name of one of the endpoints you still want to allow to connect to the interface.

  8. Scroll down to the Preshared Key panel, and click the name of the Corresponding Endpoint. If it has no corresponding endpoint, or if the corresponding endpoint is not on a monitored host, you won’t be able to update it through Pro Custodibus — you’ll have to update it manually (instead of performing the remaining steps, manually copy the public key of the new peer identity to the host this endpoint represents, and update the host’s WireGuard configuration with it; then return to step 7 for other endpoints).

  9. You are now viewing the corresponding endpoint — you need to delete it and replace it with a copy that uses the new peer identity instead of the old one. Write down the configuration settings for it listed on its Endpoint and Routing panels. If the SHA-256 Hash of a preshared key is listed in the Preshared Key panel, click the “key-on-shield” icon on the right side of that panel to view the preshared key itself, and write it down its full value, as well (then click the Cancel button to return to the endpoint’s main page).

  10. Click the “Delete” icon on the right side of the Endpoint panel.

  11. Navigate to the endpoint’s interface by clicking the interface’s name in the page breadcrumbs (usually the interface will be named something like “wg0”).

  12. Click the “plus” icon on the right side of the Endpoints panel.

  13. Select the new peer identity by entering the name of the peer you selected in step 5 above.

  14. Fill out the rest of the Add Endpoint form using the old endpoint’s settings you copied down in step 9 above. See the Add an Endpoint documentation for full details.

  15. Click the Add button at the bottom of the form to submit it and queue the creation of the endpoint.

  16. Repeat steps 7-15 for each endpoint you still want to allow to connect the interface you updated in step 6 (you can skip this for old endpoints that no longer need to connect to the interface).

The connection between the interface and each endpoint will be interrupted until the peer identity has been updated on both sides of the connection. If both sides of the connection reside on monitored hosts, this should take only a few minutes.

If one side of the connection is not to a monitored host, you will have to update that side manually with the new public-key pair (using the private key if the unmonitored host is the host on which the interface resides, or, for the other side of the connection, its public key).

Bulk Rotation

To rotate a public-key pair (ie peer identity) the easy way, follow these steps:

  1. Navigate to the main page for the peer.

  2. Click the “certificate” icon on the right side of the Peer panel.

  3. Click the Rotate Key Pair button at the bottom of the Manage Key Pair panel.

  4. Click the OK button in the “Rotate Key Pair” confirmation dialog.

A new public-key pair will be generated for you, and changes queued to update each interface and endpoint that used the old key pair (this may take a few seconds if the peer identity was used by many endpoints). When all the changes have been queued, the page will reload to display the new peer identity, and list the queued changes.

Each connection using the peer will be interrupted until the key rotation process has completed on both sides of the connection. On monitored hosts, this should take less than two minutes.

If one side of the connection is not to a monitored host, you will have to update that side manually with the new key pair. See the Manual Rotation section for details.

Manual Rotation

When you use the Bulk Rotation tool to rotate the public-key pair of a connection between a monitored host and an unmonitored host, you will have to manually update the rotated key on the unmonitored host.

Such hosts will have a blank (or old) “Last Ping” value in the Peer Connections panel (and the host, interface, and endpoint columns also may be blank). For each such connection where the unmonitored host is the “Peer’s Host”, listed on the left side of the Peer Connection panel, follow these steps:

  1. Copy the value from the Private Key field of the Manage Key Pair panel (click the “eye” icon to reveal this value), and transfer it to the unmonitored host (for example, SSH into the unmonitored host, or send a secure message to a colleague who has physical access to the unmonitored host).

  2. On the unmonitored host, open the WireGuard configuration for the host, and paste the transferred private key into the PrivateKey setting for the interface.

  3. Save the WireGuard configuration change, and restart WireGuard on the unmonitored host.

For each such connection where the unmonitored host is the “Other Host”, listed on the right side of the Peer Connection panel, follow these steps:

  1. Copy the value of the Public Key field of the Manage Key Pair panel and transfer it to the unmonitored host (for example, SSH into the unmonitored host, or send a secure message to a colleague who has physical access to the unmonitored host).

  2. On the unmonitored host, open the WireGuard configuration for the host, and paste the transferred public key into the PublicKey setting for the [Peer] entry that represents the endpoint to the monitored host.

  3. Save the WireGuard configuration change, and restart WireGuard on the unmonitored host.

To perform these manual steps, you will need to either have physical access to the unmonitored host, or have a remote connection to the unmonitored host that isn’t itself tunneled through a WireGuard connection which you’re in the process of updating (for example, an SSH connection to the unmonitored host that doesn’t go through WireGuard, or an RDP connection through WireGuard to the unmonitored from a host other than the monitored host, etc).