]> Git — Sourcephile - julm/julm-nix.git/blob - nixpkgs/patches/openvpn/0001-nixos-netns-init-module-to-manage-network-namespaces.patch
nix: update to nixos-25.05
[julm/julm-nix.git] / nixpkgs / patches / openvpn / 0001-nixos-netns-init-module-to-manage-network-namespaces.patch
1 From 6805353e349165acb54e59abff10c53ea9069da7 Mon Sep 17 00:00:00 2001
2 From: Julien Moutinho <julm+nixpkgs@sourcephile.fr>
3 Date: Sun, 17 Jan 2021 15:28:13 +0100
4 Subject: [PATCH 1/2] nixos/netns: init module to manage network namespaces
5
6 ---
7 nixos/modules/module-list.nix | 1 +
8 nixos/modules/services/networking/netns.nix | 133 ++++++++++++++++++++
9 2 files changed, 134 insertions(+)
10 create mode 100644 nixos/modules/services/networking/netns.nix
11
12 diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
13 index 79f5c22f5b..a350346754 100644
14 --- a/nixos/modules/module-list.nix
15 +++ b/nixos/modules/module-list.nix
16 @@ -1235,6 +1235,7 @@
17 ./services/networking/netclient.nix
18 ./services/networking/networkd-dispatcher.nix
19 ./services/networking/networkmanager.nix
20 + ./services/networking/netns.nix
21 ./services/networking/nextdns.nix
22 ./services/networking/nftables.nix
23 ./services/networking/nghttpx/default.nix
24 diff --git a/nixos/modules/services/networking/netns.nix b/nixos/modules/services/networking/netns.nix
25 new file mode 100644
26 index 0000000000..eb05d0c0fd
27 --- /dev/null
28 +++ b/nixos/modules/services/networking/netns.nix
29 @@ -0,0 +1,133 @@
30 +{
31 + pkgs,
32 + lib,
33 + config,
34 + options,
35 + ...
36 +}:
37 +with lib;
38 +let
39 + cfg = config.services.netns;
40 + inherit (config) networking;
41 + # Escape as required by: https://www.freedesktop.org/software/systemd/man/systemd.unit.html
42 + escapeUnitName =
43 + name:
44 + lib.concatMapStrings (s: if lib.isList s then "-" else s) (
45 + builtins.split "[^a-zA-Z0-9_.\\-]+" name
46 + );
47 +in
48 +{
49 + options.services.netns = {
50 + namespaces = mkOption {
51 + description = ''
52 + Network namespaces to create.
53 +
54 + Other services can join a network namespace named `netns` with:
55 + ```
56 + PrivateNetwork=true;
57 + JoinsNamespaceOf="netns-''${netns}.service";
58 + ```
59 +
60 + So can `iproute2` with: `ip -n ''${netns}`
61 +
62 + ::: {.warning}
63 + You should usually create (or update via your VPN configuration's up script)
64 + a file named `/etc/netns/''${netns}/resolv.conf`
65 + that will be bind-mounted by `ip -n ''${netns}` onto `/etc/resolv.conf`,
66 + which you'll also want to configure in the services joining this network namespace:
67 + ```
68 + BindReadOnlyPaths = ["/etc/netns/''${netns}/resolv.conf:/etc/resolv.conf"];
69 + ```
70 + :::
71 + '';
72 + default = { };
73 + type = types.attrsOf (
74 + types.submodule {
75 + options.nftables = mkOption {
76 + description = "Nftables ruleset within the network namespace.";
77 + type = types.lines;
78 + default = networking.nftables.ruleset;
79 + defaultText = "config.networking.nftables.ruleset";
80 + };
81 + options.sysctl = options.boot.kernel.sysctl // {
82 + description = "sysctl within the network namespace.";
83 + default = config.boot.kernel.sysctl;
84 + defaultText = literalMD "config.boot.kernel.sysctl";
85 + };
86 + options.service = mkOption {
87 + description = "Systemd configuration specific to this netns service";
88 + type = types.attrs;
89 + default = { };
90 + };
91 + }
92 + );
93 + };
94 + };
95 + config = {
96 + systemd.services = mapAttrs' (
97 + name: c:
98 + nameValuePair "netns-${escapeUnitName name}" (mkMerge [
99 + {
100 + description = "${name} network namespace";
101 + before = [ "network.target" ];
102 + serviceConfig = {
103 + Type = "oneshot";
104 + RemainAfterExit = true;
105 + # Let systemd create the netns so that PrivateNetwork=true
106 + # with JoinsNamespaceOf="netns-${name}.service" works.
107 + PrivateNetwork = true;
108 + # PrivateNetwork=true implies PrivateMounts=true by default,
109 + # which would prevent the persisting and sharing of /var/run/netns/$name
110 + # causing `ip netns exec $name $SHELL` outside of this service to fail with:
111 + # Error: Peer netns reference is invalid.
112 + # As `stat -f -c %T /var/run/netns/$name` would not be "nsfs" in those mntns.
113 + # See https://serverfault.com/questions/961504/cannot-create-nested-network-namespace
114 + PrivateMounts = false;
115 + ExecStart =
116 + [
117 + # Register the netns with a binding mount to /var/run/netns/$name to keep it alive,
118 + # and make sure resolv.conf can be used in BindReadOnlyPaths=
119 + # For propagating changes in that file to the services bind mounting it,
120 + # updating must not remove the file, but only truncate it.
121 + (pkgs.writeShellScript "ip-netns-attach" ''
122 + ${pkgs.iproute2}/bin/ip netns attach ${escapeShellArg name} $$
123 + mkdir -p /etc/netns/${escapeShellArg name}
124 + touch /etc/netns/${escapeShellArg name}/resolv.conf
125 + '')
126 +
127 + # Bringing the loopback interface is almost always a good thing.
128 + "${pkgs.iproute2}/bin/ip link set dev lo up"
129 +
130 + # Use --ignore because some keys may no longer exist in that new namespace,
131 + # like net.ipv6.conf.eth0.addr_gen_mode or net.core.rmem_max
132 + ''
133 + ${pkgs.procps}/bin/sysctl --ignore -p ${
134 + pkgs.writeScript "sysctl" (
135 + concatStrings (
136 + mapAttrsToList (
137 + n: v: optionalString (v != null) "${n}=${if v == false then "0" else toString v}\n"
138 + ) c.sysctl
139 + )
140 + )
141 + }
142 + ''
143 + ]
144 + ++
145 + # Load the nftables ruleset of this netns.
146 + optional networking.nftables.enable (
147 + pkgs.writeScript "nftables-ruleset" ''
148 + #!${pkgs.nftables}/bin/nft -f
149 + flush ruleset
150 + ${c.nftables}
151 + ''
152 + );
153 + # Unregister the netns from the tracking mecanism of iproute2.
154 + ExecStop = "${pkgs.iproute2}/bin/ip netns delete ${escapeShellArg name}";
155 + };
156 + }
157 + c.service
158 + ])
159 + ) cfg.namespaces;
160 + meta.maintainers = with lib.maintainers; [ julm ];
161 + };
162 +}
163 --
164 2.47.2
165