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