| Title: How to setup wireguard on NixOS | |
| Author: Solène | |
| Date: 18 May 2021 | |
| Tags: nixos networking | |
| Description: | |
| # 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 documentation | |
| # 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 192.168.100.0/24 in which the wireguard server will be | |
| 192.168.100.1 and a laptop peer will be 192.168.100.2, the wireguard | |
| UDP port chosen is 5553. | |
| ```NixOS configuration file sample | |
| networking.wireguard.interfaces = { | |
| wg0 = { | |
| ips = [ "192.168.100.1/24" ]; | |
| listenPort = 5553; | |
| privateKeyFile = "/root/wg-private"; | |
| peers = [ | |
| { # laptop | |
| publicKey = "uPfe4VBmYjnKaaqdDT1A2PMFldUQUreqGz6v2VWjwXA="; | |
| allowedIPs = [ "192.168.100.2/32" ]; | |
| }]; | |
| }; | |
| }; | |
| ``` | |
| # 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. |