1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.aiccu;
8 showBool = b: if b then "true" else "false";
9 notNull = a: ! isNull a;
10 configFile = pkgs.writeText "aiccu.conf" ''
11 ${if notNull cfg.username then "username " + cfg.username else ""}
12 ${if notNull cfg.password then "password " + cfg.password else ""}
13 protocol ${cfg.protocol}
14 server ${cfg.server}
15 ipv6_interface ${cfg.interfaceName}
16 verbose ${showBool cfg.verbose}
17 daemonize true
18 automatic ${showBool cfg.automatic}
19 requiretls ${showBool cfg.requireTLS}
20 pidfile ${cfg.pidFile}
21 defaultroute ${showBool cfg.defaultRoute}
22 ${if notNull cfg.setupScript then cfg.setupScript else ""}
23 makebeats ${showBool cfg.makeHeartBeats}
24 noconfigure ${showBool cfg.noConfigure}
25 behindnat ${showBool cfg.behindNAT}
26 ${if cfg.localIPv4Override then "local_ipv4_override" else ""}
27 '';
28
29in {
30
31 options = {
32
33 services.aiccu = {
34
35 enable = mkOption {
36 type = types.bool;
37 default = false;
38 example = true;
39 description = "Enable aiccu IPv6 over IPv4 SiXXs tunnel";
40 };
41
42 username = mkOption {
43 type = with types; nullOr str;
44 default = null;
45 example = "FAB5-SIXXS";
46 description = "Login credential";
47 };
48
49 password = mkOption {
50 type = with types; nullOr str;
51 default = null;
52 example = "TmAkRbBEr0";
53 description = "Login credential";
54 };
55
56 protocol = mkOption {
57 type = types.str;
58 default = "tic";
59 example = "tic|tsp|l2tp";
60 description = "Protocol to use for setting up the tunnel";
61 };
62
63 server = mkOption {
64 type = types.str;
65 default = "tic.sixxs.net";
66 example = "enabled.ipv6server.net";
67 description = "Server to use for setting up the tunnel";
68 };
69
70 interfaceName = mkOption {
71 type = types.str;
72 default = "aiccu";
73 example = "sixxs";
74 description = ''
75 The name of the interface that will be used as a tunnel interface.
76 On *BSD the ipv6_interface should be set to gifX (eg gif0) for proto-41 tunnels
77 or tunX (eg tun0) for AYIYA tunnels.
78 '';
79 };
80
81 tunnelID = mkOption {
82 type = with types; nullOr str;
83 default = null;
84 example = "T12345";
85 description = "The tunnel id to use, only required when there are multiple tunnels in the list";
86 };
87
88 verbose = mkOption {
89 type = types.bool;
90 default = false;
91 example = true;
92 description = "Be verbose?";
93 };
94
95 automatic = mkOption {
96 type = types.bool;
97 default = true;
98 example = false;
99 description = "Automatic Login and Tunnel activation";
100 };
101
102 requireTLS = mkOption {
103 type = types.bool;
104 default = false;
105 example = true;
106 description = ''
107 When set to true, if TLS is not supported on the server
108 the TIC transaction will fail.
109 When set to false, it will try a starttls, when that is
110 not supported it will continue.
111 In any case if AICCU is build with TLS support it will
112 try to do a 'starttls' to the TIC server to see if that
113 is supported.
114 '';
115 };
116
117 pidFile = mkOption {
118 type = types.path;
119 default = "/run/aiccu.pid";
120 example = "/var/lib/aiccu/aiccu.pid";
121 description = "Location of PID File";
122 };
123
124 defaultRoute = mkOption {
125 type = types.bool;
126 default = true;
127 example = false;
128 description = "Add a default route";
129 };
130
131 setupScript = mkOption {
132 type = with types; nullOr path;
133 default = null;
134 example = "/var/lib/aiccu/fix-subnets.sh";
135 description = "Script to run after setting up the interfaces";
136 };
137
138 makeHeartBeats = mkOption {
139 type = types.bool;
140 default = true;
141 example = false;
142 description = ''
143 In general you don't want to turn this off
144 Of course only applies to AYIYA and heartbeat tunnels not to static ones
145 '';
146 };
147
148 noConfigure = mkOption {
149 type = types.bool;
150 default = false;
151 example = true;
152 description = "Don't configure anything";
153 };
154
155 behindNAT = mkOption {
156 type = types.bool;
157 default = false;
158 example = true;
159 description = "Notify the user that a NAT-kind network is detected";
160 };
161
162 localIPv4Override = mkOption {
163 type = types.bool;
164 default = false;
165 example = true;
166 description = ''
167 Overrides the IPv4 parameter received from TIC
168 This allows one to configure a NAT into "DMZ" mode and then
169 forwarding the proto-41 packets to an internal host.
170
171 This is only needed for static proto-41 tunnels!
172 AYIYA and heartbeat tunnels don't require this.
173 '';
174 };
175
176 };
177 };
178
179 config = mkIf cfg.enable {
180
181 systemd.services.aiccu = {
182 description = "Automatic IPv6 Connectivity Client Utility";
183 after = [ "network.target" ];
184 wantedBy = [ "multi-user.target" ];
185 serviceConfig = {
186 ExecStart = "${pkgs.aiccu}/bin/aiccu start ${configFile}";
187 ExecStop = "${pkgs.aiccu}/bin/aiccu stop";
188 Type = "forking";
189 PIDFile = cfg.pidFile;
190 Restart = "no"; # aiccu startup errors are serious, do not pound the tic server or be banned.
191 };
192 };
193
194 };
195}