* [bug#30459] [PATCH 02/11] services: certbot: Run certbot twice a day at a random minute.
2018-02-14 21:34 ` [bug#30459] [PATCH 01/11] services: certbot: Listen on IPv6 Clément Lassieur
@ 2018-02-14 21:34 ` Clément Lassieur
2018-02-14 21:34 ` [bug#30459] [PATCH 03/11] services: certbot: Fix indentation Clément Lassieur
` (8 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Clément Lassieur @ 2018-02-14 21:34 UTC (permalink / raw)
To: 30459
* doc/guix.texi (Certificate Services): Document it.
* gnu/services/certbot.scm (certbot-renewal-jobs): Change job's time
specification.
---
doc/guix.texi | 8 +++++++-
gnu/services/certbot.scm | 8 ++++----
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index b3bf52735..42705ff8d 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -30,7 +30,7 @@ Copyright @copyright{} 2016, 2017 ng0@*
Copyright @copyright{} 2016, 2017 Jan Nieuwenhuizen@*
Copyright @copyright{} 2016 Julien Lepiller@*
Copyright @copyright{} 2016 Alex ter Weele@*
-Copyright @copyright{} 2017 Clément Lassieur@*
+Copyright @copyright{} 2017, 2018 Clément Lassieur@*
Copyright @copyright{} 2017 Mathieu Othacehe@*
Copyright @copyright{} 2017 Federico Beffa@*
Copyright @copyright{} 2017 Carlo Zancanaro@*
@@ -15670,6 +15670,12 @@ generation, the initial certification request to the Let's Encrypt
service, the web server challenge/response integration, writing the
certificate to disk, and the automated periodic renewals.
+Certbot is run twice a day, at a random minute within the hour. It
+won't do anything until your certificates are due for renewal or
+revoked, but running it regularly would give your service a chance of
+staying online in case a Let's Encrypt-initiated revocation happened for
+some reason.
+
@defvr {Scheme Variable} certbot-service-type
A service type for the @code{certbot} Let's Encrypt client.
@end defvr
diff --git a/gnu/services/certbot.scm b/gnu/services/certbot.scm
index 91249ed3e..1728d126f 100644
--- a/gnu/services/certbot.scm
+++ b/gnu/services/certbot.scm
@@ -65,10 +65,10 @@
(() '())
(_
(list
- ;; Attempt to renew the certificates twice a week.
- #~(job (lambda (now)
- (next-day-from (next-hour-from now '(3))
- '(2 5)))
+ ;; Attempt to renew the certificates twice per day, at a random
+ ;; minute within the hour. See
+ ;; https://certbot.eff.org/all-instructions/.
+ #~(job '(next-minute-from (next-hour '(0 12)) (list (random 60)))
(string-append #$package "/bin/certbot renew"
(string-concatenate
(map (lambda (host)
--
2.16.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 03/11] services: certbot: Fix indentation.
2018-02-14 21:34 ` [bug#30459] [PATCH 01/11] services: certbot: Listen on IPv6 Clément Lassieur
2018-02-14 21:34 ` [bug#30459] [PATCH 02/11] services: certbot: Run certbot twice a day at a random minute Clément Lassieur
@ 2018-02-14 21:34 ` Clément Lassieur
2018-02-14 21:34 ` [bug#30459] [PATCH 04/11] services: certbot: Rename 'host' to 'domain' Clément Lassieur
` (7 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Clément Lassieur @ 2018-02-14 21:34 UTC (permalink / raw)
To: 30459
* gnu/services/certbot.scm (certbot-activation): Fix indentation.
---
gnu/services/certbot.scm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gnu/services/certbot.scm b/gnu/services/certbot.scm
index 1728d126f..8ca64d998 100644
--- a/gnu/services/certbot.scm
+++ b/gnu/services/certbot.scm
@@ -80,8 +80,8 @@
(($ <certbot-configuration> package webroot hosts default-location)
(with-imported-modules '((guix build utils))
#~(begin
- (use-modules (guix build utils))
- (mkdir-p #$webroot)
+ (use-modules (guix build utils))
+ (mkdir-p #$webroot)
(for-each
(lambda (host)
(unless (file-exists? (in-vicinity "/etc/letsencrypt/live" host))
--
2.16.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 04/11] services: certbot: Rename 'host' to 'domain'.
2018-02-14 21:34 ` [bug#30459] [PATCH 01/11] services: certbot: Listen on IPv6 Clément Lassieur
2018-02-14 21:34 ` [bug#30459] [PATCH 02/11] services: certbot: Run certbot twice a day at a random minute Clément Lassieur
2018-02-14 21:34 ` [bug#30459] [PATCH 03/11] services: certbot: Fix indentation Clément Lassieur
@ 2018-02-14 21:34 ` Clément Lassieur
2018-02-14 21:34 ` [bug#30459] [PATCH 05/11] services: certbot: Refactor certbot command Clément Lassieur
` (6 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Clément Lassieur @ 2018-02-14 21:34 UTC (permalink / raw)
To: 30459
* doc/guix.texi (Certificate Services): Rename 'host' to 'domain'.
* gnu/services/certbot.scm (<certbot-configuration>, certbot-renewal-jobs,
certbot-activation, certbot-nginx-server-configurations,
certbot-service-type): Rename 'host' to 'domain'.
---
doc/guix.texi | 14 +++++++-------
gnu/services/certbot.scm | 42 ++++++++++++++++++++++--------------------
2 files changed, 29 insertions(+), 27 deletions(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index 42705ff8d..42f2593d3 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -15692,8 +15692,8 @@ The certbot package to use.
The directory from which to serve the Let's Encrypt challenge/response
files.
-@item @code{hosts} (default: @code{()})
-A list of hosts for which to generate certificates and request
+@item @code{domains} (default: @code{()})
+A list of domains for which to generate certificates and request
signatures.
@item @code{default-location} (default: @i{see below})
@@ -15701,7 +15701,7 @@ The default @code{nginx-location-configuration}. Because @code{certbot}
needs to be able to serve challenges and responses, it needs to be able
to run a web server. It does so by extending the @code{nginx} web
service with an @code{nginx-server-configuration} listening on the
-@var{hosts} on port 80, and which has a
+@var{domains} on port 80, and which has a
@code{nginx-location-configuration} for the @code{/.well-known/} URI
path subspace used by Let's Encrypt. @xref{Web Services}, for more on
these nginx configuration data types.
@@ -15711,7 +15711,7 @@ Requests to other URL paths will be matched by the
@code{nginx-server-configuration}s.
By default, the @code{default-location} will issue a redirect from
-@code{http://@var{host}/...} to @code{https://@var{host}/...}, leaving
+@code{http://@var{domain}/...} to @code{https://@var{domain}/...}, leaving
you to define what to serve on your site via @code{https}.
Pass @code{#f} to not issue a default location.
@@ -15719,9 +15719,9 @@ Pass @code{#f} to not issue a default location.
@end deftp
The public key and its signatures will be written to
-@code{/etc/letsencrypt/live/@var{host}/fullchain.pem}, for each
-@var{host} in the configuration. The private key is written to
-@code{/etc/letsencrypt/live/@var{host}/privkey.pem}.
+@code{/etc/letsencrypt/live/@var{domain}/fullchain.pem}, for each
+@var{domain} in the configuration. The private key is written to
+@code{/etc/letsencrypt/live/@var{domain}/privkey.pem}.
@node DNS Services
diff --git a/gnu/services/certbot.scm b/gnu/services/certbot.scm
index 8ca64d998..0b425bab9 100644
--- a/gnu/services/certbot.scm
+++ b/gnu/services/certbot.scm
@@ -48,7 +48,7 @@
(default certbot))
(webroot certbot-configuration-webroot
(default "/var/www"))
- (hosts certbot-configuration-hosts
+ (domains certbot-configuration-domains
(default '()))
(default-location certbot-configuration-default-location
(default
@@ -59,9 +59,9 @@
(define certbot-renewal-jobs
(match-lambda
- (($ <certbot-configuration> package webroot hosts default-location)
- (match hosts
- ;; Avoid pinging certbot if we have no hosts.
+ (($ <certbot-configuration> package webroot domains default-location)
+ (match domains
+ ;; Avoid pinging certbot if we have no domains.
(() '())
(_
(list
@@ -71,37 +71,38 @@
#~(job '(next-minute-from (next-hour '(0 12)) (list (random 60)))
(string-append #$package "/bin/certbot renew"
(string-concatenate
- (map (lambda (host)
- (string-append " -d " host))
- '#$hosts))))))))))
+ (map (lambda (domain)
+ (string-append " -d " domain))
+ '#$domains))))))))))
(define certbot-activation
(match-lambda
- (($ <certbot-configuration> package webroot hosts default-location)
+ (($ <certbot-configuration> package webroot domains default-location)
(with-imported-modules '((guix build utils))
#~(begin
(use-modules (guix build utils))
(mkdir-p #$webroot)
(for-each
- (lambda (host)
- (unless (file-exists? (in-vicinity "/etc/letsencrypt/live" host))
+ (lambda (domain)
+ (unless (file-exists?
+ (in-vicinity "/etc/letsencrypt/live" domain))
(unless (zero? (system*
(string-append #$certbot "/bin/certbot")
"certonly" "--webroot" "-w" #$webroot
- "-d" host))
- (error "failed to acquire cert for host" host))))
- '#$hosts))))))
+ "-d" domain))
+ (error "failed to acquire cert for domain" domain))))
+ '#$domains))))))
(define certbot-nginx-server-configurations
(match-lambda
- (($ <certbot-configuration> package webroot hosts default-location)
+ (($ <certbot-configuration> package webroot domains default-location)
(map
- (lambda (host)
+ (lambda (domain)
(nginx-server-configuration
(listen '("80" "[::]:80"))
(ssl-certificate #f)
(ssl-certificate-key #f)
- (server-name (list host))
+ (server-name (list domain))
(locations
(filter identity
(list
@@ -109,7 +110,7 @@
(uri "/.well-known")
(body (list (list "root " webroot ";"))))
default-location)))))
- hosts))))
+ domains))))
(define certbot-service-type
(service-type (name 'certbot)
@@ -121,11 +122,12 @@
(service-extension mcron-service-type
certbot-renewal-jobs)))
(compose concatenate)
- (extend (lambda (config additional-hosts)
+ (extend (lambda (config additional-domains)
(certbot-configuration
(inherit config)
- (hosts (append (certbot-configuration-hosts config)
- additional-hosts)))))
+ (domains (append
+ (certbot-configuration-domains config)
+ additional-domains)))))
(default-value (certbot-configuration))
(description
"Automatically renew @url{https://letsencrypt.org, Let's
--
2.16.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 05/11] services: certbot: Refactor certbot command.
2018-02-14 21:34 ` [bug#30459] [PATCH 01/11] services: certbot: Listen on IPv6 Clément Lassieur
` (2 preceding siblings ...)
2018-02-14 21:34 ` [bug#30459] [PATCH 04/11] services: certbot: Rename 'host' to 'domain' Clément Lassieur
@ 2018-02-14 21:34 ` Clément Lassieur
2018-02-14 21:34 ` [bug#30459] [PATCH 06/11] services: certbot: Get certbot to run non-interactively Clément Lassieur
` (5 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Clément Lassieur @ 2018-02-14 21:34 UTC (permalink / raw)
To: 30459
* gnu/services/certbot.scm (certbot-renewal-jobs, certbot-activation):
Refactor common code into certbot-command.
---
gnu/services/certbot.scm | 53 ++++++++++++++++++++++++------------------------
1 file changed, 26 insertions(+), 27 deletions(-)
diff --git a/gnu/services/certbot.scm b/gnu/services/certbot.scm
index 0b425bab9..661e17498 100644
--- a/gnu/services/certbot.scm
+++ b/gnu/services/certbot.scm
@@ -57,41 +57,40 @@
(body
(list "return 301 https://$host$request_uri;"))))))
-(define certbot-renewal-jobs
+(define certbot-command
(match-lambda
(($ <certbot-configuration> package webroot domains default-location)
- (match domains
- ;; Avoid pinging certbot if we have no domains.
- (() '())
- (_
- (list
- ;; Attempt to renew the certificates twice per day, at a random
- ;; minute within the hour. See
- ;; https://certbot.eff.org/all-instructions/.
- #~(job '(next-minute-from (next-hour '(0 12)) (list (random 60)))
- (string-append #$package "/bin/certbot renew"
- (string-concatenate
- (map (lambda (domain)
- (string-append " -d " domain))
- '#$domains))))))))))
+ (let* ((certbot (file-append package "/bin/certbot"))
+ (commands
+ (map
+ (lambda (domain)
+ (list certbot "certonly"
+ "--webroot" "-w" webroot
+ "-d" domain))
+ domains)))
+ (program-file
+ "certbot-command"
+ #~(let ((code 0))
+ (for-each
+ (lambda (command)
+ (set! code (or (apply system* command) code)))
+ '#$commands) code))))))
-(define certbot-activation
- (match-lambda
+(define (certbot-renewal-jobs config)
+ (list
+ ;; Attempt to renew the certificates twice per day, at a random minute
+ ;; within the hour. See https://certbot.eff.org/all-instructions/.
+ #~(job '(next-minute-from (next-hour '(0 12)) (list (random 60)))
+ #$(certbot-command config))))
+
+(define (certbot-activation config)
+ (match config
(($ <certbot-configuration> package webroot domains default-location)
(with-imported-modules '((guix build utils))
#~(begin
(use-modules (guix build utils))
(mkdir-p #$webroot)
- (for-each
- (lambda (domain)
- (unless (file-exists?
- (in-vicinity "/etc/letsencrypt/live" domain))
- (unless (zero? (system*
- (string-append #$certbot "/bin/certbot")
- "certonly" "--webroot" "-w" #$webroot
- "-d" domain))
- (error "failed to acquire cert for domain" domain))))
- '#$domains))))))
+ (zero? (system* #$(certbot-command config))))))))
(define certbot-nginx-server-configurations
(match-lambda
--
2.16.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 06/11] services: certbot: Get certbot to run non-interactively.
2018-02-14 21:34 ` [bug#30459] [PATCH 01/11] services: certbot: Listen on IPv6 Clément Lassieur
` (3 preceding siblings ...)
2018-02-14 21:34 ` [bug#30459] [PATCH 05/11] services: certbot: Refactor certbot command Clément Lassieur
@ 2018-02-14 21:34 ` Clément Lassieur
2018-02-17 15:13 ` Marius Bakke
2018-02-14 21:35 ` [bug#30459] [PATCH 07/11] services: certbot: Associate one certificate with several domains Clément Lassieur
` (4 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Clément Lassieur @ 2018-02-14 21:34 UTC (permalink / raw)
To: 30459
* doc/guix.texi (Certificate Services): Add email field.
* gnu/services/certbot.scm (<certbot-configuration>, certbot-command,
certbot-activation, certbot-nginx-server-configurations): Add email field.
(certbot-command): Add '-n' and '--agree-tos' options.
(certbot-service-type): Remove default-value.
---
doc/guix.texi | 4 ++++
gnu/services/certbot.scm | 14 +++++++++-----
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index 42f2593d3..e951b3274 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -15696,6 +15696,10 @@ files.
A list of domains for which to generate certificates and request
signatures.
+@item @code{email}
+Mandatory email used for registration, recovery contact, and important
+account notifications.
+
@item @code{default-location} (default: @i{see below})
The default @code{nginx-location-configuration}. Because @code{certbot}
needs to be able to serve challenges and responses, it needs to be able
diff --git a/gnu/services/certbot.scm b/gnu/services/certbot.scm
index 661e17498..379c21143 100644
--- a/gnu/services/certbot.scm
+++ b/gnu/services/certbot.scm
@@ -50,6 +50,7 @@
(default "/var/www"))
(domains certbot-configuration-domains
(default '()))
+ (email certbot-configuration-email)
(default-location certbot-configuration-default-location
(default
(nginx-location-configuration
@@ -59,12 +60,14 @@
(define certbot-command
(match-lambda
- (($ <certbot-configuration> package webroot domains default-location)
+ (($ <certbot-configuration> package webroot domains email
+ default-location)
(let* ((certbot (file-append package "/bin/certbot"))
(commands
(map
(lambda (domain)
- (list certbot "certonly"
+ (list certbot "certonly" "-n" "--agree-tos"
+ "-m" email
"--webroot" "-w" webroot
"-d" domain))
domains)))
@@ -85,7 +88,8 @@
(define (certbot-activation config)
(match config
- (($ <certbot-configuration> package webroot domains default-location)
+ (($ <certbot-configuration> package webroot domains email
+ default-location)
(with-imported-modules '((guix build utils))
#~(begin
(use-modules (guix build utils))
@@ -94,7 +98,8 @@
(define certbot-nginx-server-configurations
(match-lambda
- (($ <certbot-configuration> package webroot domains default-location)
+ (($ <certbot-configuration> package webroot domains email
+ default-location)
(map
(lambda (domain)
(nginx-server-configuration
@@ -127,7 +132,6 @@
(domains (append
(certbot-configuration-domains config)
additional-domains)))))
- (default-value (certbot-configuration))
(description
"Automatically renew @url{https://letsencrypt.org, Let's
Encrypt} HTTPS certificates by adjusting the nginx web server configuration
--
2.16.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 06/11] services: certbot: Get certbot to run non-interactively.
2018-02-14 21:34 ` [bug#30459] [PATCH 06/11] services: certbot: Get certbot to run non-interactively Clément Lassieur
@ 2018-02-17 15:13 ` Marius Bakke
2018-02-19 22:46 ` Clément Lassieur
0 siblings, 1 reply; 18+ messages in thread
From: Marius Bakke @ 2018-02-17 15:13 UTC (permalink / raw)
To: Clément Lassieur, 30459
[-- Attachment #1: Type: text/plain, Size: 732 bytes --]
Clément Lassieur <clement@lassieur.org> writes:
> * doc/guix.texi (Certificate Services): Add email field.
> * gnu/services/certbot.scm (<certbot-configuration>, certbot-command,
> certbot-activation, certbot-nginx-server-configurations): Add email field.
> (certbot-command): Add '-n' and '--agree-tos' options.
> (certbot-service-type): Remove default-value.
Since this effectively hides the ToS from the user, I think we should
update documentation to link to it. Something along the lines of
"By using this service, you agree to the Terms and Conditions laid out
in URL...".
I'm not a user of certbot currently and thus haven't tested it, but the
other patches LGTM to me. Thanks a lot for working on this!
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 487 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 06/11] services: certbot: Get certbot to run non-interactively.
2018-02-17 15:13 ` Marius Bakke
@ 2018-02-19 22:46 ` Clément Lassieur
2018-02-22 13:57 ` Marius Bakke
0 siblings, 1 reply; 18+ messages in thread
From: Clément Lassieur @ 2018-02-19 22:46 UTC (permalink / raw)
To: Marius Bakke; +Cc: 30459
Marius Bakke <mbakke@fastmail.com> writes:
> Clément Lassieur <clement@lassieur.org> writes:
>
>> * doc/guix.texi (Certificate Services): Add email field.
>> * gnu/services/certbot.scm (<certbot-configuration>, certbot-command,
>> certbot-activation, certbot-nginx-server-configurations): Add email field.
>> (certbot-command): Add '-n' and '--agree-tos' options.
>> (certbot-service-type): Remove default-value.
>
> Since this effectively hides the ToS from the user, I think we should
> update documentation to link to it. Something along the lines of
> "By using this service, you agree to the Terms and Conditions laid out
> in URL...".
>
> I'm not a user of certbot currently and thus haven't tested it, but the
> other patches LGTM to me. Thanks a lot for working on this!
Thank you very much for the review, Marius, I'll update the
documentation as you said.
I won't push right now because I'm unconvinced by certbot-activation:
- it runs at every reconfigure, whereas I want it to run only when the
configuration changes
- it runs at system startup (with no internet access, I think) which I
obviously don't want
- it requires internet access
Assuming there is no way to get it to run only on reconfigure when the
configuration has changed, I could make a command that the user would
use manually (wich profile-service-type). They would use this command
if they add new certificates and if they don't want to wait for the cron
task to happen. WDYT?
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 06/11] services: certbot: Get certbot to run non-interactively.
2018-02-19 22:46 ` Clément Lassieur
@ 2018-02-22 13:57 ` Marius Bakke
2018-02-22 20:49 ` Clément Lassieur
0 siblings, 1 reply; 18+ messages in thread
From: Marius Bakke @ 2018-02-22 13:57 UTC (permalink / raw)
To: Clément Lassieur; +Cc: 30459
[-- Attachment #1: Type: text/plain, Size: 2099 bytes --]
Clément Lassieur <clement@lassieur.org> writes:
> Marius Bakke <mbakke@fastmail.com> writes:
>
>> Clément Lassieur <clement@lassieur.org> writes:
>>
>>> * doc/guix.texi (Certificate Services): Add email field.
>>> * gnu/services/certbot.scm (<certbot-configuration>, certbot-command,
>>> certbot-activation, certbot-nginx-server-configurations): Add email field.
>>> (certbot-command): Add '-n' and '--agree-tos' options.
>>> (certbot-service-type): Remove default-value.
>>
>> Since this effectively hides the ToS from the user, I think we should
>> update documentation to link to it. Something along the lines of
>> "By using this service, you agree to the Terms and Conditions laid out
>> in URL...".
>>
>> I'm not a user of certbot currently and thus haven't tested it, but the
>> other patches LGTM to me. Thanks a lot for working on this!
>
> Thank you very much for the review, Marius, I'll update the
> documentation as you said.
>
> I won't push right now because I'm unconvinced by certbot-activation:
> - it runs at every reconfigure, whereas I want it to run only when the
> configuration changes
> - it runs at system startup (with no internet access, I think) which I
> obviously don't want
> - it requires internet access
I haven't studied the code, but perhaps certbot-activation could be made
a "proper" Shepherd service (e.g. simple-service)? That way it can have
a dependency on networking, at least. It also would not run on every
reconfigure.
> Assuming there is no way to get it to run only on reconfigure when the
> configuration has changed, I could make a command that the user would
> use manually (wich profile-service-type). They would use this command
> if they add new certificates and if they don't want to wait for the cron
> task to happen. WDYT?
This sounds great, but don't know if it should block this series.
Perhaps you can push it to a 'wip-certbot' branch on Savannah for easier
access and testing?
Also, hopefully some of our newfound Shepherd experts can chime in on
this thread :)
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 487 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 06/11] services: certbot: Get certbot to run non-interactively.
2018-02-22 13:57 ` Marius Bakke
@ 2018-02-22 20:49 ` Clément Lassieur
2018-03-03 21:52 ` bug#30459: " Ludovic Courtès
0 siblings, 1 reply; 18+ messages in thread
From: Clément Lassieur @ 2018-02-22 20:49 UTC (permalink / raw)
To: Marius Bakke; +Cc: 30459
Marius Bakke <mbakke@fastmail.com> writes:
>> I won't push right now because I'm unconvinced by certbot-activation:
>> - it runs at every reconfigure, whereas I want it to run only when the
>> configuration changes
>> - it runs at system startup (with no internet access, I think) which I
>> obviously don't want
>> - it requires internet access
>
> I haven't studied the code, but perhaps certbot-activation could be made
> a "proper" Shepherd service (e.g. simple-service)? That way it can have
> a dependency on networking, at least. It also would not run on every
> reconfigure.
Good idea!
>> Assuming there is no way to get it to run only on reconfigure when the
>> configuration has changed, I could make a command that the user would
>> use manually (wich profile-service-type). They would use this command
>> if they add new certificates and if they don't want to wait for the cron
>> task to happen. WDYT?
>
> This sounds great, but don't know if it should block this series.
> Perhaps you can push it to a 'wip-certbot' branch on Savannah for easier
> access and testing?
>
> Also, hopefully some of our newfound Shepherd experts can chime in on
> this thread :)
I pushed the series as is in the master branch, because it changes the
API and it's better that the potential users use the new API as soon as
possible. (And it works anyway.) I'll add a patch implementing the
certbot-activation as a Shepherd service.
Thank you for the review!
Clément
^ permalink raw reply [flat|nested] 18+ messages in thread
* bug#30459: [PATCH 06/11] services: certbot: Get certbot to run non-interactively.
2018-02-22 20:49 ` Clément Lassieur
@ 2018-03-03 21:52 ` Ludovic Courtès
2018-03-03 22:09 ` [bug#30459] " Clément Lassieur
0 siblings, 1 reply; 18+ messages in thread
From: Ludovic Courtès @ 2018-03-03 21:52 UTC (permalink / raw)
To: Clément Lassieur; +Cc: 30459-done
Clément Lassieur <clement@lassieur.org> skribis:
> I pushed the series as is in the master branch, because it changes the
> API and it's better that the potential users use the new API as soon as
> possible. (And it works anyway.) I'll add a patch implementing the
> certbot-activation as a Shepherd service.
Awesome.
Remember to close the bug by emailing NNN-done@debbugs.gnu.org as I’m
doing here. :-)
Ludo’.
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 06/11] services: certbot: Get certbot to run non-interactively.
2018-03-03 21:52 ` bug#30459: " Ludovic Courtès
@ 2018-03-03 22:09 ` Clément Lassieur
0 siblings, 0 replies; 18+ messages in thread
From: Clément Lassieur @ 2018-03-03 22:09 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: 30459-done
Ludovic Courtès <ludo@gnu.org> writes:
> Clément Lassieur <clement@lassieur.org> skribis:
>
>> I pushed the series as is in the master branch, because it changes the
>> API and it's better that the potential users use the new API as soon as
>> possible. (And it works anyway.) I'll add a patch implementing the
>> certbot-activation as a Shepherd service.
>
> Awesome.
>
> Remember to close the bug by emailing NNN-done@debbugs.gnu.org as I’m
> doing here. :-)
I didn't close it on purpose because I planned to add a new patch this
week in this thread (to fix the activation). But I'll send it in a new
thread. You're right: it's probably easier to keep track of things this
way.
Clément
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 07/11] services: certbot: Associate one certificate with several domains.
2018-02-14 21:34 ` [bug#30459] [PATCH 01/11] services: certbot: Listen on IPv6 Clément Lassieur
` (4 preceding siblings ...)
2018-02-14 21:34 ` [bug#30459] [PATCH 06/11] services: certbot: Get certbot to run non-interactively Clément Lassieur
@ 2018-02-14 21:35 ` Clément Lassieur
2018-02-14 21:35 ` [bug#30459] [PATCH 08/11] doc: Fix typo in certbot-configuration description Clément Lassieur
` (3 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Clément Lassieur @ 2018-02-14 21:35 UTC (permalink / raw)
To: 30459
* doc/guix.texi (Certificate Services): Document <certificate-configuration>,
the change from domains to certificates and the fact that their path is now
derived from their name.
* gnu/services/certbot.scm (<certificate-configuration>): Add and export it.
(certbot-configuration, certbot-command, certbot-activation,
certbot-nginx-server-configurations, certbot-service-type): Replace 'domains'
with 'certificates'.
(certbot-nginx-server-configurations): Use only one nginx-server-configuration
and use all certificate domains as the server-name.
---
doc/guix.texi | 48 ++++++++++++++++++++++++++------
gnu/services/certbot.scm | 71 ++++++++++++++++++++++++++++--------------------
2 files changed, 81 insertions(+), 38 deletions(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index e951b3274..78508eeac 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -15677,7 +15677,22 @@ staying online in case a Let's Encrypt-initiated revocation happened for
some reason.
@defvr {Scheme Variable} certbot-service-type
-A service type for the @code{certbot} Let's Encrypt client.
+A service type for the @code{certbot} Let's Encrypt client. Its value
+must be a @code{certbot-configuration} record as in this example:
+
+@example
+(service certbot-service-type
+ (certbot-configuration
+ (email "foo@@example.net")
+ (certificates
+ (list
+ (certificate-configuration
+ (domains '("example.net" "www.example.net")))
+ (certificate-configuration
+ (domains '("bar.example.net")))))))
+@end example
+
+See below for details about @code{certbot-configuration}.
@end defvr
@deftp {Data Type} certbot-configuration
@@ -15692,9 +15707,10 @@ The certbot package to use.
The directory from which to serve the Let's Encrypt challenge/response
files.
-@item @code{domains} (default: @code{()})
-A list of domains for which to generate certificates and request
-signatures.
+@item @code{certificates} (default: @code{()})
+A list of @code{certificates-configuration}s for which to generate
+certificates and request signatures. Each certificate has a @code{name}
+and several @code{domains}.
@item @code{email}
Mandatory email used for registration, recovery contact, and important
@@ -15722,12 +15738,28 @@ Pass @code{#f} to not issue a default location.
@end table
@end deftp
-The public key and its signatures will be written to
-@code{/etc/letsencrypt/live/@var{domain}/fullchain.pem}, for each
-@var{domain} in the configuration. The private key is written to
-@code{/etc/letsencrypt/live/@var{domain}/privkey.pem}.
+@deftp {Data Type} certificate-configuration
+Data type representing the configuration of a certificate.
+This type has the following parameters:
+
+@table @asis
+@item @code{name} (default: @i{see below})
+This name is used by Certbot for housekeeping and in file paths; it
+doesn't affect the content of the certificate itself. To see
+certificate names, run @code{certbot certificates}.
+
+Its default is the first provided domain.
+@item @code{domains} (default: @code{()})
+The first domain provided will be the subject CN of the certificate, and
+all domains will be Subject Alternative Names on the certificate.
+
+@end table
+@end deftp
+For each @code{certificate-configuration}, the certificate is saved to
+@code{/etc/letsencrypt/live/@var{name}/fullchain.pem} and the key is
+saved to @code{/etc/letsencrypt/live/@var{name}/privkey.pem}.
@node DNS Services
@subsubsection DNS Services
@cindex DNS (domain name system)
diff --git a/gnu/services/certbot.scm b/gnu/services/certbot.scm
index 379c21143..a70a36591 100644
--- a/gnu/services/certbot.scm
+++ b/gnu/services/certbot.scm
@@ -32,7 +32,8 @@
#:use-module (ice-9 match)
#:export (certbot-service-type
certbot-configuration
- certbot-configuration?))
+ certbot-configuration?
+ certificate-configuration))
;;; Commentary:
;;;
@@ -41,6 +42,14 @@
;;; Code:
\f
+(define-record-type* <certificate-configuration>
+ certificate-configuration make-certificate-configuration
+ certificate-configuration?
+ (name certificate-configuration-name
+ (default #f))
+ (domains certificate-configuration-domains
+ (default '())))
+
(define-record-type* <certbot-configuration>
certbot-configuration make-certbot-configuration
certbot-configuration?
@@ -48,7 +57,7 @@
(default certbot))
(webroot certbot-configuration-webroot
(default "/var/www"))
- (domains certbot-configuration-domains
+ (certificates certbot-configuration-certificates
(default '()))
(email certbot-configuration-email)
(default-location certbot-configuration-default-location
@@ -60,17 +69,19 @@
(define certbot-command
(match-lambda
- (($ <certbot-configuration> package webroot domains email
+ (($ <certbot-configuration> package webroot certificates email
default-location)
(let* ((certbot (file-append package "/bin/certbot"))
(commands
(map
- (lambda (domain)
- (list certbot "certonly" "-n" "--agree-tos"
- "-m" email
- "--webroot" "-w" webroot
- "-d" domain))
- domains)))
+ (match-lambda
+ (($ <certificate-configuration> name domains)
+ (list certbot "certonly" "-n" "--agree-tos"
+ "-m" email
+ "--webroot" "-w" webroot
+ "--cert-name" (or name (car domains))
+ "-d" (string-join domains ","))))
+ certificates)))
(program-file
"certbot-command"
#~(let ((code 0))
@@ -88,7 +99,7 @@
(define (certbot-activation config)
(match config
- (($ <certbot-configuration> package webroot domains email
+ (($ <certbot-configuration> package webroot certificates email
default-location)
(with-imported-modules '((guix build utils))
#~(begin
@@ -98,23 +109,22 @@
(define certbot-nginx-server-configurations
(match-lambda
- (($ <certbot-configuration> package webroot domains email
+ (($ <certbot-configuration> package webroot certificates email
default-location)
- (map
- (lambda (domain)
- (nginx-server-configuration
- (listen '("80" "[::]:80"))
- (ssl-certificate #f)
- (ssl-certificate-key #f)
- (server-name (list domain))
- (locations
- (filter identity
- (list
- (nginx-location-configuration
- (uri "/.well-known")
- (body (list (list "root " webroot ";"))))
- default-location)))))
- domains))))
+ (list
+ (nginx-server-configuration
+ (listen '("80" "[::]:80"))
+ (ssl-certificate #f)
+ (ssl-certificate-key #f)
+ (server-name
+ (apply append (map certificate-configuration-domains certificates)))
+ (locations
+ (filter identity
+ (list
+ (nginx-location-configuration
+ (uri "/.well-known")
+ (body (list (list "root " webroot ";"))))
+ default-location))))))))
(define certbot-service-type
(service-type (name 'certbot)
@@ -126,12 +136,13 @@
(service-extension mcron-service-type
certbot-renewal-jobs)))
(compose concatenate)
- (extend (lambda (config additional-domains)
+ (extend (lambda (config additional-certificates)
(certbot-configuration
(inherit config)
- (domains (append
- (certbot-configuration-domains config)
- additional-domains)))))
+ (certificates
+ (append
+ (certbot-configuration-certificates config)
+ additional-certificates)))))
(description
"Automatically renew @url{https://letsencrypt.org, Let's
Encrypt} HTTPS certificates by adjusting the nginx web server configuration
--
2.16.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 08/11] doc: Fix typo in certbot-configuration description.
2018-02-14 21:34 ` [bug#30459] [PATCH 01/11] services: certbot: Listen on IPv6 Clément Lassieur
` (5 preceding siblings ...)
2018-02-14 21:35 ` [bug#30459] [PATCH 07/11] services: certbot: Associate one certificate with several domains Clément Lassieur
@ 2018-02-14 21:35 ` Clément Lassieur
2018-02-14 21:35 ` [bug#30459] [PATCH 09/11] services: certbot: Allow to set RSA key size Clément Lassieur
` (2 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Clément Lassieur @ 2018-02-14 21:35 UTC (permalink / raw)
To: 30459
* doc/guix.texi (Certificate Services): Fix typo.
---
doc/guix.texi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index 78508eeac..4f6f9e9c7 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -15696,7 +15696,7 @@ See below for details about @code{certbot-configuration}.
@end defvr
@deftp {Data Type} certbot-configuration
-Data type representing the configuration of the @code{certbot} serice.
+Data type representing the configuration of the @code{certbot} service.
This type has the following parameters:
@table @asis
--
2.16.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 09/11] services: certbot: Allow to set RSA key size.
2018-02-14 21:34 ` [bug#30459] [PATCH 01/11] services: certbot: Listen on IPv6 Clément Lassieur
` (6 preceding siblings ...)
2018-02-14 21:35 ` [bug#30459] [PATCH 08/11] doc: Fix typo in certbot-configuration description Clément Lassieur
@ 2018-02-14 21:35 ` Clément Lassieur
2018-02-14 21:35 ` [bug#30459] [PATCH 10/11] services: certbot: Add verbosity Clément Lassieur
2018-02-14 21:35 ` [bug#30459] [PATCH 11/11] services: certbot: Allow to set a deploy hook Clément Lassieur
9 siblings, 0 replies; 18+ messages in thread
From: Clément Lassieur @ 2018-02-14 21:35 UTC (permalink / raw)
To: 30459
* doc/guix.texi (Certificate Services): Document it.
* gnu/services/certbot.scm (<cerbot-configuration>, certbot-command,
certbot-activation, certbot-nginx-server-configurations): Add it.
---
doc/guix.texi | 3 +++
gnu/services/certbot.scm | 21 +++++++++++++--------
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index 4f6f9e9c7..8500cda6d 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -15716,6 +15716,9 @@ and several @code{domains}.
Mandatory email used for registration, recovery contact, and important
account notifications.
+@item @code{rsa-key-size} (default: @code{2048})
+Size of the RSA key.
+
@item @code{default-location} (default: @i{see below})
The default @code{nginx-location-configuration}. Because @code{certbot}
needs to be able to serve challenges and responses, it needs to be able
diff --git a/gnu/services/certbot.scm b/gnu/services/certbot.scm
index a70a36591..51f5d719a 100644
--- a/gnu/services/certbot.scm
+++ b/gnu/services/certbot.scm
@@ -60,6 +60,8 @@
(certificates certbot-configuration-certificates
(default '()))
(email certbot-configuration-email)
+ (rsa-key-size certbot-configuration-rsa-key-size
+ (default #f))
(default-location certbot-configuration-default-location
(default
(nginx-location-configuration
@@ -70,17 +72,20 @@
(define certbot-command
(match-lambda
(($ <certbot-configuration> package webroot certificates email
- default-location)
+ rsa-key-size default-location)
(let* ((certbot (file-append package "/bin/certbot"))
+ (rsa-key-size (and rsa-key-size (number->string rsa-key-size)))
(commands
(map
(match-lambda
(($ <certificate-configuration> name domains)
- (list certbot "certonly" "-n" "--agree-tos"
- "-m" email
- "--webroot" "-w" webroot
- "--cert-name" (or name (car domains))
- "-d" (string-join domains ","))))
+ (append
+ (list certbot "certonly" "-n" "--agree-tos"
+ "-m" email
+ "--webroot" "-w" webroot
+ "--cert-name" (or name (car domains))
+ "-d" (string-join domains ","))
+ (if rsa-key-size `("--rsa-key-size" ,rsa-key-size) '()))))
certificates)))
(program-file
"certbot-command"
@@ -100,7 +105,7 @@
(define (certbot-activation config)
(match config
(($ <certbot-configuration> package webroot certificates email
- default-location)
+ rsa-key-size default-location)
(with-imported-modules '((guix build utils))
#~(begin
(use-modules (guix build utils))
@@ -110,7 +115,7 @@
(define certbot-nginx-server-configurations
(match-lambda
(($ <certbot-configuration> package webroot certificates email
- default-location)
+ rsa-key-size default-location)
(list
(nginx-server-configuration
(listen '("80" "[::]:80"))
--
2.16.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 10/11] services: certbot: Add verbosity.
2018-02-14 21:34 ` [bug#30459] [PATCH 01/11] services: certbot: Listen on IPv6 Clément Lassieur
` (7 preceding siblings ...)
2018-02-14 21:35 ` [bug#30459] [PATCH 09/11] services: certbot: Allow to set RSA key size Clément Lassieur
@ 2018-02-14 21:35 ` Clément Lassieur
2018-02-14 21:35 ` [bug#30459] [PATCH 11/11] services: certbot: Allow to set a deploy hook Clément Lassieur
9 siblings, 0 replies; 18+ messages in thread
From: Clément Lassieur @ 2018-02-14 21:35 UTC (permalink / raw)
To: 30459
The certificate name wasn't displayed if it wasn't being renewed.
* gnu/services/certbot.scm (certbot-command): Print certificate name before
running the associated command.
---
gnu/services/certbot.scm | 32 +++++++++++++++++++-------------
1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/gnu/services/certbot.scm b/gnu/services/certbot.scm
index 51f5d719a..f90e4f04b 100644
--- a/gnu/services/certbot.scm
+++ b/gnu/services/certbot.scm
@@ -78,22 +78,28 @@
(commands
(map
(match-lambda
- (($ <certificate-configuration> name domains)
- (append
- (list certbot "certonly" "-n" "--agree-tos"
- "-m" email
- "--webroot" "-w" webroot
- "--cert-name" (or name (car domains))
- "-d" (string-join domains ","))
- (if rsa-key-size `("--rsa-key-size" ,rsa-key-size) '()))))
+ (($ <certificate-configuration> custom-name domains)
+ (let ((name (or custom-name (car domains))))
+ (append
+ (list name certbot "certonly" "-n" "--agree-tos"
+ "-m" email
+ "--webroot" "-w" webroot
+ "--cert-name" name
+ "-d" (string-join domains ","))
+ (if rsa-key-size `("--rsa-key-size" ,rsa-key-size) '())))))
certificates)))
(program-file
"certbot-command"
- #~(let ((code 0))
- (for-each
- (lambda (command)
- (set! code (or (apply system* command) code)))
- '#$commands) code))))))
+ #~(begin
+ (use-modules (ice-9 match))
+ (let ((code 0))
+ (for-each
+ (match-lambda
+ ((name . command)
+ (begin
+ (format #t "Acquiring or renewing certificate: ~a~%" name)
+ (set! code (or (apply system* command) code)))))
+ '#$commands) code)))))))
(define (certbot-renewal-jobs config)
(list
--
2.16.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#30459] [PATCH 11/11] services: certbot: Allow to set a deploy hook.
2018-02-14 21:34 ` [bug#30459] [PATCH 01/11] services: certbot: Listen on IPv6 Clément Lassieur
` (8 preceding siblings ...)
2018-02-14 21:35 ` [bug#30459] [PATCH 10/11] services: certbot: Add verbosity Clément Lassieur
@ 2018-02-14 21:35 ` Clément Lassieur
9 siblings, 0 replies; 18+ messages in thread
From: Clément Lassieur @ 2018-02-14 21:35 UTC (permalink / raw)
To: 30459
* doc/guix.texi (Certificate Services): Document it.
* gnu/services/certbot.scm (<certificate-configuration>, certbot-command): Add
it.
---
doc/guix.texi | 22 ++++++++++++++++++++--
gnu/services/certbot.scm | 10 +++++++---
2 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index 8500cda6d..2092e1d3b 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -15668,7 +15668,9 @@ signature.
The certbot service automates this process: the initial key
generation, the initial certification request to the Let's Encrypt
service, the web server challenge/response integration, writing the
-certificate to disk, and the automated periodic renewals.
+certificate to disk, the automated periodic renewals, and the deployment
+tasks associated with the renewal (e.g. reloading services, copying keys
+with different permissions).
Certbot is run twice a day, at a random minute within the hour. It
won't do anything until your certificates are due for renewal or
@@ -15681,13 +15683,20 @@ A service type for the @code{certbot} Let's Encrypt client. Its value
must be a @code{certbot-configuration} record as in this example:
@example
+(define %nginx-deploy-hook
+ (program-file
+ "nginx-deploy-hook"
+ #~(let ((pid (call-with-input-file "/var/run/nginx/pid" read)))
+ (kill pid SIGHUP))))
+
(service certbot-service-type
(certbot-configuration
(email "foo@@example.net")
(certificates
(list
(certificate-configuration
- (domains '("example.net" "www.example.net")))
+ (domains '("example.net" "www.example.net"))
+ (deploy-hook %nginx-deploy-hook))
(certificate-configuration
(domains '("bar.example.net")))))))
@end example
@@ -15757,6 +15766,15 @@ Its default is the first provided domain.
The first domain provided will be the subject CN of the certificate, and
all domains will be Subject Alternative Names on the certificate.
+@item @code{deploy-hook} (default: @code{#f})
+Command to be run in a shell once for each successfully issued
+certificate. For this command, the shell variable
+@code{$RENEWED_LINEAGE} will point to the config live subdirectory (for
+example, @samp{"/etc/letsencrypt/live/example.com"}) containing the new
+certificates and keys; the shell variable @code{$RENEWED_DOMAINS} will
+contain a space-delimited list of renewed certificate domains (for
+example, @samp{"example.com www.example.com"}.
+
@end table
@end deftp
diff --git a/gnu/services/certbot.scm b/gnu/services/certbot.scm
index f90e4f04b..066b8241b 100644
--- a/gnu/services/certbot.scm
+++ b/gnu/services/certbot.scm
@@ -48,7 +48,9 @@
(name certificate-configuration-name
(default #f))
(domains certificate-configuration-domains
- (default '())))
+ (default '()))
+ (deploy-hook certificate-configuration-deploy-hook
+ (default #f)))
(define-record-type* <certbot-configuration>
certbot-configuration make-certbot-configuration
@@ -78,7 +80,8 @@
(commands
(map
(match-lambda
- (($ <certificate-configuration> custom-name domains)
+ (($ <certificate-configuration> custom-name domains
+ deploy-hook)
(let ((name (or custom-name (car domains))))
(append
(list name certbot "certonly" "-n" "--agree-tos"
@@ -86,7 +89,8 @@
"--webroot" "-w" webroot
"--cert-name" name
"-d" (string-join domains ","))
- (if rsa-key-size `("--rsa-key-size" ,rsa-key-size) '())))))
+ (if rsa-key-size `("--rsa-key-size" ,rsa-key-size) '())
+ (if deploy-hook `("--deploy-hook" ,deploy-hook) '())))))
certificates)))
(program-file
"certbot-command"
--
2.16.1
^ permalink raw reply related [flat|nested] 18+ messages in thread