aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWojtek Kosior <koszko@koszko.org>2024-02-27 12:10:11 +0100
committerWojtek Kosior <koszko@koszko.org>2024-02-27 13:35:11 +0100
commit869b6ce440d5d1dff1da3de5395595869ae305e7 (patch)
tree15ec8399675fc58d5d27b5dd15dc35c2d95bbeb0
parente422a1a90aeacc024f4332edaec890186a66c6cf (diff)
downloadkoszko-org-server-869b6ce440d5d1dff1da3de5395595869ae305e7.tar.gz
koszko-org-server-869b6ce440d5d1dff1da3de5395595869ae305e7.zip
Update Certbot configuration to work after Guix Certbot updates.
-rw-r--r--container.scm190
1 files changed, 113 insertions, 77 deletions
diff --git a/container.scm b/container.scm
index 914abe5..ad5e741 100644
--- a/container.scm
+++ b/container.scm
@@ -480,79 +480,81 @@
"/etc/self-issued/ca-cert.pem"))))
(define g-activate-certs
- #~(lambda (cert-names domain-lists)
- (use-modules (guix build utils)
- (ice-9 format)
- (ice-9 textual-ports))
-
- (define (issue-cert cert-name domains)
- (let* ((cert-dir (format #f "/etc/self-issued/certs/~a" cert-name))
- (cert-path (format #f "~a/cert.pem" cert-dir))
- (chain-path (format #f "~a/chain.pem" cert-dir))
- (fullchain-path (format #f "~a/fullchain.pem" cert-dir))
- (privkey-path (format #f "~a/privkey.pem" cert-dir))
- (csr-path (format #f "~a/csr.pem" cert-dir))
- (openssl (string-append #$openssl "/bin/openssl"))
- (initial-umask (umask)))
- (unless (false-if-exception (> (stat:gid (stat cert-path)) 0))
- ;; Prepare the directory and private key.
- (umask #o027)
- (mkdir-p cert-dir)
- (system* openssl "genrsa" "-out" privkey-path "2048")
-
- ;; Make cert.pem and chain.pem.
- (with-output-to-file "/tmp/sth"
- (lambda _
- (display (format #f "subjectAltName=~{DNS:~a~^,~}"
- domains))))
- (system* openssl "req"
- "-new" "-nodes" "-out" csr-path "-key" privkey-path
- "-subj" "/CN=My Server/C=PL/ST=PL/L=Krakow/O=Koszko"
- "-addext" (format #f "subjectAltName=~{DNS:~a~^,~}"
- domains))
- (system* openssl "x509"
- "-req" "-in" csr-path "-copy_extensions=copyall"
- "-CA" "/etc/self-issued/ca-cert.pem"
- "-CAkey" "/etc/self-issued/ca-key.pem" "-CAcreateserial"
- "-out" cert-path "-days" "3650" "-sha256")
- (copy-file "/etc/self-issued/ca-cert.pem" chain-path)
-
- ;; Concatenate cert.pem and chain.pem into fullchain.pem.
- (with-output-to-file fullchain-path
- (lambda _
- (for-each (lambda (part)
- (call-with-input-file part
- (lambda (port)
- (display (get-string-all port)))))
- (list cert-path chain-path))))
-
- ;; Correct permissions.
- (chmod privkey-path #o640)
- (for-each (lambda (path)
- (chown path 0 #$%g-certsaccess-gid))
- (list cert-dir
- privkey-path
- cert-path
- chain-path
- fullchain-path))
- (umask initial-umask))))
-
- (for-each (lambda (cert-name domains)
- (let* ((link-name (format #f "/etc/cert-links/~a" cert-name))
- (tmp-link-name (format #f "~a.newlink" link-name))
- (letsencrypt-target-name
- (format #f "/etc/letsencrypt/live/~a" cert-name))
- (self-issued-target-name
- (format #f "/etc/self-issued/certs/~a" cert-name)))
- (when (#$g-symlink-exists? tmp-link-name)
- (delete-file tmp-link-name))
- (if (file-exists? letsencrypt-target-name)
- (symlink letsencrypt-target-name tmp-link-name)
- (begin
- (issue-cert cert-name domains)
- (symlink self-issued-target-name tmp-link-name)))
- (rename-file tmp-link-name link-name)))
- cert-names domain-lists)))
+ (with-imported-modules '((guix build utils))
+ #~(lambda (cert-names domain-lists)
+ (use-modules (guix build utils)
+ (ice-9 format)
+ (ice-9 textual-ports))
+
+ (define (issue-cert cert-name domains)
+ (let* ((cert-dir (format #f "/etc/self-issued/certs/~a" cert-name))
+ (cert-path (format #f "~a/cert.pem" cert-dir))
+ (chain-path (format #f "~a/chain.pem" cert-dir))
+ (fullchain-path (format #f "~a/fullchain.pem" cert-dir))
+ (privkey-path (format #f "~a/privkey.pem" cert-dir))
+ (csr-path (format #f "~a/csr.pem" cert-dir))
+ (openssl (string-append #$openssl "/bin/openssl"))
+ (initial-umask (umask)))
+ (unless (false-if-exception (> (stat:gid (stat cert-path)) 0))
+ ;; Prepare the directory and private key.
+ (umask #o027)
+ (mkdir-p cert-dir)
+ (system* openssl "genrsa" "-out" privkey-path "2048")
+
+ ;; Make cert.pem and chain.pem.
+ (with-output-to-file "/tmp/sth"
+ (lambda _
+ (display (format #f "subjectAltName=~{DNS:~a~^,~}"
+ domains))))
+ (system* openssl "req"
+ "-new" "-nodes" "-out" csr-path "-key" privkey-path
+ "-subj" "/CN=My Server/C=PL/ST=PL/L=Krakow/O=Koszko"
+ "-addext" (format #f "subjectAltName=~{DNS:~a~^,~}"
+ domains))
+ (system* openssl "x509"
+ "-req" "-in" csr-path "-copy_extensions=copyall"
+ "-CA" "/etc/self-issued/ca-cert.pem"
+ "-CAkey" "/etc/self-issued/ca-key.pem" "-CAcreateserial"
+ "-out" cert-path "-days" "3650" "-sha256")
+ (copy-file "/etc/self-issued/ca-cert.pem" chain-path)
+
+ ;; Concatenate cert.pem and chain.pem into fullchain.pem.
+ (with-output-to-file fullchain-path
+ (lambda _
+ (for-each (lambda (part)
+ (call-with-input-file part
+ (lambda (port)
+ (display (get-string-all port)))))
+ (list cert-path chain-path))))
+
+ ;; Correct permissions.
+ (chmod privkey-path #o640)
+ (for-each (lambda (path)
+ (chown path 0 #$%g-certsaccess-gid))
+ (list cert-dir
+ privkey-path
+ cert-path
+ chain-path
+ fullchain-path))
+ (umask initial-umask))))
+
+ (for-each (lambda (cert-name domains)
+ (let* ((link-name (format #f "/etc/cert-links/~a"
+ cert-name))
+ (tmp-link-name (format #f "~a.newlink" link-name))
+ (letsencrypt-target-name
+ (format #f "/etc/letsencrypt/live/~a" cert-name))
+ (self-issued-target-name
+ (format #f "/etc/self-issued/certs/~a" cert-name)))
+ (when (#$g-symlink-exists? tmp-link-name)
+ (delete-file tmp-link-name))
+ (if (file-exists? letsencrypt-target-name)
+ (symlink letsencrypt-target-name tmp-link-name)
+ (begin
+ (issue-cert cert-name domains)
+ (symlink self-issued-target-name tmp-link-name)))
+ (rename-file tmp-link-name link-name)))
+ cert-names domain-lists))))
(define (make-httpd-deploy-hook cert-name domains)
(program-file
@@ -576,8 +578,10 @@
(#$g-activate-certs (list %cert-name) (list %domains))
- (kill (call-with-input-file "/var/run/httpd" read)
- SIGHUP))))
+ (let ((pid (call-with-input-file "/var/run/httpd" read)))
+ (if pid
+ (kill pid SIGHUP)
+ #t)))))
(define %certbot-token-filename-gexp
#~(format #f "/srv/http/acme-challenge/~a" (getenv "CERTBOT_TOKEN")))
@@ -598,14 +602,46 @@
"cert-cleanup-hook"
#~(delete-file #$%certbot-token-filename-gexp)))
+(define (adapt-certbot-shepherd-root-extension ext)
+ ;; Make certbot independent of Nginx.
+ (let ((old-activation (service-extension-compute ext)))
+ (define (new-activation certbot-config)
+ (cons
+ ;; Dummy Nginx shepherd service will prevent reloading in certbot from
+ ;; throwing "&service-not-found-error: nginx".
+ (shepherd-service
+ (provision '(nginx))
+ (one-shot? #t)
+ (start #~(const #t))
+ (documentation "Provide dummy Nginx.")
+ (actions
+ (list
+ (shepherd-action
+ (name 'reload)
+ (documentation "Dummy reload")
+ (procedure #~(const #t))))))
+
+ (map (lambda (shepherd-service-record)
+ (shepherd-service
+ (inherit shepherd-service-record)
+ (requirement '(httpd))))
+ (old-activation certbot-config))))
+
+ (service-extension shepherd-root-service-type new-activation)))
+
(define koszko-certbot-service-type
(service-type
(inherit certbot-service-type)
(name 'koszko-certbot)
;; Prevent certbot from pulling in Nginx — we use Apache here.
- (extensions (filter
+ (extensions (filter-map
(lambda (ext)
- (not (extension-of-type? ext nginx-service-type)))
+ (cond ((extension-of-type? ext nginx-service-type)
+ #f)
+ ((extension-of-type? ext shepherd-root-service-type)
+ (adapt-certbot-shepherd-root-extension ext))
+ (else
+ ext)))
(service-type-extensions certbot-service-type)))))
(define %koszko-certificate-configurations