···
117
+
preliminarySelfsigned = mkOption {
121
+
Whether a preliminary self-signed certificate should be generated before
122
+
doing ACME requests. This can be useful when certificates are required in
123
+
a webserver, but ACME needs the webserver to make its requests.
125
+
With preliminary self-signed certificate the webserver can be started and
126
+
can later reload the correct ACME certificates.
type = types.loaOf types.optionSet;
···
(mkIf (cfg.certs != { }) {
143
-
systemd.services = flip mapAttrs' cfg.certs (cert: data:
145
-
cpath = "${cfg.directory}/${cert}";
146
-
rights = if data.allowKeysForGroup then "750" else "700";
147
-
cmdline = [ "-v" "-d" cert "--default_root" data.webroot "--valid_min" cfg.validMin ]
148
-
++ optionals (data.email != null) [ "--email" data.email ]
149
-
++ concatMap (p: [ "-f" p ]) data.plugins
150
-
++ concatLists (mapAttrsToList (name: root: [ "-d" (if root == null then name else "${name}:${root}")]) data.extraDomains);
156
+
systemd.services = let
157
+
services = concatLists servicesLists;
158
+
servicesLists = mapAttrsToList certToServices cfg.certs;
159
+
certToServices = cert: data:
161
+
cpath = "${cfg.directory}/${cert}";
162
+
rights = if data.allowKeysForGroup then "750" else "700";
163
+
cmdline = [ "-v" "-d" cert "--default_root" data.webroot "--valid_min" cfg.validMin ]
164
+
++ optionals (data.email != null) [ "--email" data.email ]
165
+
++ concatMap (p: [ "-f" p ]) data.plugins
166
+
++ concatLists (mapAttrsToList (name: root: [ "-d" (if root == null then name else "${name}:${root}")]) data.extraDomains);
168
+
description = "Renew ACME Certificate for ${cert}";
169
+
after = [ "network.target" ];
172
+
SuccessExitStatus = [ "0" "1" ];
173
+
PermissionsStartOnly = true;
175
+
Group = data.group;
178
+
path = [ pkgs.simp_le ];
180
+
mkdir -p '${cfg.directory}'
181
+
if [ ! -d '${cpath}' ]; then
184
+
chmod ${rights} '${cpath}'
185
+
chown -R '${data.user}:${data.group}' '${cpath}'
190
+
simp_le ${concatMapStringsSep " " (arg: escapeShellArg (toString arg)) cmdline}
193
+
echo "$EXITCODE" > /tmp/lastExitCode
197
+
if [ -e /tmp/lastExitCode ] && [ "$(cat /tmp/lastExitCode)" = "0" ]; then
198
+
echo "Executing postRun hook..."
155
-
description = "Renew ACME Certificate for ${cert}";
156
-
after = [ "network.target" ];
159
-
SuccessExitStatus = [ "0" "1" ];
160
-
PermissionsStartOnly = true;
162
-
Group = data.group;
203
+
before = [ "acme-certificates.target" ];
204
+
wantedBy = [ "acme-certificates.target" ];
206
+
selfsignedService = {
207
+
description = "Create preliminary self-signed certificate for ${cert}";
209
+
if [ ! -d '${cpath}' ]
211
+
mkdir -p '${cpath}'
212
+
chmod ${rights} '${cpath}'
213
+
chown '${data.user}:${data.group}' '${cpath}'
218
+
# Create self-signed key
219
+
workdir="/run/acme-selfsigned-${cert}"
220
+
${pkgs.openssl.bin}/bin/openssl genrsa -des3 -passout pass:x -out $workdir/server.pass.key 2048
221
+
${pkgs.openssl.bin}/bin/openssl rsa -passin pass:x -in $workdir/server.pass.key -out $workdir/server.key
222
+
${pkgs.openssl.bin}/bin/openssl req -new -key $workdir/server.key -out $workdir/server.csr \
223
+
-subj "/C=UK/ST=Warwickshire/L=Leamington/O=OrgName/OU=IT Department/CN=example.com"
224
+
${pkgs.openssl.bin}/bin/openssl x509 -req -days 1 -in $workdir/server.csr -signkey $workdir/server.key -out $workdir/server.crt
226
+
# Move key to destination
227
+
mv $workdir/server.key ${cpath}/key.pem
228
+
mv $workdir/server.crt ${cpath}/fullchain.pem
230
+
# Clean up working directory
231
+
rm $workdir/server.csr
232
+
rm $workdir/server.pass.key
234
+
# Give key acme permissions
235
+
chmod ${rights} '${cpath}/key.pem'
236
+
chown '${data.user}:${data.group}' '${cpath}/key.pem'
237
+
chmod ${rights} '${cpath}/fullchain.pem'
238
+
chown '${data.user}:${data.group}' '${cpath}/fullchain.pem'
242
+
RuntimeDirectory = "acme-selfsigned-${cert}";
243
+
PermissionsStartOnly = true;
245
+
Group = data.group;
248
+
# Do not create self-signed key when key already exists
249
+
ConditionPathExists = "!${cpath}/key.pem";
252
+
"acme-selfsigned-certificates.target"
255
+
"acme-selfsigned-certificates.target"
259
+
[ { name = "acme-${cert}"; value = acmeService; } ]
261
+
(if cfg.preliminarySelfsigned
262
+
then [ { name = "acme-selfsigned-${cert}"; value = selfsignedService; } ]
266
+
servicesAttr = listToAttrs services;
269
+
after = [ "acme-selfsigned-certificates.target" ];
270
+
wants = [ "acme-selfsigned-certificates.target" "acme-certificates.target" ];
165
-
path = [ pkgs.simp_le ];
167
-
mkdir -p '${cfg.directory}'
168
-
if [ ! -d '${cpath}' ]; then
171
-
chmod ${rights} '${cpath}'
172
-
chown -R '${data.user}:${data.group}' '${cpath}'
177
-
simp_le ${concatMapStringsSep " " (arg: escapeShellArg (toString arg)) cmdline}
180
-
echo "$EXITCODE" > /tmp/lastExitCode
184
-
if [ -e /tmp/lastExitCode ] && [ "$(cat /tmp/lastExitCode)" = "0" ]; then
185
-
echo "Executing postRun hook..."
275
+
(if config.services.nginx.enable then nginxAttr else {});
systemd.timers = flip mapAttrs' cfg.certs (cert: data: nameValuePair
···
289
+
systemd.targets."acme-selfsigned-certificates" = mkIf cfg.preliminarySelfsigned {};
290
+
systemd.targets."acme-certificates" = {};
{ meta.maintainers = with lib.maintainers; [ abbradar fpletz globin ];