diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2020-01-15 20:41:19 +0100 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2020-01-15 20:41:19 +0100 |
commit | 981fa80354fd6f00f49446777c38f77bd8a65f65 (patch) | |
tree | 878a24e3daa325cfec75b1a413e5144829558d38 | |
parent | 258441019881c451686dbe537069228cc8e49612 (diff) | |
download | Nix-981fa80354fd6f00f49446777c38f77bd8a65f65.tar.gz Nix-981fa80354fd6f00f49446777c38f77bd8a65f65.tar.zst Nix-981fa80354fd6f00f49446777c38f77bd8a65f65.zip |
Upgrade acme bot
26 files changed, 495 insertions, 54 deletions
diff --git a/modules/acme2.nix b/modules/acme2.nix new file mode 100644 index 0000000..408c098 --- /dev/null +++ b/modules/acme2.nix | |||
@@ -0,0 +1,340 @@ | |||
1 | { config, lib, pkgs, ... }: | ||
2 | |||
3 | with lib; | ||
4 | |||
5 | let | ||
6 | |||
7 | cfg = config.security.acme2; | ||
8 | |||
9 | certOpts = { name, ... }: { | ||
10 | options = { | ||
11 | webroot = mkOption { | ||
12 | type = types.str; | ||
13 | example = "/var/lib/acme/acme-challenges"; | ||
14 | description = '' | ||
15 | Where the webroot of the HTTP vhost is located. | ||
16 | <filename>.well-known/acme-challenge/</filename> directory | ||
17 | will be created below the webroot if it doesn't exist. | ||
18 | <literal>http://example.org/.well-known/acme-challenge/</literal> must also | ||
19 | be available (notice unencrypted HTTP). | ||
20 | ''; | ||
21 | }; | ||
22 | |||
23 | server = mkOption { | ||
24 | type = types.nullOr types.str; | ||
25 | default = null; | ||
26 | description = '' | ||
27 | ACME Directory Resource URI. Defaults to let's encrypt | ||
28 | production endpoint, | ||
29 | https://acme-v02.api.letsencrypt.org/directory, if unset. | ||
30 | ''; | ||
31 | }; | ||
32 | |||
33 | domain = mkOption { | ||
34 | type = types.str; | ||
35 | default = name; | ||
36 | description = "Domain to fetch certificate for (defaults to the entry name)"; | ||
37 | }; | ||
38 | |||
39 | email = mkOption { | ||
40 | type = types.nullOr types.str; | ||
41 | default = null; | ||
42 | description = "Contact email address for the CA to be able to reach you."; | ||
43 | }; | ||
44 | |||
45 | user = mkOption { | ||
46 | type = types.str; | ||
47 | default = "root"; | ||
48 | description = "User running the ACME client."; | ||
49 | }; | ||
50 | |||
51 | group = mkOption { | ||
52 | type = types.str; | ||
53 | default = "root"; | ||
54 | description = "Group running the ACME client."; | ||
55 | }; | ||
56 | |||
57 | allowKeysForGroup = mkOption { | ||
58 | type = types.bool; | ||
59 | default = false; | ||
60 | description = '' | ||
61 | Give read permissions to the specified group | ||
62 | (<option>security.acme2.cert.<name>.group</option>) to read SSL private certificates. | ||
63 | ''; | ||
64 | }; | ||
65 | |||
66 | postRun = mkOption { | ||
67 | type = types.lines; | ||
68 | default = ""; | ||
69 | example = "systemctl reload nginx.service"; | ||
70 | description = '' | ||
71 | Commands to run after new certificates go live. Typically | ||
72 | the web server and other servers using certificates need to | ||
73 | be reloaded. | ||
74 | |||
75 | Executed in the same directory with the new certificate. | ||
76 | ''; | ||
77 | }; | ||
78 | |||
79 | plugins = mkOption { | ||
80 | type = types.listOf (types.enum [ | ||
81 | "cert.der" "cert.pem" "chain.pem" "external.sh" | ||
82 | "fullchain.pem" "full.pem" "key.der" "key.pem" "account_key.json" "account_reg.json" | ||
83 | ]); | ||
84 | default = [ "fullchain.pem" "full.pem" "key.pem" "account_key.json" "account_reg.json" ]; | ||
85 | description = '' | ||
86 | Plugins to enable. With default settings simp_le will | ||
87 | store public certificate bundle in <filename>fullchain.pem</filename>, | ||
88 | private key in <filename>key.pem</filename> and those two previous | ||
89 | files combined in <filename>full.pem</filename> in its state directory. | ||
90 | ''; | ||
91 | }; | ||
92 | |||
93 | directory = mkOption { | ||
94 | type = types.str; | ||
95 | readOnly = true; | ||
96 | default = "/var/lib/acme/${name}"; | ||
97 | description = "Directory where certificate and other state is stored."; | ||
98 | }; | ||
99 | |||
100 | extraDomains = mkOption { | ||
101 | type = types.attrsOf (types.nullOr types.str); | ||
102 | default = {}; | ||
103 | example = literalExample '' | ||
104 | { | ||
105 | "example.org" = "/srv/http/nginx"; | ||
106 | "mydomain.org" = null; | ||
107 | } | ||
108 | ''; | ||
109 | description = '' | ||
110 | A list of extra domain names, which are included in the one certificate to be issued, with their | ||
111 | own server roots if needed. | ||
112 | ''; | ||
113 | }; | ||
114 | }; | ||
115 | }; | ||
116 | |||
117 | in | ||
118 | |||
119 | { | ||
120 | |||
121 | ###### interface | ||
122 | imports = [ | ||
123 | (mkRemovedOptionModule [ "security" "acme2" "production" ] '' | ||
124 | Use security.acme2.server to define your staging ACME server URL instead. | ||
125 | |||
126 | To use the let's encrypt staging server, use security.acme2.server = | ||
127 | "https://acme-staging-v02.api.letsencrypt.org/directory". | ||
128 | '' | ||
129 | ) | ||
130 | (mkRemovedOptionModule [ "security" "acme2" "directory"] "ACME Directory is now hardcoded to /var/lib/acme and its permisisons are managed by systemd. See https://github.com/NixOS/nixpkgs/issues/53852 for more info.") | ||
131 | (mkRemovedOptionModule [ "security" "acme" "preDelay"] "This option has been removed. If you want to make sure that something executes before certificates are provisioned, add a RequiredBy=acme-\${cert}.service to the service you want to execute before the cert renewal") | ||
132 | (mkRemovedOptionModule [ "security" "acme" "activationDelay"] "This option has been removed. If you want to make sure that something executes before certificates are provisioned, add a RequiredBy=acme-\${cert}.service to the service you want to execute before the cert renewal") | ||
133 | ]; | ||
134 | options = { | ||
135 | security.acme2 = { | ||
136 | |||
137 | validMin = mkOption { | ||
138 | type = types.int; | ||
139 | default = 30 * 24 * 3600; | ||
140 | description = "Minimum remaining validity before renewal in seconds."; | ||
141 | }; | ||
142 | |||
143 | renewInterval = mkOption { | ||
144 | type = types.str; | ||
145 | default = "weekly"; | ||
146 | description = '' | ||
147 | Systemd calendar expression when to check for renewal. See | ||
148 | <citerefentry><refentrytitle>systemd.time</refentrytitle> | ||
149 | <manvolnum>7</manvolnum></citerefentry>. | ||
150 | ''; | ||
151 | }; | ||
152 | |||
153 | server = mkOption { | ||
154 | type = types.nullOr types.str; | ||
155 | default = null; | ||
156 | description = '' | ||
157 | ACME Directory Resource URI. Defaults to let's encrypt | ||
158 | production endpoint, | ||
159 | <literal>https://acme-v02.api.letsencrypt.org/directory</literal>, if unset. | ||
160 | ''; | ||
161 | }; | ||
162 | |||
163 | preliminarySelfsigned = mkOption { | ||
164 | type = types.bool; | ||
165 | default = true; | ||
166 | description = '' | ||
167 | Whether a preliminary self-signed certificate should be generated before | ||
168 | doing ACME requests. This can be useful when certificates are required in | ||
169 | a webserver, but ACME needs the webserver to make its requests. | ||
170 | |||
171 | With preliminary self-signed certificate the webserver can be started and | ||
172 | can later reload the correct ACME certificates. | ||
173 | ''; | ||
174 | }; | ||
175 | |||
176 | certs = mkOption { | ||
177 | default = { }; | ||
178 | type = with types; attrsOf (submodule certOpts); | ||
179 | description = '' | ||
180 | Attribute set of certificates to get signed and renewed. Creates | ||
181 | <literal>acme-''${cert}.{service,timer}</literal> systemd units for | ||
182 | each certificate defined here. Other services can add dependencies | ||
183 | to those units if they rely on the certificates being present, | ||
184 | or trigger restarts of the service if certificates get renewed. | ||
185 | ''; | ||
186 | example = literalExample '' | ||
187 | { | ||
188 | "example.com" = { | ||
189 | webroot = "/var/www/challenges/"; | ||
190 | email = "foo@example.com"; | ||
191 | extraDomains = { "www.example.com" = null; "foo.example.com" = "/var/www/foo/"; }; | ||
192 | }; | ||
193 | "bar.example.com" = { | ||
194 | webroot = "/var/www/challenges/"; | ||
195 | email = "bar@example.com"; | ||
196 | }; | ||
197 | } | ||
198 | ''; | ||
199 | }; | ||
200 | }; | ||
201 | }; | ||
202 | |||
203 | ###### implementation | ||
204 | config = mkMerge [ | ||
205 | (mkIf (cfg.certs != { }) { | ||
206 | |||
207 | systemd.services = let | ||
208 | services = concatLists servicesLists; | ||
209 | servicesLists = mapAttrsToList certToServices cfg.certs; | ||
210 | certToServices = cert: data: | ||
211 | let | ||
212 | lpath = "acme/${cert}"; | ||
213 | rights = if data.allowKeysForGroup then "750" else "700"; | ||
214 | cmdline = [ "-v" "-d" data.domain "--default_root" data.webroot "--valid_min" cfg.validMin ] | ||
215 | ++ optionals (data.email != null) [ "--email" data.email ] | ||
216 | ++ concatMap (p: [ "-f" p ]) data.plugins | ||
217 | ++ concatLists (mapAttrsToList (name: root: [ "-d" (if root == null then name else "${name}:${root}")]) data.extraDomains) | ||
218 | ++ optionals (cfg.server != null || data.server != null) ["--server" (if data.server == null then cfg.server else data.server)]; | ||
219 | acmeService = { | ||
220 | description = "Renew ACME Certificate for ${cert}"; | ||
221 | after = [ "network.target" "network-online.target" ]; | ||
222 | wants = [ "network-online.target" ]; | ||
223 | # simp_le uses requests, which uses certifi under the hood, | ||
224 | # which doesn't respect the system trust store. | ||
225 | # At least in the acme test, we provision a fake CA, impersonating the LE endpoint. | ||
226 | # REQUESTS_CA_BUNDLE is a way to teach python requests to use something else | ||
227 | environment.REQUESTS_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; | ||
228 | serviceConfig = { | ||
229 | Type = "oneshot"; | ||
230 | # With RemainAfterExit the service is considered active even | ||
231 | # after the main process having exited, which means when it | ||
232 | # gets changed, the activation phase restarts it, meaning | ||
233 | # the permissions of the StateDirectory get adjusted | ||
234 | # according to the specified group | ||
235 | RemainAfterExit = true; | ||
236 | SuccessExitStatus = [ "0" "1" ]; | ||
237 | User = data.user; | ||
238 | Group = data.group; | ||
239 | PrivateTmp = true; | ||
240 | StateDirectory = lpath; | ||
241 | StateDirectoryMode = rights; | ||
242 | WorkingDirectory = "/var/lib/${lpath}"; | ||
243 | ExecStart = "${pkgs.simp_le_0_17}/bin/simp_le ${escapeShellArgs cmdline}"; | ||
244 | ExecStartPost = | ||
245 | let | ||
246 | script = pkgs.writeScript "acme-post-start" '' | ||
247 | #!${pkgs.runtimeShell} -e | ||
248 | ${data.postRun} | ||
249 | ''; | ||
250 | in | ||
251 | "+${script}"; | ||
252 | }; | ||
253 | |||
254 | }; | ||
255 | selfsignedService = { | ||
256 | description = "Create preliminary self-signed certificate for ${cert}"; | ||
257 | path = [ pkgs.openssl ]; | ||
258 | script = | ||
259 | '' | ||
260 | workdir="$(mktemp -d)" | ||
261 | |||
262 | # Create CA | ||
263 | openssl genrsa -des3 -passout pass:xxxx -out $workdir/ca.pass.key 2048 | ||
264 | openssl rsa -passin pass:xxxx -in $workdir/ca.pass.key -out $workdir/ca.key | ||
265 | openssl req -new -key $workdir/ca.key -out $workdir/ca.csr \ | ||
266 | -subj "/C=UK/ST=Warwickshire/L=Leamington/O=OrgName/OU=Security Department/CN=example.com" | ||
267 | openssl x509 -req -days 1 -in $workdir/ca.csr -signkey $workdir/ca.key -out $workdir/ca.crt | ||
268 | |||
269 | # Create key | ||
270 | openssl genrsa -des3 -passout pass:xxxx -out $workdir/server.pass.key 2048 | ||
271 | openssl rsa -passin pass:xxxx -in $workdir/server.pass.key -out $workdir/server.key | ||
272 | openssl req -new -key $workdir/server.key -out $workdir/server.csr \ | ||
273 | -subj "/C=UK/ST=Warwickshire/L=Leamington/O=OrgName/OU=IT Department/CN=example.com" | ||
274 | openssl x509 -req -days 1 -in $workdir/server.csr -CA $workdir/ca.crt \ | ||
275 | -CAkey $workdir/ca.key -CAserial $workdir/ca.srl -CAcreateserial \ | ||
276 | -out $workdir/server.crt | ||
277 | |||
278 | # Copy key to destination | ||
279 | cp $workdir/server.key /var/lib/${lpath}/key.pem | ||
280 | |||
281 | # Create fullchain.pem (same format as "simp_le ... -f fullchain.pem" creates) | ||
282 | cat $workdir/{server.crt,ca.crt} > "/var/lib/${lpath}/fullchain.pem" | ||
283 | |||
284 | # Create full.pem for e.g. lighttpd | ||
285 | cat $workdir/{server.key,server.crt,ca.crt} > "/var/lib/${lpath}/full.pem" | ||
286 | |||
287 | # Give key acme permissions | ||
288 | chown '${data.user}:${data.group}' "/var/lib/${lpath}/"{key,fullchain,full}.pem | ||
289 | chmod ${rights} "/var/lib/${lpath}/"{key,fullchain,full}.pem | ||
290 | ''; | ||
291 | serviceConfig = { | ||
292 | Type = "oneshot"; | ||
293 | PrivateTmp = true; | ||
294 | StateDirectory = lpath; | ||
295 | User = data.user; | ||
296 | Group = data.group; | ||
297 | }; | ||
298 | unitConfig = { | ||
299 | # Do not create self-signed key when key already exists | ||
300 | ConditionPathExists = "!/var/lib/${lpath}/key.pem"; | ||
301 | }; | ||
302 | }; | ||
303 | in ( | ||
304 | [ { name = "acme-${cert}"; value = acmeService; } ] | ||
305 | ++ optional cfg.preliminarySelfsigned { name = "acme-selfsigned-${cert}"; value = selfsignedService; } | ||
306 | ); | ||
307 | servicesAttr = listToAttrs services; | ||
308 | in | ||
309 | servicesAttr; | ||
310 | |||
311 | systemd.tmpfiles.rules = | ||
312 | flip mapAttrsToList cfg.certs | ||
313 | (cert: data: "d ${data.webroot}/.well-known/acme-challenge - ${data.user} ${data.group}"); | ||
314 | |||
315 | systemd.timers = flip mapAttrs' cfg.certs (cert: data: nameValuePair | ||
316 | ("acme-${cert}") | ||
317 | ({ | ||
318 | description = "Renew ACME Certificate for ${cert}"; | ||
319 | wantedBy = [ "timers.target" ]; | ||
320 | timerConfig = { | ||
321 | OnCalendar = cfg.renewInterval; | ||
322 | Unit = "acme-${cert}.service"; | ||
323 | Persistent = "yes"; | ||
324 | AccuracySec = "5m"; | ||
325 | RandomizedDelaySec = "1h"; | ||
326 | }; | ||
327 | }) | ||
328 | ); | ||
329 | |||
330 | systemd.targets.acme-selfsigned-certificates = mkIf cfg.preliminarySelfsigned {}; | ||
331 | systemd.targets.acme-certificates = {}; | ||
332 | }) | ||
333 | |||
334 | ]; | ||
335 | |||
336 | meta = { | ||
337 | maintainers = with lib.maintainers; [ abbradar fpletz globin ]; | ||
338 | #doc = ./acme.xml; | ||
339 | }; | ||
340 | } | ||
diff --git a/modules/default.nix b/modules/default.nix index 9ff6ea6..98dc77d 100644 --- a/modules/default.nix +++ b/modules/default.nix | |||
@@ -19,4 +19,5 @@ | |||
19 | 19 | ||
20 | php-application = ./websites/php-application.nix; | 20 | php-application = ./websites/php-application.nix; |
21 | websites = ./websites; | 21 | websites = ./websites; |
22 | acme2 = ./acme2.nix; | ||
22 | } // (if builtins.pathExists ./private then import ./private else {}) | 23 | } // (if builtins.pathExists ./private then import ./private else {}) |
diff --git a/modules/private/certificates.nix b/modules/private/certificates.nix index 2d24579..f057200 100644 --- a/modules/private/certificates.nix +++ b/modules/private/certificates.nix | |||
@@ -4,7 +4,7 @@ | |||
4 | enable = lib.mkEnableOption "enable certificates"; | 4 | enable = lib.mkEnableOption "enable certificates"; |
5 | certConfig = lib.mkOption { | 5 | certConfig = lib.mkOption { |
6 | default = { | 6 | default = { |
7 | webroot = "${config.security.acme.directory}/acme-challenge"; | 7 | webroot = "/var/lib/acme/acme-challenge"; |
8 | email = "ismael@bouya.org"; | 8 | email = "ismael@bouya.org"; |
9 | postRun = builtins.concatStringsSep "\n" [ | 9 | postRun = builtins.concatStringsSep "\n" [ |
10 | (lib.optionalString config.services.httpd.Prod.enable "systemctl reload httpdProd.service") | 10 | (lib.optionalString config.services.httpd.Prod.enable "systemctl reload httpdProd.service") |
@@ -12,7 +12,7 @@ | |||
12 | (lib.optionalString config.services.httpd.Inte.enable "systemctl reload httpdInte.service") | 12 | (lib.optionalString config.services.httpd.Inte.enable "systemctl reload httpdInte.service") |
13 | (lib.optionalString config.services.nginx.enable "systemctl reload nginx.service") | 13 | (lib.optionalString config.services.nginx.enable "systemctl reload nginx.service") |
14 | ]; | 14 | ]; |
15 | plugins = [ "cert.pem" "chain.pem" "fullchain.pem" "full.pem" "key.pem" "account_key.json" ]; | 15 | plugins = [ "cert.pem" "chain.pem" "fullchain.pem" "full.pem" "key.pem" "account_key.json" "account_reg.json"]; |
16 | }; | 16 | }; |
17 | description = "Default configuration for certificates"; | 17 | description = "Default configuration for certificates"; |
18 | }; | 18 | }; |
@@ -20,7 +20,7 @@ | |||
20 | 20 | ||
21 | config = lib.mkIf config.myServices.certificates.enable { | 21 | config = lib.mkIf config.myServices.certificates.enable { |
22 | services.duplyBackup.profiles.system.excludeFile = '' | 22 | services.duplyBackup.profiles.system.excludeFile = '' |
23 | + ${config.security.acme.directory} | 23 | + /var/lib/acme/acme-challenge |
24 | ''; | 24 | ''; |
25 | services.nginx = { | 25 | services.nginx = { |
26 | recommendedTlsSettings = true; | 26 | recommendedTlsSettings = true; |
@@ -30,9 +30,9 @@ | |||
30 | myServices.databasesCerts = config.myServices.certificates.certConfig; | 30 | myServices.databasesCerts = config.myServices.certificates.certConfig; |
31 | myServices.ircCerts = config.myServices.certificates.certConfig; | 31 | myServices.ircCerts = config.myServices.certificates.certConfig; |
32 | 32 | ||
33 | security.acme.preliminarySelfsigned = true; | 33 | security.acme2.preliminarySelfsigned = true; |
34 | 34 | ||
35 | security.acme.certs = { | 35 | security.acme2.certs = { |
36 | "${name}" = config.myServices.certificates.certConfig // { | 36 | "${name}" = config.myServices.certificates.certConfig // { |
37 | domain = config.hostEnv.fqdn; | 37 | domain = config.hostEnv.fqdn; |
38 | }; | 38 | }; |
@@ -41,17 +41,17 @@ | |||
41 | systemd.services = lib.attrsets.mapAttrs' (k: v: | 41 | systemd.services = lib.attrsets.mapAttrs' (k: v: |
42 | lib.attrsets.nameValuePair "acme-selfsigned-${k}" (lib.mkBefore { script = | 42 | lib.attrsets.nameValuePair "acme-selfsigned-${k}" (lib.mkBefore { script = |
43 | (lib.optionalString (builtins.elem "cert.pem" v.plugins) '' | 43 | (lib.optionalString (builtins.elem "cert.pem" v.plugins) '' |
44 | cp $workdir/server.crt ${config.security.acme.directory}/${k}/cert.pem | 44 | cp $workdir/server.crt ${config.security.acme2.certs."${k}".directory}/cert.pem |
45 | chown '${v.user}:${v.group}' ${config.security.acme.directory}/${k}/cert.pem | 45 | chown '${v.user}:${v.group}' ${config.security.acme2.certs."${k}".directory}/cert.pem |
46 | chmod ${if v.allowKeysForGroup then "750" else "700"} ${config.security.acme.directory}/${k}/cert.pem | 46 | chmod ${if v.allowKeysForGroup then "750" else "700"} ${config.security.acme2.certs."${k}".directory}/cert.pem |
47 | '') + | 47 | '') + |
48 | (lib.optionalString (builtins.elem "chain.pem" v.plugins) '' | 48 | (lib.optionalString (builtins.elem "chain.pem" v.plugins) '' |
49 | cp $workdir/ca.crt ${config.security.acme.directory}/${k}/chain.pem | 49 | cp $workdir/ca.crt ${config.security.acme2.certs."${k}".directory}/chain.pem |
50 | chown '${v.user}:${v.group}' ${config.security.acme.directory}/${k}/chain.pem | 50 | chown '${v.user}:${v.group}' ${config.security.acme2.certs."${k}".directory}/chain.pem |
51 | chmod ${if v.allowKeysForGroup then "750" else "700"} ${config.security.acme.directory}/${k}/chain.pem | 51 | chmod ${if v.allowKeysForGroup then "750" else "700"} ${config.security.acme2.certs."${k}".directory}/chain.pem |
52 | '') | 52 | '') |
53 | ; }) | 53 | ; }) |
54 | ) config.security.acme.certs // { | 54 | ) config.security.acme2.certs // { |
55 | httpdProd = lib.mkIf config.services.httpd.Prod.enable | 55 | httpdProd = lib.mkIf config.services.httpd.Prod.enable |
56 | { after = [ "acme-selfsigned-certificates.target" ]; wants = [ "acme-selfsigned-certificates.target" ]; }; | 56 | { after = [ "acme-selfsigned-certificates.target" ]; wants = [ "acme-selfsigned-certificates.target" ]; }; |
57 | httpdTools = lib.mkIf config.services.httpd.Tools.enable | 57 | httpdTools = lib.mkIf config.services.httpd.Tools.enable |
diff --git a/modules/private/databases/mariadb.nix b/modules/private/databases/mariadb.nix index 3359064..ed647ea 100644 --- a/modules/private/databases/mariadb.nix +++ b/modules/private/databases/mariadb.nix | |||
@@ -96,8 +96,8 @@ in { | |||
96 | dataDir = cfg.dataDir; | 96 | dataDir = cfg.dataDir; |
97 | extraOptions = '' | 97 | extraOptions = '' |
98 | ssl_ca = ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt | 98 | ssl_ca = ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt |
99 | ssl_key = ${config.security.acme.directory}/mysql/key.pem | 99 | ssl_key = ${config.security.acme2.certs.mysql.directory}/key.pem |
100 | ssl_cert = ${config.security.acme.directory}/mysql/fullchain.pem | 100 | ssl_cert = ${config.security.acme2.certs.mysql.directory}/fullchain.pem |
101 | 101 | ||
102 | # for replication | 102 | # for replication |
103 | log-bin=mariadb-bin | 103 | log-bin=mariadb-bin |
@@ -110,10 +110,10 @@ in { | |||
110 | }; | 110 | }; |
111 | 111 | ||
112 | users.users.mysql.extraGroups = [ "keys" ]; | 112 | users.users.mysql.extraGroups = [ "keys" ]; |
113 | security.acme.certs."mysql" = config.myServices.databasesCerts // { | 113 | security.acme2.certs."mysql" = config.myServices.databasesCerts // { |
114 | user = "mysql"; | 114 | user = "mysql"; |
115 | group = "mysql"; | 115 | group = "mysql"; |
116 | plugins = [ "fullchain.pem" "key.pem" "account_key.json" ]; | 116 | plugins = [ "fullchain.pem" "key.pem" "account_key.json" "account_reg.json" ]; |
117 | domain = "db-1.immae.eu"; | 117 | domain = "db-1.immae.eu"; |
118 | postRun = '' | 118 | postRun = '' |
119 | systemctl restart mysql.service | 119 | systemctl restart mysql.service |
diff --git a/modules/private/databases/openldap/default.nix b/modules/private/databases/openldap/default.nix index 22f6f7b..d7d61db 100644 --- a/modules/private/databases/openldap/default.nix +++ b/modules/private/databases/openldap/default.nix | |||
@@ -24,9 +24,9 @@ let | |||
24 | overlay syncprov | 24 | overlay syncprov |
25 | syncprov-checkpoint 100 10 | 25 | syncprov-checkpoint 100 10 |
26 | 26 | ||
27 | TLSCertificateFile ${config.security.acme.directory}/ldap/cert.pem | 27 | TLSCertificateFile ${config.security.acme2.certs.ldap.directory}/cert.pem |
28 | TLSCertificateKeyFile ${config.security.acme.directory}/ldap/key.pem | 28 | TLSCertificateKeyFile ${config.security.acme2.certs.ldap.directory}/key.pem |
29 | TLSCACertificateFile ${config.security.acme.directory}/ldap/fullchain.pem | 29 | TLSCACertificateFile ${config.security.acme2.certs.ldap.directory}/fullchain.pem |
30 | TLSCACertificatePath ${pkgs.cacert.unbundled}/etc/ssl/certs/ | 30 | TLSCACertificatePath ${pkgs.cacert.unbundled}/etc/ssl/certs/ |
31 | #This makes openldap crash | 31 | #This makes openldap crash |
32 | #TLSCipherSuite DEFAULT | 32 | #TLSCipherSuite DEFAULT |
@@ -117,10 +117,10 @@ in | |||
117 | users.users.openldap.extraGroups = [ "keys" ]; | 117 | users.users.openldap.extraGroups = [ "keys" ]; |
118 | networking.firewall.allowedTCPPorts = [ 636 389 ]; | 118 | networking.firewall.allowedTCPPorts = [ 636 389 ]; |
119 | 119 | ||
120 | security.acme.certs."ldap" = config.myServices.databasesCerts // { | 120 | security.acme2.certs."ldap" = config.myServices.databasesCerts // { |
121 | user = "openldap"; | 121 | user = "openldap"; |
122 | group = "openldap"; | 122 | group = "openldap"; |
123 | plugins = [ "fullchain.pem" "key.pem" "cert.pem" "account_key.json" ]; | 123 | plugins = [ "fullchain.pem" "key.pem" "cert.pem" "account_key.json" "account_reg.json" ]; |
124 | domain = "ldap.immae.eu"; | 124 | domain = "ldap.immae.eu"; |
125 | postRun = '' | 125 | postRun = '' |
126 | systemctl restart openldap.service | 126 | systemctl restart openldap.service |
diff --git a/modules/private/databases/postgresql.nix b/modules/private/databases/postgresql.nix index 3dcd311..27ea59c 100644 --- a/modules/private/databases/postgresql.nix +++ b/modules/private/databases/postgresql.nix | |||
@@ -107,10 +107,10 @@ in { | |||
107 | config = lib.mkIf cfg.enable { | 107 | config = lib.mkIf cfg.enable { |
108 | networking.firewall.allowedTCPPorts = [ 5432 ]; | 108 | networking.firewall.allowedTCPPorts = [ 5432 ]; |
109 | 109 | ||
110 | security.acme.certs."postgresql" = config.myServices.databasesCerts // { | 110 | security.acme2.certs."postgresql" = config.myServices.databasesCerts // { |
111 | user = "postgres"; | 111 | user = "postgres"; |
112 | group = "postgres"; | 112 | group = "postgres"; |
113 | plugins = [ "fullchain.pem" "key.pem" "account_key.json" ]; | 113 | plugins = [ "fullchain.pem" "key.pem" "account_key.json" "account_reg.json" ]; |
114 | domain = "db-1.immae.eu"; | 114 | domain = "db-1.immae.eu"; |
115 | postRun = '' | 115 | postRun = '' |
116 | systemctl reload postgresql.service | 116 | systemctl reload postgresql.service |
@@ -165,8 +165,8 @@ in { | |||
165 | # makes it order of magnitudes quicker | 165 | # makes it order of magnitudes quicker |
166 | synchronous_commit = off | 166 | synchronous_commit = off |
167 | ssl = on | 167 | ssl = on |
168 | ssl_cert_file = '${config.security.acme.directory}/postgresql/fullchain.pem' | 168 | ssl_cert_file = '${config.security.acme2.certs.postgresql.directory}/fullchain.pem' |
169 | ssl_key_file = '${config.security.acme.directory}/postgresql/key.pem' | 169 | ssl_key_file = '${config.security.acme2.certs.postgresql.directory}/key.pem' |
170 | ''; | 170 | ''; |
171 | authentication = let | 171 | authentication = let |
172 | hosts = builtins.concatStringsSep "\n" ( | 172 | hosts = builtins.concatStringsSep "\n" ( |
diff --git a/modules/private/ejabberd/default.nix b/modules/private/ejabberd/default.nix index 5e717f4..3537c24 100644 --- a/modules/private/ejabberd/default.nix +++ b/modules/private/ejabberd/default.nix | |||
@@ -14,7 +14,7 @@ in | |||
14 | }; | 14 | }; |
15 | 15 | ||
16 | config = lib.mkIf cfg.enable { | 16 | config = lib.mkIf cfg.enable { |
17 | security.acme.certs = { | 17 | security.acme2.certs = { |
18 | "ejabberd" = config.myServices.certificates.certConfig // { | 18 | "ejabberd" = config.myServices.certificates.certConfig // { |
19 | user = "ejabberd"; | 19 | user = "ejabberd"; |
20 | group = "ejabberd"; | 20 | group = "ejabberd"; |
@@ -58,7 +58,7 @@ in | |||
58 | text = '' | 58 | text = '' |
59 | host_config: | 59 | host_config: |
60 | "immae.fr": | 60 | "immae.fr": |
61 | domain_certfile: "${config.security.acme.directory}/ejabberd/full.pem" | 61 | domain_certfile: "${config.security.acme2.certs.ejabberd.directory}/full.pem" |
62 | auth_method: [ldap] | 62 | auth_method: [ldap] |
63 | ldap_servers: ["${config.myEnv.jabber.ldap.host}"] | 63 | ldap_servers: ["${config.myEnv.jabber.ldap.host}"] |
64 | ldap_encrypt: tls | 64 | ldap_encrypt: tls |
@@ -81,7 +81,7 @@ in | |||
81 | ERLANG_NODE=ejabberd@localhost | 81 | ERLANG_NODE=ejabberd@localhost |
82 | ''; | 82 | ''; |
83 | configFile = pkgs.runCommand "ejabberd.yml" { | 83 | configFile = pkgs.runCommand "ejabberd.yml" { |
84 | certificatePrivateKeyAndFullChain = "${config.security.acme.directory}/ejabberd/full.pem"; | 84 | certificatePrivateKeyAndFullChain = "${config.security.acme2.certs.ejabberd.directory}/full.pem"; |
85 | certificateCA = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; | 85 | certificateCA = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; |
86 | sql_config_file = config.secrets.fullPaths."ejabberd/psql.yml"; | 86 | sql_config_file = config.secrets.fullPaths."ejabberd/psql.yml"; |
87 | host_config_file = config.secrets.fullPaths."ejabberd/host.yml"; | 87 | host_config_file = config.secrets.fullPaths."ejabberd/host.yml"; |
diff --git a/modules/private/ftp.nix b/modules/private/ftp.nix index e3c1f70..585fe63 100644 --- a/modules/private/ftp.nix +++ b/modules/private/ftp.nix | |||
@@ -17,7 +17,7 @@ in | |||
17 | services.duplyBackup.profiles.ftp = { | 17 | services.duplyBackup.profiles.ftp = { |
18 | rootDir = "/var/lib/ftp"; | 18 | rootDir = "/var/lib/ftp"; |
19 | }; | 19 | }; |
20 | security.acme.certs."ftp" = config.myServices.certificates.certConfig // { | 20 | security.acme2.certs."ftp" = config.myServices.certificates.certConfig // { |
21 | domain = "eldiron.immae.eu"; | 21 | domain = "eldiron.immae.eu"; |
22 | postRun = '' | 22 | postRun = '' |
23 | systemctl restart pure-ftpd.service | 23 | systemctl restart pure-ftpd.service |
@@ -113,7 +113,7 @@ in | |||
113 | MaxDiskUsage 99 | 113 | MaxDiskUsage 99 |
114 | CustomerProof yes | 114 | CustomerProof yes |
115 | TLS 1 | 115 | TLS 1 |
116 | CertFile ${config.security.acme.directory}/ftp/full.pem | 116 | CertFile ${config.security.acme2.certs.ftp.directory}/full.pem |
117 | ''; | 117 | ''; |
118 | in { | 118 | in { |
119 | description = "Pure-FTPd server"; | 119 | description = "Pure-FTPd server"; |
diff --git a/modules/private/irc.nix b/modules/private/irc.nix index 4e6eaab..1054b96 100644 --- a/modules/private/irc.nix +++ b/modules/private/irc.nix | |||
@@ -20,7 +20,7 @@ in | |||
20 | services.duplyBackup.profiles.irc = { | 20 | services.duplyBackup.profiles.irc = { |
21 | rootDir = "/var/lib/bitlbee"; | 21 | rootDir = "/var/lib/bitlbee"; |
22 | }; | 22 | }; |
23 | security.acme.certs."irc" = config.myServices.ircCerts // { | 23 | security.acme2.certs."irc" = config.myServices.ircCerts // { |
24 | domain = "irc.immae.eu"; | 24 | domain = "irc.immae.eu"; |
25 | postRun = '' | 25 | postRun = '' |
26 | systemctl restart stunnel.service | 26 | systemctl restart stunnel.service |
@@ -49,7 +49,7 @@ in | |||
49 | bitlbee = { | 49 | bitlbee = { |
50 | accept = 6697; | 50 | accept = 6697; |
51 | connect = 6667; | 51 | connect = 6667; |
52 | cert = "${config.security.acme.directory}/irc/full.pem"; | 52 | cert = "${config.security.acme2.certs.irc.directory}/full.pem"; |
53 | }; | 53 | }; |
54 | }; | 54 | }; |
55 | }; | 55 | }; |
diff --git a/modules/private/mail/default.nix b/modules/private/mail/default.nix index b50e346..1c64e15 100644 --- a/modules/private/mail/default.nix +++ b/modules/private/mail/default.nix | |||
@@ -13,7 +13,7 @@ | |||
13 | options.myServices.mailBackup.enable = lib.mkEnableOption "enable MX backup services"; | 13 | options.myServices.mailBackup.enable = lib.mkEnableOption "enable MX backup services"; |
14 | 14 | ||
15 | config = lib.mkIf config.myServices.mail.enable { | 15 | config = lib.mkIf config.myServices.mail.enable { |
16 | security.acme.certs."mail" = config.myServices.certificates.certConfig // { | 16 | security.acme2.certs."mail" = config.myServices.certificates.certConfig // { |
17 | domain = config.hostEnv.fqdn; | 17 | domain = config.hostEnv.fqdn; |
18 | extraDomains = let | 18 | extraDomains = let |
19 | zonesWithMx = builtins.filter (zone: | 19 | zonesWithMx = builtins.filter (zone: |
diff --git a/modules/private/mail/dovecot.nix b/modules/private/mail/dovecot.nix index 4facef5..523c017 100644 --- a/modules/private/mail/dovecot.nix +++ b/modules/private/mail/dovecot.nix | |||
@@ -269,7 +269,7 @@ in | |||
269 | [ | 269 | [ |
270 | "0 2 * * * root ${cron_script}/bin/cleanup-imap-folders" | 270 | "0 2 * * * root ${cron_script}/bin/cleanup-imap-folders" |
271 | ]; | 271 | ]; |
272 | security.acme.certs."mail" = { | 272 | security.acme2.certs."mail" = { |
273 | postRun = '' | 273 | postRun = '' |
274 | systemctl restart dovecot2.service | 274 | systemctl restart dovecot2.service |
275 | ''; | 275 | ''; |
diff --git a/modules/private/mail/postfix.nix b/modules/private/mail/postfix.nix index bd284cb..8fe06da 100644 --- a/modules/private/mail/postfix.nix +++ b/modules/private/mail/postfix.nix | |||
@@ -417,7 +417,7 @@ | |||
417 | }; | 417 | }; |
418 | }; | 418 | }; |
419 | }; | 419 | }; |
420 | security.acme.certs."mail" = { | 420 | security.acme2.certs."mail" = { |
421 | postRun = '' | 421 | postRun = '' |
422 | systemctl restart postfix.service | 422 | systemctl restart postfix.service |
423 | ''; | 423 | ''; |
diff --git a/modules/private/mail/relay.nix b/modules/private/mail/relay.nix index 9111350..e0aa387 100644 --- a/modules/private/mail/relay.nix +++ b/modules/private/mail/relay.nix | |||
@@ -1,7 +1,7 @@ | |||
1 | { lib, pkgs, config, nodes, name, ... }: | 1 | { lib, pkgs, config, nodes, name, ... }: |
2 | { | 2 | { |
3 | config = lib.mkIf config.myServices.mailBackup.enable { | 3 | config = lib.mkIf config.myServices.mailBackup.enable { |
4 | security.acme.certs."mail" = config.myServices.certificates.certConfig // { | 4 | security.acme2.certs."mail" = config.myServices.certificates.certConfig // { |
5 | postRun = '' | 5 | postRun = '' |
6 | systemctl restart postfix.service | 6 | systemctl restart postfix.service |
7 | ''; | 7 | ''; |
diff --git a/modules/private/monitoring/status.nix b/modules/private/monitoring/status.nix index d25d934..2860e96 100644 --- a/modules/private/monitoring/status.nix +++ b/modules/private/monitoring/status.nix | |||
@@ -34,7 +34,7 @@ | |||
34 | locations."/".proxyPass = "http://unix:/run/naemon-status/socket.sock:/"; | 34 | locations."/".proxyPass = "http://unix:/run/naemon-status/socket.sock:/"; |
35 | }; | 35 | }; |
36 | }; | 36 | }; |
37 | security.acme.certs."${name}".extraDomains."status.immae.eu" = null; | 37 | security.acme2.certs."${name}".extraDomains."status.immae.eu" = null; |
38 | 38 | ||
39 | myServices.certificates.enable = true; | 39 | myServices.certificates.enable = true; |
40 | networking.firewall.allowedTCPPorts = [ 80 443 ]; | 40 | networking.firewall.allowedTCPPorts = [ 80 443 ]; |
diff --git a/modules/private/tasks/default.nix b/modules/private/tasks/default.nix index c4f065b..c0cc87b 100644 --- a/modules/private/tasks/default.nix +++ b/modules/private/tasks/default.nix | |||
@@ -192,9 +192,9 @@ in { | |||
192 | 192 | ||
193 | myServices.websites.webappDirs._task = ./www; | 193 | myServices.websites.webappDirs._task = ./www; |
194 | 194 | ||
195 | security.acme.certs."task" = config.myServices.certificates.certConfig // { | 195 | security.acme2.certs."task" = config.myServices.certificates.certConfig // { |
196 | inherit user group; | 196 | inherit user group; |
197 | plugins = [ "fullchain.pem" "key.pem" "cert.pem" "account_key.json" ]; | 197 | plugins = [ "fullchain.pem" "key.pem" "cert.pem" "account_key.json" "account_reg.json" ]; |
198 | domain = fqdn; | 198 | domain = fqdn; |
199 | postRun = '' | 199 | postRun = '' |
200 | systemctl restart taskserver.service | 200 | systemctl restart taskserver.service |
@@ -244,9 +244,9 @@ in { | |||
244 | inherit fqdn; | 244 | inherit fqdn; |
245 | listenHost = "::"; | 245 | listenHost = "::"; |
246 | pki.manual.ca.cert = "${server_vardir}/keys/ca.cert"; | 246 | pki.manual.ca.cert = "${server_vardir}/keys/ca.cert"; |
247 | pki.manual.server.cert = "${config.security.acme.directory}/task/fullchain.pem"; | 247 | pki.manual.server.cert = "${config.security.acme2.certs.task.directory}/fullchain.pem"; |
248 | pki.manual.server.crl = "${config.security.acme.directory}/task/invalid.crl"; | 248 | pki.manual.server.crl = "${config.security.acme2.certs.task.directory}/invalid.crl"; |
249 | pki.manual.server.key = "${config.security.acme.directory}/task/key.pem"; | 249 | pki.manual.server.key = "${config.security.acme2.certs.task.directory}/key.pem"; |
250 | requestLimit = 104857600; | 250 | requestLimit = 104857600; |
251 | }; | 251 | }; |
252 | 252 | ||
diff --git a/modules/private/websites/default.nix b/modules/private/websites/default.nix index 7f3e463..90f24a4 100644 --- a/modules/private/websites/default.nix +++ b/modules/private/websites/default.nix | |||
@@ -125,7 +125,7 @@ in | |||
125 | 125 | ||
126 | system.activationScripts = { | 126 | system.activationScripts = { |
127 | httpd = '' | 127 | httpd = '' |
128 | install -d -m 0755 ${config.security.acme.directory}/acme-challenge | 128 | install -d -m 0755 /var/lib/acme/acme-challenge |
129 | install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions | 129 | install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions |
130 | ''; | 130 | ''; |
131 | }; | 131 | }; |
diff --git a/modules/private/websites/florian/integration.nix b/modules/private/websites/florian/integration.nix index 00de761..ef7d13a 100644 --- a/modules/private/websites/florian/integration.nix +++ b/modules/private/websites/florian/integration.nix | |||
@@ -8,7 +8,7 @@ in { | |||
8 | options.myServices.websites.florian.integration.enable = lib.mkEnableOption "enable Florian's website integration"; | 8 | options.myServices.websites.florian.integration.enable = lib.mkEnableOption "enable Florian's website integration"; |
9 | 9 | ||
10 | config = lib.mkIf cfg.enable { | 10 | config = lib.mkIf cfg.enable { |
11 | security.acme.certs."ftp".extraDomains."florian.immae.eu" = null; | 11 | security.acme2.certs."ftp".extraDomains."florian.immae.eu" = null; |
12 | 12 | ||
13 | services.websites.env.integration.modules = adminer.apache.modules; | 13 | services.websites.env.integration.modules = adminer.apache.modules; |
14 | services.websites.env.integration.vhostConfs.florian = { | 14 | services.websites.env.integration.vhostConfs.florian = { |
diff --git a/modules/private/websites/florian/production.nix b/modules/private/websites/florian/production.nix index 8d3dfb0..1abc715 100644 --- a/modules/private/websites/florian/production.nix +++ b/modules/private/websites/florian/production.nix | |||
@@ -8,7 +8,7 @@ in { | |||
8 | options.myServices.websites.florian.production.enable = lib.mkEnableOption "enable Florian's website production"; | 8 | options.myServices.websites.florian.production.enable = lib.mkEnableOption "enable Florian's website production"; |
9 | 9 | ||
10 | config = lib.mkIf cfg.enable { | 10 | config = lib.mkIf cfg.enable { |
11 | security.acme.certs."ftp".extraDomains."tellesflorian.com" = null; | 11 | security.acme2.certs."ftp".extraDomains."tellesflorian.com" = null; |
12 | 12 | ||
13 | services.websites.env.production.modules = adminer.apache.modules; | 13 | services.websites.env.production.modules = adminer.apache.modules; |
14 | services.websites.env.production.vhostConfs.florian = { | 14 | services.websites.env.production.vhostConfs.florian = { |
diff --git a/modules/private/websites/nassime/production.nix b/modules/private/websites/nassime/production.nix index f9468f9..293519f 100644 --- a/modules/private/websites/nassime/production.nix +++ b/modules/private/websites/nassime/production.nix | |||
@@ -9,7 +9,7 @@ in { | |||
9 | config = lib.mkIf cfg.enable { | 9 | config = lib.mkIf cfg.enable { |
10 | services.webstats.sites = [ { name = "nassime.bouya.org"; } ]; | 10 | services.webstats.sites = [ { name = "nassime.bouya.org"; } ]; |
11 | 11 | ||
12 | security.acme.certs."ftp".extraDomains."nassime.bouya.org" = null; | 12 | security.acme2.certs."ftp".extraDomains."nassime.bouya.org" = null; |
13 | 13 | ||
14 | services.websites.env.production.vhostConfs.nassime = { | 14 | services.websites.env.production.vhostConfs.nassime = { |
15 | certName = "nassime"; | 15 | certName = "nassime"; |
diff --git a/modules/private/websites/naturaloutil/production.nix b/modules/private/websites/naturaloutil/production.nix index 628e129..a276c47 100644 --- a/modules/private/websites/naturaloutil/production.nix +++ b/modules/private/websites/naturaloutil/production.nix | |||
@@ -10,7 +10,7 @@ in { | |||
10 | config = lib.mkIf cfg.enable { | 10 | config = lib.mkIf cfg.enable { |
11 | services.webstats.sites = [ { name = "naturaloutil.immae.eu"; } ]; | 11 | services.webstats.sites = [ { name = "naturaloutil.immae.eu"; } ]; |
12 | 12 | ||
13 | security.acme.certs."ftp".extraDomains."naturaloutil.immae.eu" = null; | 13 | security.acme2.certs."ftp".extraDomains."naturaloutil.immae.eu" = null; |
14 | 14 | ||
15 | secrets.keys = [{ | 15 | secrets.keys = [{ |
16 | dest = "webapps/prod-naturaloutil"; | 16 | dest = "webapps/prod-naturaloutil"; |
diff --git a/modules/private/websites/papa/surveillance.nix b/modules/private/websites/papa/surveillance.nix index 1bb6ac8..f6e1772 100644 --- a/modules/private/websites/papa/surveillance.nix +++ b/modules/private/websites/papa/surveillance.nix | |||
@@ -6,7 +6,7 @@ in { | |||
6 | options.myServices.websites.papa.surveillance.enable = lib.mkEnableOption "enable Papa surveillance's website"; | 6 | options.myServices.websites.papa.surveillance.enable = lib.mkEnableOption "enable Papa surveillance's website"; |
7 | 7 | ||
8 | config = lib.mkIf cfg.enable { | 8 | config = lib.mkIf cfg.enable { |
9 | security.acme.certs."ftp".extraDomains."surveillance.maison.bbc.bouya.org" = null; | 9 | security.acme2.certs."ftp".extraDomains."surveillance.maison.bbc.bouya.org" = null; |
10 | 10 | ||
11 | services.cron = { | 11 | services.cron = { |
12 | systemCronJobs = let | 12 | systemCronJobs = let |
diff --git a/modules/private/websites/teliotortay/production.nix b/modules/private/websites/teliotortay/production.nix index 59090f5..2c62d10 100644 --- a/modules/private/websites/teliotortay/production.nix +++ b/modules/private/websites/teliotortay/production.nix | |||
@@ -10,7 +10,7 @@ in { | |||
10 | config = lib.mkIf cfg.enable { | 10 | config = lib.mkIf cfg.enable { |
11 | services.webstats.sites = [ { name = "telio-tortay.immae.eu"; } ]; | 11 | services.webstats.sites = [ { name = "telio-tortay.immae.eu"; } ]; |
12 | 12 | ||
13 | security.acme.certs."ftp".extraDomains."telio-tortay.immae.eu" = null; | 13 | security.acme2.certs."ftp".extraDomains."telio-tortay.immae.eu" = null; |
14 | 14 | ||
15 | system.activationScripts.telio-tortay = { | 15 | system.activationScripts.telio-tortay = { |
16 | deps = [ "httpd" ]; | 16 | deps = [ "httpd" ]; |
diff --git a/modules/websites/default.nix b/modules/websites/default.nix index 6ba0d68..e69080e 100644 --- a/modules/websites/default.nix +++ b/modules/websites/default.nix | |||
@@ -149,7 +149,7 @@ in | |||
149 | serverAliases = [ "*" ]; | 149 | serverAliases = [ "*" ]; |
150 | enableSSL = false; | 150 | enableSSL = false; |
151 | logFormat = "combinedVhost"; | 151 | logFormat = "combinedVhost"; |
152 | documentRoot = "${config.security.acme.directory}/acme-challenge"; | 152 | documentRoot = "/var/lib/acme/acme-challenge"; |
153 | extraConfig = '' | 153 | extraConfig = '' |
154 | RewriteEngine on | 154 | RewriteEngine on |
155 | RewriteCond "%{REQUEST_URI}" "!^/\.well-known" | 155 | RewriteCond "%{REQUEST_URI}" "!^/\.well-known" |
@@ -178,9 +178,9 @@ in | |||
178 | }; | 178 | }; |
179 | toVhost = ips: vhostConf: { | 179 | toVhost = ips: vhostConf: { |
180 | enableSSL = true; | 180 | enableSSL = true; |
181 | sslServerCert = "${config.security.acme.directory}/${vhostConf.certName}/cert.pem"; | 181 | sslServerCert = "${config.security.acme2.certs."${vhostConf.certName}".directory}/cert.pem"; |
182 | sslServerKey = "${config.security.acme.directory}/${vhostConf.certName}/key.pem"; | 182 | sslServerKey = "${config.security.acme2.certs."${vhostConf.certName}".directory}/key.pem"; |
183 | sslServerChain = "${config.security.acme.directory}/${vhostConf.certName}/chain.pem"; | 183 | sslServerChain = "${config.security.acme2.certs."${vhostConf.certName}".directory}/chain.pem"; |
184 | logFormat = "combinedVhost"; | 184 | logFormat = "combinedVhost"; |
185 | listen = map (ip: { inherit ip; port = 443; }) ips; | 185 | listen = map (ip: { inherit ip; port = 443; }) ips; |
186 | hostName = builtins.head vhostConf.hosts; | 186 | hostName = builtins.head vhostConf.hosts; |
@@ -223,7 +223,7 @@ in | |||
223 | } | 223 | } |
224 | ) cfg.env; | 224 | ) cfg.env; |
225 | 225 | ||
226 | config.security.acme.certs = let | 226 | config.security.acme2.certs = let |
227 | typesToManage = attrsets.filterAttrs (k: v: v.enable) cfg.env; | 227 | typesToManage = attrsets.filterAttrs (k: v: v.enable) cfg.env; |
228 | flatVhosts = lists.flatten (attrsets.mapAttrsToList (k: v: | 228 | flatVhosts = lists.flatten (attrsets.mapAttrsToList (k: v: |
229 | attrValues v.vhostConfs | 229 | attrValues v.vhostConfs |
diff --git a/pkgs/certbot/default.nix b/pkgs/certbot/default.nix new file mode 100644 index 0000000..8fdbfd1 --- /dev/null +++ b/pkgs/certbot/default.nix | |||
@@ -0,0 +1,65 @@ | |||
1 | { stdenv, python37Packages, fetchFromGitHub, fetchurl, dialog, autoPatchelfHook }: | ||
2 | |||
3 | |||
4 | python37Packages.buildPythonApplication rec { | ||
5 | pname = "certbot"; | ||
6 | version = "1.0.0"; | ||
7 | |||
8 | src = fetchFromGitHub { | ||
9 | owner = pname; | ||
10 | repo = pname; | ||
11 | rev = "v${version}"; | ||
12 | sha256 = "180x7gcpfbrzw8k654s7b5nxdy2yg61lq513dykyn3wz4gssw465"; | ||
13 | }; | ||
14 | |||
15 | patches = [ | ||
16 | ./0001-Don-t-use-distutils.StrictVersion-that-cannot-handle.patch | ||
17 | ]; | ||
18 | |||
19 | propagatedBuildInputs = with python37Packages; [ | ||
20 | ConfigArgParse | ||
21 | acme | ||
22 | configobj | ||
23 | cryptography | ||
24 | distro | ||
25 | josepy | ||
26 | parsedatetime | ||
27 | psutil | ||
28 | pyRFC3339 | ||
29 | pyopenssl | ||
30 | pytz | ||
31 | six | ||
32 | zope_component | ||
33 | zope_interface | ||
34 | ]; | ||
35 | |||
36 | buildInputs = [ dialog ] ++ (with python37Packages; [ mock gnureadline ]); | ||
37 | |||
38 | checkInputs = with python37Packages; [ | ||
39 | pytest_xdist | ||
40 | pytest | ||
41 | dateutil | ||
42 | ]; | ||
43 | |||
44 | postPatch = '' | ||
45 | cd certbot | ||
46 | substituteInPlace certbot/_internal/notify.py --replace "/usr/sbin/sendmail" "/run/wrappers/bin/sendmail" | ||
47 | ''; | ||
48 | |||
49 | postInstall = '' | ||
50 | for i in $out/bin/*; do | ||
51 | wrapProgram "$i" --prefix PYTHONPATH : "$PYTHONPATH" \ | ||
52 | --prefix PATH : "${dialog}/bin:$PATH" | ||
53 | done | ||
54 | ''; | ||
55 | |||
56 | doCheck = true; | ||
57 | |||
58 | meta = with stdenv.lib; { | ||
59 | homepage = src.meta.homepage; | ||
60 | description = "ACME client that can obtain certs and extensibly update server configurations"; | ||
61 | platforms = platforms.unix; | ||
62 | maintainers = [ maintainers.domenkozar ]; | ||
63 | license = licenses.asl20; | ||
64 | }; | ||
65 | } | ||
diff --git a/pkgs/default.nix b/pkgs/default.nix index 82be20e..54868ba 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix | |||
@@ -48,6 +48,9 @@ rec { | |||
48 | naemon = callPackage ./naemon { inherit mylibs monitoring-plugins; }; | 48 | naemon = callPackage ./naemon { inherit mylibs monitoring-plugins; }; |
49 | naemon-livestatus = callPackage ./naemon-livestatus { inherit mylibs naemon; }; | 49 | naemon-livestatus = callPackage ./naemon-livestatus { inherit mylibs naemon; }; |
50 | 50 | ||
51 | simp_le_0_17 = callPackage ./simp_le {}; | ||
52 | certbot = callPackage ./certbot {}; | ||
53 | |||
51 | private = if builtins.pathExists (./. + "/private") | 54 | private = if builtins.pathExists (./. + "/private") |
52 | then import ./private { inherit pkgs; } | 55 | then import ./private { inherit pkgs; } |
53 | else { webapps = {}; }; | 56 | else { webapps = {}; }; |
diff --git a/pkgs/simp_le/default.nix b/pkgs/simp_le/default.nix new file mode 100644 index 0000000..eaefba3 --- /dev/null +++ b/pkgs/simp_le/default.nix | |||
@@ -0,0 +1,32 @@ | |||
1 | { stdenv, python3Packages, bash }: | ||
2 | |||
3 | python3Packages.buildPythonApplication rec { | ||
4 | pname = "simp_le-client"; | ||
5 | version = "0.17.0"; | ||
6 | |||
7 | src = python3Packages.fetchPypi { | ||
8 | inherit pname version; | ||
9 | sha256 = "0m1jynar4calaffp2zdxr5yy9vnhw2qf2hsfxwzfwf8fqb5h7bjb"; | ||
10 | }; | ||
11 | |||
12 | postPatch = '' | ||
13 | # drop upper bound of idna requirement | ||
14 | sed -ri "s/'(idna)<[^']+'/'\1'/" setup.py | ||
15 | substituteInPlace simp_le.py \ | ||
16 | --replace "/bin/sh" "${bash}/bin/sh" | ||
17 | ''; | ||
18 | |||
19 | checkPhase = '' | ||
20 | $out/bin/simp_le --test | ||
21 | ''; | ||
22 | |||
23 | propagatedBuildInputs = with python3Packages; [ acme setuptools_scm josepy idna ]; | ||
24 | |||
25 | meta = with stdenv.lib; { | ||
26 | homepage = https://github.com/zenhack/simp_le; | ||
27 | description = "Simple Let's Encrypt client"; | ||
28 | license = licenses.gpl3; | ||
29 | maintainers = with maintainers; [ gebner makefu ]; | ||
30 | platforms = platforms.linux; | ||
31 | }; | ||
32 | } | ||