1# NixOS module for iodine, ip over dns daemon
2
3{ config, lib, pkgs, ... }:
4
5with lib;
6
7let
8 cfg = config.services.iodine;
9
10 iodinedUser = "iodined";
11
12in
13{
14
15 ### configuration
16
17 options = {
18
19 services.iodine = {
20 clients = mkOption {
21 default = {};
22 description = ''
23 Each attribute of this option defines a systemd service that
24 runs iodine. Many or none may be defined.
25 The name of each service is
26 <literal>iodine-<replaceable>name</replaceable></literal>
27 where <replaceable>name</replaceable> is the name of the
28 corresponding attribute name.
29 '';
30 example = literalExample ''
31 {
32 foo = {
33 server = "tunnel.mdomain.com";
34 relay = "8.8.8.8";
35 extraConfig = "-v";
36 }
37 }
38 '';
39 type = types.attrsOf (types.submodule (
40 {
41 options = {
42 server = mkOption {
43 type = types.str;
44 default = "";
45 description = "Domain or Subdomain of server running iodined";
46 example = "tunnel.mydomain.com";
47 };
48
49 relay = mkOption {
50 type = types.str;
51 default = "";
52 description = "DNS server to use as a intermediate relay to the iodined server";
53 example = "8.8.8.8";
54 };
55
56 extraConfig = mkOption {
57 type = types.str;
58 default = "";
59 description = "Additional command line parameters";
60 example = "-l 192.168.1.10 -p 23";
61 };
62
63 passwordFile = mkOption {
64 type = types.str;
65 default = "";
66 description = "File that containts password";
67 };
68 };
69 }));
70 };
71
72 server = {
73 enable = mkOption {
74 type = types.bool;
75 default = false;
76 description = "enable iodined server";
77 };
78
79 ip = mkOption {
80 type = types.str;
81 default = "";
82 description = "The assigned ip address or ip range";
83 example = "172.16.10.1/24";
84 };
85
86 domain = mkOption {
87 type = types.str;
88 default = "";
89 description = "Domain or subdomain of which nameservers point to us";
90 example = "tunnel.mydomain.com";
91 };
92
93 extraConfig = mkOption {
94 type = types.str;
95 default = "";
96 description = "Additional command line parameters";
97 example = "-l 192.168.1.10 -p 23";
98 };
99
100 passwordFile = mkOption {
101 type = types.str;
102 default = "";
103 description = "File that containts password";
104 };
105 };
106
107 };
108 };
109
110 ### implementation
111
112 config = mkIf (cfg.server.enable || cfg.clients != {}) {
113 environment.systemPackages = [ pkgs.iodine ];
114 boot.kernelModules = [ "tun" ];
115
116 systemd.services =
117 let
118 createIodineClientService = name: cfg:
119 {
120 description = "iodine client - ${name}";
121 after = [ "network.target" ];
122 wantedBy = [ "multi-user.target" ];
123 script = "${pkgs.iodine}/bin/iodine -f -u ${iodinedUser} ${cfg.extraConfig} ${optionalString (cfg.passwordFile != "") "-P $(cat \"${cfg.passwordFile}\")"} ${cfg.relay} ${cfg.server}";
124 serviceConfig = {
125 RestartSec = "30s";
126 Restart = "always";
127 };
128 };
129 in
130 listToAttrs (
131 mapAttrsToList
132 (name: value: nameValuePair "iodine-${name}" (createIodineClientService name value))
133 cfg.clients
134 ) // {
135 iodined = mkIf (cfg.server.enable) {
136 description = "iodine, ip over dns server daemon";
137 after = [ "network.target" ];
138 wantedBy = [ "multi-user.target" ];
139 script = "${pkgs.iodine}/bin/iodined -f -u ${iodinedUser} ${cfg.server.extraConfig} ${optionalString (cfg.server.passwordFile != "") "-P $(cat \"${cfg.server.passwordFile}\")"} ${cfg.server.ip} ${cfg.server.domain}";
140 };
141 };
142
143 users.users = singleton {
144 name = iodinedUser;
145 uid = config.ids.uids.iodined;
146 description = "Iodine daemon user";
147 };
148 users.groups.iodined.gid = config.ids.gids.iodined;
149 };
150}