Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/wireguard: allow setting a readable name for peers #71737

Closed
wants to merge 1 commit into from

Conversation

delroth
Copy link
Contributor

@delroth delroth commented Oct 23, 2019

Motivation for this change

Makes the systemd unit names more easily mappable to what peer they correspond to (I don't memorize peer public keys :-) ).

stopping the following units: wireguard-wg-peer-1PLQcx\x2beVLgRwN6e7fim53rHQXB7pjIg6okOe2nFoi8\x3d.service, wireguard-wg-peer-aN5nU\x2bdNxgemk2Al9lZvSLyYl4kfrx\x2bfxnOPzgbaemg\x3d.service, wireguard-wg-peer-it4vdCJjH5PlpJjdcg4WIwneDmOfqy5fgM0X7tbOfxw\x3d.service, wireguard-wg-peer-jR5rxDnjobcNpiVP62-LLZpvuwYh3BotSYRdw8CdwFI\x3d.service, wireguard-wg-peer-tC\x2bMMRRM50Y5NkD7DJQny7TNwefdl41-J\x2bjsHHnszVU\x3d.service, wireguard-wg-peer-vllG0namXqtwo2xZ1q-oZ-\x2buGGWFvro3Pam2V3N1eW4\x3d.service
the following new units were started: wireguard-wg-peer-chaos.service, wireguard-wg-peer-duke.service, wireguard-wg-peer-eden.service, wireguard-wg-peer-lowell.service, wireguard-wg-peer-pixel.service, wireguard-wg-peer-yew.service
Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nix-review --run "nix-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

Copy link
Member

@ivan ivan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good improvement and I confirmed that it worked on 19.09.

@ivan
Copy link
Member

ivan commented Oct 25, 2019

cc @grahamc for review or merge or reviewer assignment

keyToUnitName = replaceChars
[ "/" "-" " " "+" "=" ]
[ "-" "\\x2d" "\\x20" "\\x2b" "\\x3d" ];
unitName = keyToUnitName peer.publicKey;
unitName = keyToUnitName name;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if two peers are given the same name?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing the PR, it looks like there is no warning or error; the first peer listed with the same name "wins" and gets put into the systemd unit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this calls for a change of the current peers data structure, from "list of sets" to "set of sets", e.g.:

networking.wireguard.interfaces = {
  business = {
    # […]
    peers = {
      fileserver = { publicKey = "…"; allowedIPs = ["…"]; };
      webserver = { publicKey = "…"; allowedIPs = ["…"]; };
    };
  };
};

This would be a breaking change for existing configurations, but it seems to me like the only sane way to properly handle the name collision issue based on the current implementation.

On the other hand, instead of having individual service units per peer, the whole networking.wireguard implementation could also simply make use of systemd's native WireGuard support in systemd-networkd, so we'd end up with far less complexity and implementation overhead.
As since systemd 243, systemd-networkd also supports PrivateKeyFile=, this would also allow to take the requirement to keep the private key out of the configuration into account.

And as systemd-networkd simply provides a Description= attribute for each .netdev, the whole thing would work just fine with the existing data structure and potential name collisions, as it wouldn't be used as primary key anymore.

@Lassulus
Copy link
Member

ping?

@zopieux
Copy link
Contributor

zopieux commented Mar 16, 2020

An bonus use of the friendly name introduced by this PR would be the Prometheus exporter for Wireguard, which has a feature to export friendly names if given a config file with names as # comments. With this PR merged, such a config could be generated from NixOS WG config instead, and we could get rid of this option.

@f4814
Copy link
Contributor

f4814 commented May 8, 2020

What @zopieux said. Merging this would be awesome. How is the status on this?

@delroth
Copy link
Contributor Author

delroth commented May 8, 2020

Basically: it's easy enough to keep as a local patch in my nixpkgs and I don't care enough to go through and make the invasive changes that people have suggested (changing the whole configuration format). I agree the suggested format would be better, but the time I would have to put into it isn't worth it for me.

If someone wants to go and take this over and work on the suggested changes, be my guest, and I'll just close this PR in favor of yours :)

@f4814
Copy link
Contributor

f4814 commented May 8, 2020

I have exams coming up. If there is no progress on this until in ~3 Weeks I will take this over.

ivan added a commit to ludios/infrabase that referenced this pull request May 15, 2020
@flokli
Copy link
Contributor

flokli commented May 18, 2020

Wouldn't make it more sense to prefix the peer-specific unit name with the interface name, but keep the hash behind that?
Getting real human-readable peer names in here might be complicated, and probably a easier fix without any need for the user to supply more config would be telling what wireguard interface it belongs to.

Also, prefixing the peer-specific units with the wireguard interface name solves the unit file name clash, if we still add a name option for each peer.

@stale
Copy link

stale bot commented Nov 14, 2020

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Nov 14, 2020
@SuperSandro2000
Copy link
Member

@f4814 three weeks are over 😉

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Nov 23, 2020
@f4814
Copy link
Contributor

f4814 commented Nov 24, 2020

Yeah, sorry. I have moved to wg-quick, as it fits my usecase much better. So I'm not really interested in fixing this anymore.

@flokli
Copy link
Contributor

flokli commented Nov 24, 2020

Let's close this until someone finds time to finish this up.

@flokli flokli closed this Nov 24, 2020
@ivan
Copy link
Member

ivan commented Oct 23, 2021

an updated version of the rejected patch for nixpkgs master / 21.11

From 0d31b9131b0b29941b93e5c303d18199e988132b Mon Sep 17 00:00:00 2001
From: Pierre Bourdon <delroth@gmail.com>
Date: Wed, 23 Oct 2019 02:56:25 +0200
Subject: [PATCH] nixos/wireguard: allow setting a readable name for peers

---
 nixos/modules/services/networking/wireguard.nix | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/nixos/modules/services/networking/wireguard.nix b/nixos/modules/services/networking/wireguard.nix
index 55b84935b6c..1b11fe8e452 100644
--- a/nixos/modules/services/networking/wireguard.nix
+++ b/nixos/modules/services/networking/wireguard.nix
@@ -148,6 +148,12 @@ let
 
     options = {
 
+      name = mkOption {
+        default = null;
+        type = with types; nullOr str;
+        description = "An optional name for the peer.";
+      };
+
       publicKey = mkOption {
         example = "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=";
         type = types.str;
@@ -271,18 +277,19 @@ let
         '';
       };
 
-  peerUnitServiceName = interfaceName: publicKey: dynamicRefreshEnabled:
+  peerUnitServiceName = interfaceName: name: dynamicRefreshEnabled:
     let
       keyToUnitName = replaceChars
         [ "/" "-"    " "     "+"     "="      ]
         [ "-" "\\x2d" "\\x20" "\\x2b" "\\x3d" ];
-      unitName = keyToUnitName publicKey;
+      unitName = keyToUnitName name;
       refreshSuffix = optionalString dynamicRefreshEnabled "-refresh";
     in
       "wireguard-${interfaceName}-peer-${unitName}${refreshSuffix}";
 
   generatePeerUnit = { interfaceName, interfaceCfg, peer }:
     let
+      name = if peer.name != null then peer.name else peer.publicKey;
       psk =
         if peer.presharedKey != null
           then pkgs.writeText "wg-psk" peer.presharedKey
@@ -295,10 +302,10 @@ let
       # We generate a different name (a `-refresh` suffix) when `dynamicEndpointRefreshSeconds`
       # to avoid that the same service switches `Type` (`oneshot` vs `simple`),
       # with the intent to make scripting more obvious.
-      serviceName = peerUnitServiceName interfaceName peer.publicKey dynamicRefreshEnabled;
+      serviceName = peerUnitServiceName interfaceName name dynamicRefreshEnabled;
     in nameValuePair serviceName
       {
-        description = "WireGuard Peer - ${interfaceName} - ${peer.publicKey}";
+        description = "WireGuard Peer - ${interfaceName} - ${name}";
         requires = [ "wireguard-${interfaceName}.service" ];
         after = [ "wireguard-${interfaceName}.service" ];
         wantedBy = [ "multi-user.target" "wireguard-${interfaceName}.service" ];
-- 
2.33.0

@Lassulus
Copy link
Member

maybe a new PR would be better than a patch on a closed one?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants