summary refs log tree commit diff
diff options
context:
space:
mode:
authorCarlo Zancanaro <carlo@zancanaro.id.au>2024-01-31 11:46:22 +0000
committerClément Lassieur <clement@lassieur.org>2024-01-31 16:54:03 +0100
commita2b1ef903be001d5abfc47fc3e8add04fb748ff3 (patch)
treeb6c46b03499678d8fd6a04e9fa893e6addffbdfe
parent7a45f7b9e1b34912ee087daf4014aa4f67b11bf0 (diff)
downloadguix-a2b1ef903be001d5abfc47fc3e8add04fb748ff3.tar.gz
services: certbot: Symlink certificates to /etc/certs.
* gnu/services/certbot.scm (certbot-deploy-hook): New procedure.
(certbot-command): Pass new deploy hook to certbot.
* doc/guix.texi: Replace "letsencrypt/live" with "certs" throughout, except in
the certbot deploy-hook description.

Change-Id: I2ba5e4903d1e293e566b732a84b07d5a134b697d
Signed-off-by: Clément Lassieur <clement@lassieur.org>
-rw-r--r--doc/guix.texi24
-rw-r--r--gnu/services/certbot.scm36
2 files changed, 46 insertions, 14 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index bb0af26d93..97be37f9b5 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -43,7 +43,7 @@ Copyright @copyright{} 2016, 2017, 2018, 2019, 2020, 2021 Christopher Baines@*
 Copyright @copyright{} 2017, 2018, 2019 Clément Lassieur@*
 Copyright @copyright{} 2017, 2018, 2020, 2021, 2022 Mathieu Othacehe@*
 Copyright @copyright{} 2017 Federico Beffa@*
-Copyright @copyright{} 2017, 2018 Carlo Zancanaro@*
+Copyright @copyright{} 2017, 2018, 2024 Carlo Zancanaro@*
 Copyright @copyright{} 2017 Thomas Danckaert@*
 Copyright @copyright{} 2017 humanitiesNerd@*
 Copyright @copyright{} 2017, 2021 Christine Lemmer-Webber@*
@@ -28135,7 +28135,7 @@ Prosodyctl will also help you to import certificates from the
 them.  See @url{https://prosody.im/doc/letsencrypt}.
 
 @example
-prosodyctl --root cert import /etc/letsencrypt/live
+prosodyctl --root cert import /etc/certs
 @end example
 
 The available configuration parameters follow.  Each parameter
@@ -28846,8 +28846,8 @@ look like this:
           (welcome-text
             "Welcome to this Mumble server running on Guix!")
           (cert-required? #t) ;disallow text password logins
-          (ssl-cert "/etc/letsencrypt/live/mumble.example.com/fullchain.pem")
-          (ssl-key "/etc/letsencrypt/live/mumble.example.com/privkey.pem")))
+          (ssl-cert "/etc/certs/mumble.example.com/fullchain.pem")
+          (ssl-key "/etc/certs/mumble.example.com/privkey.pem")))
 @end lisp
 
 After reconfiguring your system, you can manually set the mumble-server
@@ -28965,12 +28965,12 @@ Should logged ips be obfuscated to protect the privacy of users.
 File name of the SSL/TLS certificate used for encrypted connections.
 
 @lisp
-(ssl-cert "/etc/letsencrypt/live/example.com/fullchain.pem")
+(ssl-cert "/etc/certs/example.com/fullchain.pem")
 @end lisp
 @item @code{ssl-key} (default: @code{#f})
 Filepath to the ssl private key used for encrypted connections.
 @lisp
-(ssl-key "/etc/letsencrypt/live/example.com/privkey.pem")
+(ssl-key "/etc/certs/example.com/privkey.pem")
 @end lisp
 
 @item @code{ssl-dh-params} (default: @code{#f})
@@ -32694,8 +32694,8 @@ example, @samp{"example.com www.example.com"}.
 @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}.
+@code{/etc/certs/@var{name}/fullchain.pem} and the key is
+saved to @code{/etc/certs/@var{name}/privkey.pem}.
 @node DNS Services
 @subsection DNS Services
 @cindex DNS (domain name system)
@@ -37381,9 +37381,9 @@ serve the default @file{/srv/git} over HTTPS might be:
              (listen '("443 ssl"))
              (server-name "git.my-host.org")
              (ssl-certificate
-              "/etc/letsencrypt/live/git.my-host.org/fullchain.pem")
+              "/etc/certs/git.my-host.org/fullchain.pem")
              (ssl-certificate-key
-              "/etc/letsencrypt/live/git.my-host.org/privkey.pem")
+              "/etc/certs/git.my-host.org/privkey.pem")
              (locations
               (list
                (git-http-nginx-location-configuration
@@ -38508,9 +38508,9 @@ footers.
            (nginx-server-block
              (nginx-server-configuration
                (ssl-certificate
-                 "/etc/letsencrypt/live/myweb.site/fullchain.pem")
+                 "/etc/certs/myweb.site/fullchain.pem")
                (ssl-certificate-key
-                 "/etc/letsencrypt/live/myweb.site/privkey.pem")
+                 "/etc/certs/myweb.site/privkey.pem")
                (listen '("443 ssl http2" "[::]:443 ssl http2"))
                (locations
                  (list
diff --git a/gnu/services/certbot.scm b/gnu/services/certbot.scm
index 0c45471659..3926d0551a 100644
--- a/gnu/services/certbot.scm
+++ b/gnu/services/certbot.scm
@@ -6,6 +6,7 @@
 ;;; Copyright © 2020 Jack Hill <jackhill@jackhill.us>
 ;;; Copyright © 2020 Tobias Geerinckx-Rice <me@tobias.gr>
 ;;; Copyright © 2021 Raghav Gururajan <rg@raghavgururajan.name>
+;;; Copyright © 2024 Carlo Zancanaro <carlo@zancanaro.id.au>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -87,6 +88,35 @@
                           (body
                            (list "return 301 https://$host$request_uri;"))))))
 
+(define (certbot-deploy-hook name deploy-hook-script)
+  "Returns a gexp which creates symlinks for privkey.pem and fullchain.pem
+from /etc/certs/NAME to /etc/letsenctypt/live/NAME.  If DEPLOY-HOOK-SCRIPT is
+not #f then it is run after the symlinks have been created."
+  (program-file
+   (string-append name "-deploy-hook")
+   (with-imported-modules '((guix build utils))
+     #~(begin
+         (use-modules (guix build utils))
+         (mkdir-p #$(string-append "/etc/certs/" name))
+         (chmod #$(string-append "/etc/certs/" name) #o755)
+
+         ;; Create new symlinks
+         (symlink #$(string-append
+                     "/etc/letsencrypt/live/" name "/privkey.pem")
+                  #$(string-append "/etc/certs/" name "/privkey.pem.new"))
+         (symlink #$(string-append
+                     "/etc/letsencrypt/live/" name "/fullchain.pem")
+                  #$(string-append "/etc/certs/" name "/fullchain.pem.new"))
+
+         ;; Rename over the top of the old ones, if there are any.
+         (rename-file #$(string-append "/etc/certs/" name "/privkey.pem.new")
+                      #$(string-append "/etc/certs/" name "/privkey.pem"))
+         (rename-file #$(string-append "/etc/certs/" name "/fullchain.pem.new")
+                      #$(string-append "/etc/certs/" name "/fullchain.pem"))
+         #$@(if deploy-hook-script
+                (list #~(invoke #$deploy-hook-script))
+                '())))))
+
 (define certbot-command
   (match-lambda
     (($ <certbot-configuration> package webroot certificates email
@@ -118,7 +148,8 @@
                           `("--manual-auth-hook" ,authentication-hook)
                           '())
                       (if cleanup-hook `("--manual-cleanup-hook" ,cleanup-hook) '())
-                      (if deploy-hook `("--deploy-hook" ,deploy-hook) '()))
+                      (list "--deploy-hook"
+                            (certbot-deploy-hook name deploy-hook)))
                      (append
                       (list name certbot "certonly" "-n" "--agree-tos"
                             "--webroot" "-w" webroot
@@ -130,7 +161,8 @@
                           '("--register-unsafely-without-email"))
                       (if server `("--server" ,server) '())
                       (if rsa-key-size `("--rsa-key-size" ,rsa-key-size) '())
-                      (if deploy-hook `("--deploy-hook" ,deploy-hook) '()))))))
+                      (list "--deploy-hook"
+                            (certbot-deploy-hook name deploy-hook)))))))
               certificates)))
        (program-file
         "certbot-command"