Wireguard VPN
- each host is a Wireguard peer
- each host has a private + public key.
- the private key is encrypted to [system]/[host-name].vpn.age
- anyone except the cluster admins and the host itself can decrypt the private key
- each host has a unique id. The ip on the Wireguard network is calculated from this id and a preconfigured CIDR
- each host has a Wireguard interface and information about the bastions: their ip and port
- when the host connects to a bastion, it adds a an entry to their local
resolved
(on NixOS) so it resolves any<machine-name>.vpn
or<machine>
to the bastion’s IP address.
- each host has a private + public key.
- bastions
- the bastions have all the information about the hosts: their name, public keys, and a unique id
- from a preconfigured CIDR and the host’s unique id, the bastions can calculate the host’s ip
- the bastions have a Wireguard interface and a port so the hosts can connect to them
- the bastions also run a
dnsmasq
server on port 53 that listens to the Wireguard network interface, with the list of the hosts and their IP addresses stored in/etc/hosts
. In doing so, there is no need for the existing hosts to re-deploy their configuration if a new host is added to the project.
Setting it up
Clients and bastions can be created from scratch with their keys with the
nicos create
command.
Generate the bastion keys
Generate a wireguard private key and a public key for the bastion
machine:
This command creates an ecrypted hosts-nixos/bastion.vpn.age
private key and prints the public key that will be used in the next step.
Bastion configuration
A bastion needs to have a public key, a private key, and a unique id:
Generate the client keys
Generate a wireguard private key and a public key for the bastion
machine:
Again, this command creates an ecrypted hosts-nixos/client.vpn.age
private key and prints the public key that will be used in the next step.
Configure the client
Any machine needs to have a public key, a private key, and a unique id, too:
Deploy the configurations
Once the client and the bastion configured, you have to deploy their configurations:
Bastions need to be re-deployed for every new machine that is added to the VPN network, as they need every machine’s public key and ID to accept their connection.
Similarly, any change in bastions needs to be reflected in all the clients’ configuration.
Further configuration
You can find all the configuration options of the VPN in the reference documentation, as well as the options for bastions.
It is important to keep in mind that all the machines must share common settings in order for the VPN to work properly, except their public and private wireguard keys, as well as their identified that must be unique.
It is therefore recommended to put the common VPN settings in a shared file that can be set the nicos flake options, for instance: