1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.i2pd;
8
9 homeDir = "/var/lib/i2pd";
10
11 extip = "EXTIP=\$(${pkgs.curl}/bin/curl -sf \"http://jsonip.com\" | ${pkgs.gawk}/bin/awk -F'\"' '{print $4}')";
12
13 i2pSh = pkgs.writeScriptBin "i2pd" ''
14 #!/bin/sh
15 ${if isNull cfg.extIp then extip else ""}
16 ${pkgs.i2pd}/bin/i2p --log=1 --daemon=0 --service=0 \
17 --v6=${if cfg.enableIPv6 then "1" else "0"} \
18 --unreachable=${if cfg.unreachable then "1" else "0"} \
19 --host=${if isNull cfg.extIp then "$EXTIP" else cfg.extIp} \
20 ${if isNull cfg.port then "" else "--port=${toString cfg.port}"} \
21 --httpproxyport=${toString cfg.proxy.httpPort} \
22 --socksproxyport=${toString cfg.proxy.socksPort} \
23 --ircport=${toString cfg.irc.port} \
24 --ircdest=${cfg.irc.dest} \
25 --irckeys=${cfg.irc.keyFile} \
26 --eepport=${toString cfg.eep.port} \
27 ${if isNull cfg.sam.port then "" else "--samport=${toString cfg.sam.port}"} \
28 --eephost=${cfg.eep.host} \
29 --eepkeys=${cfg.eep.keyFile}
30 '';
31
32in
33
34{
35
36 ###### interface
37
38 options = {
39
40 services.i2pd = {
41
42 enable = mkOption {
43 type = types.bool;
44 default = false;
45 description = ''
46 Enables I2Pd as a running service upon activation.
47 '';
48 };
49
50 extIp = mkOption {
51 type = with types; nullOr str;
52 default = null;
53 description = ''
54 Your external IP.
55 '';
56 };
57
58 unreachable = mkOption {
59 type = types.bool;
60 default = false;
61 description = ''
62 If the router is declared to be unreachable and needs introduction nodes.
63 '';
64 };
65
66 port = mkOption {
67 type = with types; nullOr int;
68 default = null;
69 description = ''
70 I2P listen port. If no one is given the router will pick between 9111 and 30777.
71 '';
72 };
73
74 enableIPv6 = mkOption {
75 type = types.bool;
76 default = false;
77 description = ''
78 Enables IPv6 connectivity. Disabled by default.
79 '';
80 };
81
82 http = {
83 port = mkOption {
84 type = types.int;
85 default = 7070;
86 description = ''
87 HTTP listen port.
88 '';
89 };
90 };
91
92 proxy = {
93 httpPort = mkOption {
94 type = types.int;
95 default = 4446;
96 description = ''
97 HTTP proxy listen port.
98 '';
99 };
100 socksPort = mkOption {
101 type = types.int;
102 default = 4447;
103 description = ''
104 SOCKS proxy listen port.
105 '';
106 };
107 };
108
109 irc = {
110 dest = mkOption {
111 type = types.str;
112 default = "irc.postman.i2p";
113 description = ''
114 Destination I2P tunnel endpoint address of IRC server. irc.postman.i2p by default.
115 '';
116 };
117 port = mkOption {
118 type = types.int;
119 default = 6668;
120 description = ''
121 Local IRC tunnel endoint port to listen on. 6668 by default.
122 '';
123 };
124 keyFile = mkOption {
125 type = types.str;
126 default = "privKeys.dat";
127 description = ''
128 File name containing destination keys. privKeys.dat by default.
129 '';
130 };
131 };
132
133 eep = {
134 host = mkOption {
135 type = types.str;
136 default = "127.0.0.1";
137 description = ''
138 Address to forward incoming traffic to. 127.0.0.1 by default.
139 '';
140 };
141 port = mkOption {
142 type = types.int;
143 default = 80;
144 description = ''
145 Port to forward incoming traffic to. 80 by default.
146 '';
147 };
148 keyFile = mkOption {
149 type = types.str;
150 default = "privKeys.dat";
151 description = ''
152 File name containing destination keys. privKeys.dat by default.
153 '';
154 };
155 };
156
157 sam = {
158 port = mkOption {
159 type = with types; nullOr int;
160 default = null;
161 description = ''
162 Local SAM tunnel endpoint. Usually 7656. SAM is disabled if not specified.
163 '';
164 };
165 };
166 };
167 };
168
169
170 ###### implementation
171
172 config = mkIf cfg.enable {
173
174 users.extraUsers.i2pd = {
175 group = "i2pd";
176 description = "I2Pd User";
177 home = homeDir;
178 createHome = true;
179 uid = config.ids.uids.i2pd;
180 };
181
182 users.extraGroups.i2pd.gid = config.ids.gids.i2pd;
183
184 systemd.services.i2pd = {
185 description = "Minimal I2P router";
186 after = [ "network.target" ];
187 wantedBy = [ "multi-user.target" ];
188 serviceConfig =
189 {
190 User = "i2pd";
191 WorkingDirectory = homeDir;
192 Restart = "on-abort";
193 ExecStart = "${i2pSh}/bin/i2pd";
194 };
195 };
196 };
197}
198#