]> Git — Sourcephile - sourcephile-nix.git/blob - nixos/modules/services/networking/netns.nix
users: factorize rights
[sourcephile-nix.git] / nixos / modules / services / networking / netns.nix
1 { pkgs, lib, config, options, ... }:
2 with lib;
3 let
4 cfg = config.services.netns;
5 inherit (config) networking;
6 # Escape as required by: https://www.freedesktop.org/software/systemd/man/systemd.unit.html
7 escapeUnitName = name:
8 lib.concatMapStrings (s: if lib.isList s then "-" else s)
9 (builtins.split "[^a-zA-Z0-9_.\\-]+" name);
10 systemd = import (pkgs.path + "/nixos/modules/system/boot/systemd-unit-options.nix") { inherit config lib; };
11 in
12 {
13 options.services.netns = {
14 namespaces = mkOption {
15 description = "netns namespaces to create";
16 type = types.attrsOf (types.submodule {
17 options = {
18 nftables = mkOption {
19 type = types.lines;
20 default = networking.nftables.ruleset;
21 description = ''
22 Nftables ruleset.
23 '';
24 };
25 sysctl = options.boot.kernel.sysctl // {
26 default = config.boot.kernel.sysctl;
27 };
28 service = mkOption {
29 # Avoid error: The option `services.netns.namespaces.${netns}.service.startLimitIntervalSec' is used but not defined.
30 #type = types.submodule [ { options = builtins.removeAttrs systemd.serviceOptions ["startLimitIntervalSec"]; } ];
31 type = types.attrs;
32 default = {};
33 description = ''
34 Systemd configuration specific to this netns service.
35 '';
36 };
37 };
38 });
39 default = {};
40 };
41 };
42 config = {
43 systemd.services = mapAttrs' (name: c:
44 nameValuePair "netns-${escapeUnitName name}" (mkMerge [
45 { description = mkForce "${name} network namespace";
46 before = [ "network.target" ];
47 serviceConfig = {
48 Type = mkForce "oneshot";
49 RemainAfterExit = true;
50 PrivateNetwork = true;
51 ExecStart = mkForce (pkgs.writeShellScript "netns-start" ''
52 test -e /var/run/netns/${escapeShellArg name} ||
53 ${pkgs.iproute}/bin/ip netns add ${escapeShellArg name}
54 '');
55 ExecStartPost =
56 # Use --ignore because some keys may no longer exist in that new namespace,
57 # like net.ipv6.conf.eth0.addr_gen_mode or net.core.rmem_max
58 [''${pkgs.iproute}/bin/ip netns exec ${escapeShellArg name} ${pkgs.procps}/bin/sysctl --ignore -p ${pkgs.writeScript "sysctl"
59 (concatStrings (mapAttrsToList (n: v: optionalString (v != null) "${n}=${if v == false then "0" else toString v}\n") c.sysctl))}
60 ''] ++
61 optional networking.nftables.enable ''
62 ${pkgs.iproute}/bin/ip netns exec ${escapeShellArg name} ${pkgs.writeScript "nftables-ruleset" ''
63 #!${pkgs.nftables}/bin/nft -f
64 flush ruleset
65 ${c.nftables}
66 ''}
67 '';
68 ExecStop = mkForce "${pkgs.iproute}/bin/ip netns del ${escapeShellArg name}";
69 };
70 }
71 c.service
72 ]
73 )) cfg.namespaces;
74 meta.maintainers = with lib.maintainers; [ julm ];
75 };
76 }