1 # NixOS module for iodine, ip over dns daemon
2 { config, lib, pkgs, ... }:
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;
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" ] "")
25 clients = lib.mkOption {
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
32 where «name» is the name of the
33 corresponding attribute name.
35 example = lib.literalExpression ''
38 server = "tunnel.mdomain.com";
44 type = lib.types.attrsOf (
48 server = lib.mkOption {
51 description = "Hostname of server running iodined";
52 example = "tunnel.mydomain.com";
55 relay = lib.mkOption {
58 description = "DNS server to use as an intermediate relay to the iodined server";
62 extraConfig = lib.mkOption {
65 description = "Additional command line parameters";
66 example = "-l 192.168.1.10 -p 23";
69 passwordFile = lib.mkOption {
72 description = "Path to a file containing the password.";
81 enable = lib.mkOption {
82 type = lib.types.bool;
84 description = "enable iodined server";
90 description = "The assigned ip address or ip range";
91 example = "172.16.10.1/24";
94 domain = lib.mkOption {
97 description = "Domain or subdomain of which nameservers point to us";
98 example = "tunnel.mydomain.com";
101 extraConfig = lib.mkOption {
102 type = lib.types.str;
104 description = "Additional command line parameters";
105 example = "-l 192.168.1.10 -p 23";
108 passwordFile = lib.mkOption {
109 type = lib.types.str;
111 description = "File that contains password";
120 config = lib.mkIf (cfg.server.enable || cfg.clients != {}) {
121 environment.systemPackages = [ pkgs.iodine ];
122 boot.kernelModules = [ "tun" ];
126 createIodineClientService = name: cfg:
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}";
138 ProtectSystem = "strict";
139 ProtectHome = if isProtected cfg.passwordFile then "read-only" else "true" ;
141 ReadWritePaths = "/dev/net/tun";
142 PrivateDevices = false;
143 ProtectKernelTunables = true;
144 ProtectKernelModules = true;
145 ProtectControlGroups = true;
147 NoNewPrivileges = true;
149 LockPersonality = true;
150 RestrictRealtime = true;
151 PrivateMounts = true;
152 MemoryDenyWriteExecute = true;
158 (name: value: lib.nameValuePair "iodine-${name}" (createIodineClientService name value))
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}";
168 ProtectSystem = "strict";
169 ProtectHome = if isProtected cfg.server.passwordFile then "read-only" else "true" ;
171 ReadWritePaths = "/dev/net/tun";
172 PrivateDevices = false;
173 ProtectKernelTunables = true;
174 ProtectKernelModules = true;
175 ProtectControlGroups = true;
177 NoNewPrivileges = true;
179 LockPersonality = true;
180 RestrictRealtime = true;
181 PrivateMounts = true;
182 MemoryDenyWriteExecute = true;
187 users.users.${iodinedUser} = {
188 uid = config.ids.uids.iodined;
190 description = "Iodine daemon user";
192 users.groups.iodined.gid = config.ids.gids.iodined;