1 # NixOS module for iodine, ip over dns daemon
3 { config, lib, pkgs, ... }:
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;
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" ] "")
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
36 where «name» is the name of the
37 corresponding attribute name.
39 example = literalExpression ''
42 server = "tunnel.mdomain.com";
48 type = types.attrsOf (
55 description = lib.mdDoc "Hostname of server running iodined";
56 example = "tunnel.mydomain.com";
62 description = lib.mdDoc "DNS server to use as an intermediate relay to the iodined server";
66 extraConfig = mkOption {
69 description = lib.mdDoc "Additional command line parameters";
70 example = "-l 192.168.1.10 -p 23";
73 passwordFile = mkOption {
76 description = lib.mdDoc "Path to a file containing the password.";
88 description = lib.mdDoc "enable iodined server";
94 description = lib.mdDoc "The assigned ip address or ip range";
95 example = "172.16.10.1/24";
101 description = lib.mdDoc "Domain or subdomain of which nameservers point to us";
102 example = "tunnel.mydomain.com";
105 extraConfig = mkOption {
108 description = lib.mdDoc "Additional command line parameters";
109 example = "-l 192.168.1.10 -p 23";
112 passwordFile = mkOption {
115 description = lib.mdDoc "File that contains password";
124 config = mkIf (cfg.server.enable || cfg.clients != {}) {
125 environment.systemPackages = [ pkgs.iodine ];
126 boot.kernelModules = [ "tun" ];
130 createIodineClientService = name: cfg:
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}";
142 ProtectSystem = "strict";
143 ProtectHome = if isProtected cfg.passwordFile then "read-only" else "true" ;
145 ReadWritePaths = "/dev/net/tun";
146 PrivateDevices = false;
147 ProtectKernelTunables = true;
148 ProtectKernelModules = true;
149 ProtectControlGroups = true;
151 NoNewPrivileges = true;
153 LockPersonality = true;
154 RestrictRealtime = true;
155 PrivateMounts = true;
156 MemoryDenyWriteExecute = true;
162 (name: value: nameValuePair "iodine-${name}" (createIodineClientService name value))
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}";
172 ProtectSystem = "strict";
173 ProtectHome = if isProtected cfg.server.passwordFile then "read-only" else "true" ;
175 ReadWritePaths = "/dev/net/tun";
176 PrivateDevices = false;
177 ProtectKernelTunables = true;
178 ProtectKernelModules = true;
179 ProtectControlGroups = true;
181 NoNewPrivileges = true;
183 LockPersonality = true;
184 RestrictRealtime = true;
185 PrivateMounts = true;
186 MemoryDenyWriteExecute = true;
191 users.users.${iodinedUser} = {
192 uid = config.ids.uids.iodined;
194 description = "Iodine daemon user";
196 users.groups.iodined.gid = config.ids.gids.iodined;