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 = "-P mysecurepassword";
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 = "-P mysecurepassword -l 192.168.1.10 -p 23";
61 };
62 };
63 }));
64 };
65
66 server = {
67 enable = mkOption {
68 type = types.bool;
69 default = false;
70 description = "enable iodined server";
71 };
72
73 ip = mkOption {
74 type = types.str;
75 default = "";
76 description = "The assigned ip address or ip range";
77 example = "172.16.10.1/24";
78 };
79
80 domain = mkOption {
81 type = types.str;
82 default = "";
83 description = "Domain or subdomain of which nameservers point to us";
84 example = "tunnel.mydomain.com";
85 };
86
87 extraConfig = mkOption {
88 type = types.str;
89 default = "";
90 description = "Additional command line parameters";
91 example = "-P mysecurepassword -l 192.168.1.10 -p 23";
92 };
93 };
94
95 };
96 };
97
98 ### implementation
99
100 config = mkIf (cfg.server.enable || cfg.clients != {}) {
101 environment.systemPackages = [ pkgs.iodine ];
102 boot.kernelModules = [ "tun" ];
103
104 systemd.services =
105 let
106 createIodineClientService = name: cfg:
107 {
108 description = "iodine client - ${name}";
109 after = [ "network.target" ];
110 wantedBy = [ "multi-user.target" ];
111 serviceConfig = {
112 RestartSec = "30s";
113 Restart = "always";
114 ExecStart = "${pkgs.iodine}/bin/iodine -f -u ${iodinedUser} ${cfg.extraConfig} ${cfg.relay} ${cfg.server}";
115 };
116 };
117 in
118 listToAttrs (
119 mapAttrsToList
120 (name: value: nameValuePair "iodine-${name}" (createIodineClientService name value))
121 cfg.clients
122 ) // {
123 iodined = mkIf (cfg.server.enable) {
124 description = "iodine, ip over dns server daemon";
125 after = [ "network.target" ];
126 wantedBy = [ "multi-user.target" ];
127 serviceConfig.ExecStart = "${pkgs.iodine}/bin/iodined -f -u ${iodinedUser} ${cfg.server.extraConfig} ${cfg.server.ip} ${cfg.server.domain}";
128 };
129 };
130
131 users.extraUsers = singleton {
132 name = iodinedUser;
133 uid = config.ids.uids.iodined;
134 description = "Iodine daemon user";
135 };
136 users.extraGroups.iodined.gid = config.ids.gids.iodined;
137 };
138}