WireGuard

From NixOS Wiki
Revision as of 15:05, 24 February 2019 by Erictapen (talk | contribs)
Jump to: navigation, search

Setting up Wireguard

Generate keypair

Each peer needs to have a public-private keypair. The keys can be generated on any machine that already has Wireguard installed using the wg utility. If Wireguard isn't installed yet, it can be made available by adding wireguard to environment.systemPackages or by running nix-env -iA wireguard.

Creating a keypair is simple:

umask 077
mkdir ~/wireguard-keys
wg genkey > ~/wireguard-keys/private
wg pubkey < ~/wireguard-keys/private > ~/wireguard-keys/public

You can create as many keypairs as you like for different connections or roles; it is also possible to reuse the same keypair for every connection.

Server setup

Enable Wireguard on the server via /etc/nixos/configuration.nix:

{
  ...

  # enable NAT
  networking.nat.enable = true;
  networking.nat.externalInterface = "eth0";
  networking.nat.internalInterfaces = [ "wg0" ];

  networking.wireguard.interfaces = {
    # "wg0" is the network interface name. You can name the interface arbitrarily.
    wg0 = {
      # Determines the IP address and subnet of the server's end of the tunnel interface.
      ips = [ "10.100.0.1/24" ];

      # The port that Wireguard listens to. Must be accessible by the client.
      listenPort = 51820;

      # Path to the private key file.
      #
      # Note: The private key can also be included inline via the privateKey option,
      # but this makes the private key world-readable; thus, using privateKeyFile is
      # recommended.
      privateKeyFile = "path to private key file";

      peers = [
        # List of allowed peers.
        { # Feel free to give a meaning full name
          # Public key of the peer (not a file path).
          publicKey = "{client public key}";
          # List of IPs assigned to this peer within the tunnel subnet. Used to configure routing.
          allowedIPs = [ "10.100.0.2/32" ];
        }
        { # John Doe
          publicKey = "{john doe's public key}";
          allowedIPs = [ "10.100.0.3/32" ];
        }
      ];
    };
  };
  ...
}

Client setup

{
  ...
  # Enable Wireguard
  networking.wireguard.interfaces = {
    # "wg0" is the network interface name. You can name the interface arbitrarily.
    wg0 = {
      # Determines the IP address and subnet of the client's end of the tunnel interface.
      ips = [ "10.100.0.2/24" ];

      # Path to the private key file.
      #
      # Note: The private key can also be included inline via the privateKey option,
      # but this makes the private key world-readable; thus, using privateKeyFile is
      # recommended.
      privateKeyFile = "path to private key file";

      peers = [
        # For a client configuration, one peer entry for the server will suffice.
        {
          # Public key of the server (not a file path).
          publicKey = "{server public key}";

          # Forward all the traffic via VPN.
          allowedIPs = [ "0.0.0.0/0" ];
          # Or forward only particular subnets
          #allowedIPs = [ "10.100.0.1" "91.108.12.0/22" ];

          # Set this to the server IP and port.
          endpoint = "{server ip}:51820";

          # Send keepalives every 25 seconds. Important to keep NAT tables alive.
          persistentKeepalive = 25;
        }
      ];
    };
  };
  ...
}

Multiple connections can be configured by configuring multiple interfaces under networking.wireguard.interfaces.


Setting up Wireguard with systemd-networkd

Please note, that networkd support in NixOS is still experimental.

Client setup

{ config, pkgs, lib, ... }:{
  boot.extraModulePackages = [ config.boot.kernelPackages.wireguard ];
  systemd.network = {
    enable = true;
    netdevs = {
      "10-wg0" = {
        netdevConfig = {
          Kind = "wireguard";
          MTUBytes = "1300";
          Name = "wg0";
        };
        # See also man systemd.netdev
        extraConfig = ''
          [WireGuard]
          # Currently, the private key must be world readable, as the resulting netdev file will reside in the Nix store.
          PrivateKey=EMlybyTmXI/4z311xU9S3m82mC2OOMRfRM0Okiik83o=
          ListenPort=9918

          [WireGuardPeer]
          PublicKey=OhApdFoOYnKesRVpnYRqwk3pdM247j8PPVH5K7aIKX0=
          AllowedIPs=fc00::1/64, 10.100.0.1
          Endpoint={set this to the server ip}:51820
        '';
      };
    };
    networks = {
      # See also man systemd.network
      "40-wg0".extraConfig = ''
        [Match]
        Name=wg0

        [Network]
        DHCP=none
        IPv6AcceptRA=false
        Gateway=fc00::1
        Gateway=10.100.0.1
        DNS=fc00::53
        NTP=fc00::123

        # IP addresses the client interface will have
        [Address]
        Address=fe80::3/64
        [Address]
        Address=fc00::3/120
        [Address]
        Address=10.100.0.2/24
      '';
    };
  };
};


See also