summaryrefslogtreecommitdiffstats
path: root/nixos/modules/services/networking/nm-file-secret-agent.nix
blob: 4e36605b242d5ebb9608f3a17ab11070b515d6e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.networking.networkmanager;
  toml = pkgs.formats.toml { };

  enabled = (lib.length cfg.ensureProfiles.secrets.entries) > 0;

  nmFileSecretAgentConfig = {
    entry = map (
      i:
      {
        key = i.key;
        file = i.file;
      }
      // lib.optionalAttrs (i.matchId != null) { match_id = i.matchId; }
      // lib.optionalAttrs (i.matchUuid != null) { match_uuid = i.matchUuid; }
      // lib.optionalAttrs (i.matchType != null) { match_type = i.matchType; }
      // lib.optionalAttrs (i.matchIface != null) { match_iface = i.matchIface; }
      // lib.optionalAttrs (i.matchSetting != null) {
        match_setting = i.matchSetting;
      }
      // lib.optionalAttrs (i.trim != null) { trim = i.trim; }
    ) cfg.ensureProfiles.secrets.entries;
  };
  nmFileSecretAgentConfigFile = toml.generate "config.toml" nmFileSecretAgentConfig;
in
{
  meta = {
    maintainers = [ lib.maintainers.lilioid ];
  };

  ####### interface
  options = {
    networking.networkmanager.ensureProfiles.secrets = {
      package = lib.mkPackageOption pkgs "nm-file-secret-agent" { };
      entries = lib.mkOption {
        description = ''
          A list of secrets to provide to NetworkManager by reading their values from configured files.

          Note that NetworkManager should be configured to read secrets from a secret agent.
          This can be done for example through the `networking.networkmanager.ensureProfiles.profiles` options.
        '';
        default = [ ];
        example = [
          {
            matchId = "My WireGuard VPN";
            matchType = "wireguard";
            matchSetting = "wireguard";
            key = "private-key";
            file = "/root/wireguard_key";
          }
        ];
        type = lib.types.listOf (
          lib.types.submodule {
            options = {
              matchId = lib.mkOption {
                description = ''
                  connection id used by NetworkManager. Often displayed as name in GUIs.

                  NetworkManager describes this as a human readable unique identifier for the connection, like "Work Wi-Fi" or "T-Mobile 3G".
                '';
                type = lib.types.nullOr lib.types.str;
                default = null;
                example = "wifi1";
              };
              matchUuid = lib.mkOption {
                description = ''
                  UUID of the connection profile

                  UUIDs are assigned once on connection creation and should never change as long as the connection still applies to the same network.
                '';
                type = lib.types.nullOr lib.types.str;
                default = null;
                example = "669ea4c9-4cb3-4901-ab52-f9606590976e";
              };
              matchType = lib.mkOption {
                description = ''
                  NetworkManager connection type

                  The NetworkManager configuration settings reference roughly corresponds to connection types.
                  More might be available on your system depending on the installed plugins.

                  <https://networkmanager.dev/docs/api/latest/ch01.html>
                '';
                type = lib.types.nullOr lib.types.str;
                default = null;
                example = "wireguard";
              };
              matchIface = lib.mkOption {
                description = "interface name of the NetworkManager connection";
                type = lib.types.nullOr lib.types.str;
                default = null;
              };
              matchSetting = lib.mkOption {
                description = "name of the setting section for which secrets are requested";
                type = lib.types.nullOr lib.types.str;
                default = null;
              };
              key = lib.mkOption {
                description = "key in the setting section for which this entry provides a value";
                type = lib.types.str;
              };
              file = lib.mkOption {
                description = "file from which the secret value is read";
                type = lib.types.str;
              };
              trim = lib.mkOption {
                description = "whether leading and trailing whitespace should be stripped from the files content before being passed to NetworkManager";
                type = lib.types.nullOr lib.types.bool;
                default = true;
              };
            };
          }
        );
      };
    };
  };

  ####### implementation
  config = lib.mkIf enabled {
    # start nm-file-secret-agent if required
    systemd.services."nm-file-secret-agent" = {
      description = "NetworkManager secret agent that responds with the content of preconfigured files";
      documentation = [ "https://github.com/lilioid/nm-file-secret-agent/" ];
      requires = [ "NetworkManager.service" ];
      after = [ "NetworkManager.service" ];
      wantedBy = [ "multi-user.target" ];
      restartTriggers = [ nmFileSecretAgentConfigFile ];
      script = "${lib.getExe cfg.ensureProfiles.secrets.package} --conf ${nmFileSecretAgentConfigFile}";
    };
  };
}