vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / networking / iodine.nix
blob2bdfa6f1b844a5a3646ac538b6052379616d4d4d
1 # NixOS module for iodine, ip over dns daemon
2 { config, lib, pkgs, ... }:
3 let
4   cfg = config.services.iodine;
6   iodinedUser = "iodined";
8   /* is this path made unreadable by ProtectHome = true ? */
9   isProtected = x: lib.hasPrefix "/root" x || lib.hasPrefix "/home" x;
12   imports = [
13     (lib.mkRenamedOptionModule [ "services" "iodined" "enable" ] [ "services" "iodine" "server" "enable" ])
14     (lib.mkRenamedOptionModule [ "services" "iodined" "domain" ] [ "services" "iodine" "server" "domain" ])
15     (lib.mkRenamedOptionModule [ "services" "iodined" "ip" ] [ "services" "iodine" "server" "ip" ])
16     (lib.mkRenamedOptionModule [ "services" "iodined" "extraConfig" ] [ "services" "iodine" "server" "extraConfig" ])
17     (lib.mkRemovedOptionModule [ "services" "iodined" "client" ] "")
18   ];
20   ### configuration
22   options = {
24     services.iodine = {
25       clients = lib.mkOption {
26         default = {};
27         description = ''
28           Each attribute of this option defines a systemd service that
29           runs iodine. Many or none may be defined.
30           The name of each service is
31           `iodine-«name»`
32           where «name» is the name of the
33           corresponding attribute name.
34         '';
35         example = lib.literalExpression ''
36           {
37             foo = {
38               server = "tunnel.mdomain.com";
39               relay = "8.8.8.8";
40               extraConfig = "-v";
41             }
42           }
43         '';
44         type = lib.types.attrsOf (
45           lib.types.submodule (
46             {
47               options = {
48                 server = lib.mkOption {
49                   type = lib.types.str;
50                   default = "";
51                   description = "Hostname of server running iodined";
52                   example = "tunnel.mydomain.com";
53                 };
55                 relay = lib.mkOption {
56                   type = lib.types.str;
57                   default = "";
58                   description = "DNS server to use as an intermediate relay to the iodined server";
59                   example = "8.8.8.8";
60                 };
62                 extraConfig = lib.mkOption {
63                   type = lib.types.str;
64                   default = "";
65                   description = "Additional command line parameters";
66                   example = "-l 192.168.1.10 -p 23";
67                 };
69                 passwordFile = lib.mkOption {
70                   type = lib.types.str;
71                   default = "";
72                   description = "Path to a file containing the password.";
73                 };
74               };
75             }
76           )
77         );
78       };
80       server = {
81         enable = lib.mkOption {
82           type = lib.types.bool;
83           default = false;
84           description = "enable iodined server";
85         };
87         ip = lib.mkOption {
88           type = lib.types.str;
89           default = "";
90           description = "The assigned ip address or ip range";
91           example = "172.16.10.1/24";
92         };
94         domain = lib.mkOption {
95           type = lib.types.str;
96           default = "";
97           description = "Domain or subdomain of which nameservers point to us";
98           example = "tunnel.mydomain.com";
99         };
101         extraConfig = lib.mkOption {
102           type = lib.types.str;
103           default = "";
104           description = "Additional command line parameters";
105           example = "-l 192.168.1.10 -p 23";
106         };
108         passwordFile = lib.mkOption {
109           type = lib.types.str;
110           default = "";
111           description = "File that contains password";
112         };
113       };
115     };
116   };
118   ### implementation
120   config = lib.mkIf (cfg.server.enable || cfg.clients != {}) {
121     environment.systemPackages = [ pkgs.iodine ];
122     boot.kernelModules = [ "tun" ];
124     systemd.services =
125       let
126         createIodineClientService = name: cfg:
127           {
128             description = "iodine client - ${name}";
129             after = [ "network.target" ];
130             wantedBy = [ "multi-user.target" ];
131             script = "exec ${pkgs.iodine}/bin/iodine -f -u ${iodinedUser} ${cfg.extraConfig} ${lib.optionalString (cfg.passwordFile != "") "< \"${builtins.toString cfg.passwordFile}\""} ${cfg.relay} ${cfg.server}";
132             serviceConfig = {
133               RestartSec = "30s";
134               Restart = "always";
136               # hardening :
137               # Filesystem access
138               ProtectSystem = "strict";
139               ProtectHome = if isProtected cfg.passwordFile then "read-only" else "true" ;
140               PrivateTmp = true;
141               ReadWritePaths = "/dev/net/tun";
142               PrivateDevices = false;
143               ProtectKernelTunables = true;
144               ProtectKernelModules = true;
145               ProtectControlGroups = true;
146               # Caps
147               NoNewPrivileges = true;
148               # Misc.
149               LockPersonality = true;
150               RestrictRealtime = true;
151               PrivateMounts = true;
152               MemoryDenyWriteExecute = true;
153             };
154           };
155       in
156         lib.listToAttrs (
157           lib.mapAttrsToList
158             (name: value: lib.nameValuePair "iodine-${name}" (createIodineClientService name value))
159             cfg.clients
160         ) // {
161           iodined = lib.mkIf (cfg.server.enable) {
162             description = "iodine, ip over dns server daemon";
163             after = [ "network.target" ];
164             wantedBy = [ "multi-user.target" ];
165             script = "exec ${pkgs.iodine}/bin/iodined -f -u ${iodinedUser} ${cfg.server.extraConfig} ${lib.optionalString (cfg.server.passwordFile != "") "< \"${builtins.toString cfg.server.passwordFile}\""} ${cfg.server.ip} ${cfg.server.domain}";
166             serviceConfig = {
167               # Filesystem access
168               ProtectSystem = "strict";
169               ProtectHome = if isProtected cfg.server.passwordFile then "read-only" else "true" ;
170               PrivateTmp = true;
171               ReadWritePaths = "/dev/net/tun";
172               PrivateDevices = false;
173               ProtectKernelTunables = true;
174               ProtectKernelModules = true;
175               ProtectControlGroups = true;
176               # Caps
177               NoNewPrivileges = true;
178               # Misc.
179               LockPersonality = true;
180               RestrictRealtime = true;
181               PrivateMounts = true;
182               MemoryDenyWriteExecute = true;
183             };
184           };
185         };
187     users.users.${iodinedUser} = {
188       uid = config.ids.uids.iodined;
189       group = "iodined";
190       description = "Iodine daemon user";
191     };
192     users.groups.iodined.gid = config.ids.gids.iodined;
193   };