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.
       
 (HTM) 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.