Which should I use: `networking.wg-quick` or `networking.wireguard`?

There are both wg-quick and wireguard modules in NixOS. Their options are slightly different, but mostly the same, and they seem to do the same thing (I tried both).

Which one is better for when using wireguard as a vpn client?

I have currently configured networking.wireguard, but have two issues with its systemd service.

  1. I don’t want it to start automatically, but didn’t figure out how to stop that. (systemd.services.wireguard-wg0.wantedBy = lib.mkForce [] didn’t seem to work)
  2. The connection doesn’t come up properly after laptop sleep (probably the routes need to added again).

Thoughts?

3 Likes

On my server I use networking.wireguard sort of like this

# server config
{
   networking.wireguard.enable = true;
   networking.wireguard.interfaces."wg0" = {
     privateKeyFile = "/var/keys/wg0-priv-key";
     ips = [ "10.10.10.1/24" "fc10:10:10::1/64" ];
     listenPort = 1194;
     peers = [                                                                                                                                                                                                                        
       { publicKey = "XnBofROntu+DYUaGC8VK6t8SRpKoYuQ6GjDSZNmFME4=";
         allowedIPs = [ "10.10.10.2/32" "fc10:10:10::2/128" ]; }
     ];
   };
}

On my laptop (the client) I use NetworkManager, so I first write a wg0.conf like

[Interface]
Address = 10.10.10.2/32, fc10:10:10::2/128
PrivateKey = 4FZ5mL3tP/CT7+mo6Vm6pjQuJDl9HiINsYEfLA+GyGk=

[Peer]
PublicKey = 3yR10otKsJmoQc6GAhGcyIgRg1wZmqol9S2QqkgYdB0=
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = example.com:1194

Then I run

nmcli connection import type wireguard file wg0.conf

which converts the wg0.conf into /etc/NetworkManager/system-connections/wg0.nmconnection and can from then on be managed with the nm-connection-editor. Of course, you can also deploy this file declaratively using

# client config
{
  environment.etc."NetworkManager/system-connections/wg0.nmconnection".text = ''
    [connection]
    id=wg0
    ...
  '';
}
2 Likes

Thanks @hmenke. Why did you choose networking.wireguard over networking.wg-quick?

In my configuration, I have all the peers, addresses, etc., defined in an attrset, and I generate either a networking.wireguard.interfaces configuration, or .nmconnection file from that.

networking.wireguard generates one unit per peer, whereas networking.wg-quick generates one unit per interface. This means that with networking.wireguard you can add more peers in configuration.nix without restarting the interface. Personally I use networking.wireguard because it was the first thing that I found when searching the docs for Wireguard :slight_smile:

1 Like

@hmenke you didn’t post your real private key, right? (I know it’s been a long time ago, but still.)

1 Like

Of course that’s my very real private key for my very real Wireguard deployment at example.com.

5 Likes

How do you generate the .nmconnection file? I’ve been reading the Wireguard wiki page and it recommends importing the wireguard file with nmcli, but when declaring the wireguard config it would be awesome to run the import on a nix rebuild.

I’m now using systemd-networkd for wireguard. It works well and is better documented than NetworkManager. The main disadvantage of networkd for me is that there is no GUI integrated with GNOME which I can use to bring the wireguard link up/down.

So I don’t generate .nmconnection files any more, but previously I was using something like this:

{ config, lib, pkgs, ... }: let
  settingsFormat = let
    mkValueString = lib.generators.mkValueStringDefault {};
  in pkgs.formats.ini {
    mkKeyValue = lib.generators.mkKeyValueDefault { inherit mkValueString; } "=";
    listToValue = lib.concatMapStringsSep ";" mkValueString;
  };

in lib.mkIf config.networking.networkmanager.enable {
  environment.etc = lib.mapAttrs' (name: settings: let
    profile = "${name}.nmconnection";
  in {
    name = "NetworkManager/system-connections/${profile}";
    value = {
      mode = "0600";
      source = settingsFormat.generate profile settings;
    };
  }) MY_CONFIG_HERE_ELIDED_FOR_BREVITY;
}

Happily, it seems like someone has contributed a NixOS module which does the same thing: networking.networkmanager.ensureProfiles.