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: setup interface with systemd-networkd #45392
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not tested the actual module, but the transition makes sense.
type = types.addCheck (types.attrsOf unitOption) checkWireGuard; | ||
description = '' | ||
Each attribute in this set specifies an option in the | ||
<literal>[WIREGUARD]</literal> section of the unit. See |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[WireGuard]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
type = with types; listOf (submodule wireguardPeerOptions); | ||
description = '' | ||
Each attribute in this set specifies an option in the | ||
<literal>[WIREGUARDPEER]</literal> section of the unit. See |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[WireGuardPeer]
type = types.addCheck (types.attrsOf unitOption) checkWireGuardPeer; | ||
description = '' | ||
Each attribute in this set specifies an option in the | ||
<literal>[Route]</literal> section of the unit. See |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[WireguardPeer]
Now we would only need |
nameValuePair "wireguard-${name}" | ||
{ | ||
description = "WireGuard Tunnel - ${name}"; | ||
after = [ "network.target" ]; | ||
after = [ "sys-subsystem-net-devices-${name}.device" ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we wait for DNS/network configuration?
I am not sure what the behavior ended up being (@Mic92) within systemd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should.
(btw systemd handles the resolution of endpoints)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added exponential backoff for dns resolution, so it will retry failed endpoints just like openvpn: https://github.com/systemd/systemd/blob/master/src/network/netdev/wireguard.c#L268
It make sense to not wait for dns to avoid leaking traffic.
OK 👍
…On Tue, 21 Aug 2018, 11:42 Jörg Thalheim, ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In nixos/modules/services/networking/wireguard.nix
<#45392 (comment)>:
> nameValuePair "wireguard-${name}"
{
description = "WireGuard Tunnel - ${name}";
- after = [ "network.target" ];
+ after = [ "sys-subsystem-net-devices-${name}.device" ];
I added exponential backoff for dns resolution, so it will retry failed
endpoints just like openvpn:
https://github.com/systemd/systemd/blob/master/src/network/netdev/wireguard.c#L268
It make sense to not wait for dns to avoid leaking traffic.
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#45392 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAm_dFj8W4i0BSZpFk5Hc6-qBHoqnrfbks5uS9X3gaJpZM4WEUxh>
.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This misses creating routes, which was done before.
Patch for the inline comment on privateKey below.
Also added back postShutdown using ip set link down
. We might not want to do this in case we handle routes with networkd, too.
From 854ce74e6eb0e7362ec9a749bdda3a83b7343795 Mon Sep 17 00:00:00 2001
From: Robin Gloster <mail@glob.in>
Date: Wed, 22 Aug 2018 04:01:51 +0200
Subject: [PATCH] wireguard: fix privateKey handling, add back postShutdown
---
nixos/modules/services/networking/wireguard.nix | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/nixos/modules/services/networking/wireguard.nix b/nixos/modules/services/networking/wireguard.nix
index 43eecca1b6c..75301179706 100644
--- a/nixos/modules/services/networking/wireguard.nix
+++ b/nixos/modules/services/networking/wireguard.nix
@@ -225,14 +225,19 @@ let
};
script = ''
- wg set ${name} private-key ${values.privateKeyFile}
+ ${optionalString (values.privateKeyFile != null) "wg set ${name} private-key ${values.privateKeyFile}"}
${concatMapStringsSep "\n" (peer:
- optionalString (peer.presharedKeyFile != null) "wg set ${name} peer preshared-key ${peer.presharedKeyFile}"
+ optionalString (peer.presharedKeyFile != null) "wg set ${name} peer preshared-key ${peer.presharedKeyFile}"
) values.peers}
ip link set up dev ${name}
${values.postSetup}
'';
+
+ preStop = ''
+ ip link set down dev ${name}
+ ${values.postShutdown}
+ '';
};
in
--
2.16.4
@@ -46,11 +46,26 @@ let | |||
"bond" "bridge" "dummy" "gre" "gretap" "ip6gre" "ip6tnl" "ip6gretap" "ipip" | |||
"ipvlan" "macvlan" "macvtap" "sit" "tap" "tun" "veth" "vlan" "vti" "vti6" | |||
"vxlan" "geneve" "vrf" "vcan" "vxcan" "wireguard" "netdevsim" | |||
"wireguard" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wireguard is in the line above already
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've missed that. Thanks for pointing this out.
wg set ${name} private-key ${privKey} ${ | ||
optionalString (values.listenPort != null) " listen-port ${toString values.listenPort}"} | ||
|
||
wg set ${name} private-key ${values.privateKeyFile} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be wrapped in optionalString (values.privateKeyFile != null)
to handle the use of privateKey
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure.
@globin, I've applied your patch and restored the option allowedIPsAsRoutes. |
Ah I have one more minor nitpick to the route handling that already had existed before this PR. When adding routes without specifying
Patch to add From 9e699b21199d2d05025c069efe60afd03546742a Mon Sep 17 00:00:00 2001
From: Robin Gloster <mail@glob.in>
Date: Wed, 22 Aug 2018 19:10:32 +0200
Subject: [PATCH] wireguard: make wg routes proto static
This fixes distributing routes with e.g. babel that ignores `proto boot`
---
nixos/modules/services/networking/wireguard.nix | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nixos/modules/services/networking/wireguard.nix b/nixos/modules/services/networking/wireguard.nix
index f6d45c9d357..46fcb03d32f 100644
--- a/nixos/modules/services/networking/wireguard.nix
+++ b/nixos/modules/services/networking/wireguard.nix
@@ -234,7 +234,7 @@ let
${optionalString (values.allowedIPsAsRoutes != false) (concatStringsSep "\n" (concatMap (peer:
(map (allowedIP:
- "ip route replace ${allowedIP} dev ${name} table ${values.table}"
+ "ip route replace ${allowedIP} dev ${name} table ${values.table} proto static"
) peer.allowedIPs)
) values.peers))}
--
2.16.4 |
Also this will not work without having |
It is possible to use |
Then this should mkDefault enable it :) |
Commits have been fix up to use systemd.network.enable and keep the DEVICE env. variable in the unit... I've noticed that the unit is not reloaded when the device is reconfigured with networkd. The privateKey is not set anymore on the wireguard link after "systemctl restart system-networkd". |
Indeed, networkd will overwrite the key whenever it configures an interface https://github.com/systemd/systemd/blob/master/src/network/netdev/wireguard.c#L69 The only way this could be prevented would be to create an .netdev unit that has the private key included. |
For sure it could be prevented when the privateKey (and presharedKey) is defined instead of privateKeyFile. |
wg set ${name} private-key ${privKey} ${ | ||
optionalString (values.listenPort != null) " listen-port ${toString values.listenPort}"} | ||
# wait for ${name} to be configured | ||
while ! networkctl status $DEVICE | grep configured 1>/dev/null; do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh, this is ugly. What if the users restart systemd-networkd manually?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be fixed with PartOf=systemd-networkd.service?
Also the indentation is off in a few places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also then module should set the device up with ip
after networkctl has configured the device. Does not networkd also set the link up correctly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be fixed by waiting systemd-network-wait-online@${name}.service
. How could we make this unit from systemd-network-wait-online@.service
?
The while loop could be replaced with ${config.systemd.package}/lib/systemd/systemd-networkd-wait-online -i ${name}
. If systemd-networkd is restarted, the keys are restored as expected.
nameValuePair "wireguard-${name}" | ||
{ | ||
description = "WireGuard Tunnel - ${name}"; | ||
after = [ "network.target" ]; | ||
after = [ "sys-subsystem-net-devices-${name}.device" "systemd-networkd-online" ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The target is spelled wrong and I don't see why systemd-networkd-online.target
is required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also use utils.escapeSystemdPath
on name in the unit definition as systemd will escape e.g. hyphens with \x2d
while ! networkctl status $DEVICE | grep configured 1>/dev/null; do | ||
sleep 1 | ||
done | ||
sleep 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this sleep?
@@ -201,43 +230,30 @@ let | |||
}; | |||
|
|||
script = '' | |||
modprobe wireguard |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you load the module anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When an unknown netlink type is requested the kernel tries to load the kernel module:
╭─[~/git/nixpkgs]─[go-1_11]
╰─ % sudo rmmod wireguard
╭─[~/git/nixpkgs]─[go-1_11]
╰─ % lsmod | grep wireguard
╭─[~/git/nixpkgs]─[go-1_11]
╰─ % sudo ip l add dev foobar type wireguard
╭─[~/git/nixpkgs]─[go-1_11]
╰─ % lsmod | grep wireguard
wireguard 229376 0
ip6_udp_tunnel 16384 1 wireguard
udp_tunnel 16384 1 wireguard
ipv6 503808 248 nf_conntrack_ipv6,bridge,ip6t_rpfilter,nf_defrag_ipv6,nf_nat_ipv6,wireguard
I merged #45569 because I am not sure this is ready yet, and we should get at least one of these improvements into 18.09. The merge does not imply a vote against this change. |
868b377
to
6da208e
Compare
I've rebased this branch. I'm using it on my machines:
|
@dguibert This PR has been stuck for several months now. Is it just the merge conflict that's blocking this? Is there any way I can help? |
Just rebased. Works for me since I've pushed the first patch series. |
Heya. I recently got a patch merged in systemd that adds a Anyhow. I'd like to see this merged. So I'll happily take another pass to see if we didn't miss anything . I'll put it on my list. |
This is the specific commit in the PR that makes the change, btw. |
Great! I've just updated to whole branch with the last commit supporting this new option. PS: Maybe a presharedKeyFile option could be also added to systemd ;-) |
How is this PR related to #64040 ? Should we keep both / merge them / close one? |
PR #64040 introduces wireguard related options as well as this PR, but there are some differences.
|
It does support it. If you prefer merging this one, please do add the nixos test I wrote in #64040 . |
(cherry picked from commit ec073e4)
I don't figure it out. I've tried to add this to the test
but
done. I've also removed the controversal part generating the systemd-networkd units from the options of networking.wireguard module. |
Thanks @dguibert. Closed the other one. My bad for the multi-peer faulty behavior. Looking forward to see this PR merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Motivation for this change
This patch make the wireguard interface more resilient and should fix #41874.
Things done
sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)nix path-info -S
before and after)