Title : How to setup wireguard on NixOS
Author: Solène
Date : 18 May 2021
Tags : nixos network
# Introduction
Today I will share my simple wireguard setup using NixOS as a wireguard server. The official documentation is actually very good but it didn't really fit for my use case. I have a server with multiples services but some of them need to be only reachable through wireguard, but I don't want to open all ports to wireguard either.
As a quick introduction to Wireguard, it's an UDP based VPN protocol with the specificity that it's stateless, meaning it doesn't huge any bandwidth when not in use and doesn't rely on your IP either. If you switch from an IP to another to connect to the other wireguard peer, it will be seamless in regards to wireguard.
NixOS wireguard
# Wireguard setup
The setup is actually easy if you use the program "wireguard" to generate the keys. You can use "nix-shell -p wireguard" to run the following commands:
```shell commands
umask 077 # this is so to make files only readable by root
wg genkey > /root/wg-private
wg pubkey < /root/wg-private > /root/wg-public
Congratulations, you generated a wireguard private key in /root/wg-private and a wireguard public key in /root/wg-public, as usual, you can share the public key with other peers but the private key must be kept secret on this machine.
Now, edit your /etc/nixos/configuration.nix file, we will create a network in which the wireguard server will be and a laptop peer will be, the wireguard UDP port chosen is 5553.
```NixOS configuration file sample
networking.wireguard.interfaces = {
wg0 = {
ips = [ "" ];
listenPort = 5553;
privateKeyFile = "/root/wg-private";
peers = [
{ # laptop
publicKey = "uPfe4VBmYjnKaaqdDT1A2PMFldUQUreqGz6v2VWjwXA=";
allowedIPs = [ "" ];
# Firewall configuration
Now, you will also want to enable your firewall and make the UDP port 5553 opened on your ethernet device (eth0 here). On the wireguard tunnel, we will only allow TCP port 993.
```NixOS configuration file sample
networking.firewall.enable = true;
networking.firewall.interfaces.eth0.allowedTCPPorts = [ 22 25 465 587 ];
networking.firewall.interfaces.eth0.allowedUDPPorts = [ 5553 ];
networking.firewall.interfaces.wg0.allowedTCPPorts = [ 993 ];
Specifically defining the firewall rules for eth0 are not useful if you want to allow the same ports on wireguard (+ some other ports specifics to wg0) or if you want to set the wg0 interface entirely trusted (no firewall applied).
# Building
When you have done all the changes, run "nixos-rebuild switch" to apply the changes, you will see a new network interface wg0.
# Conclusion
I obviously stripped down my real world use case but if for some reasons you want a wireguard tunnel stricter than what's available on the public network interfaces rules, this is how you do.