From c9d5dff5af979e0d0f7466e238aaf2ada7fa1aba Mon Sep 17 00:00:00 2001 From: Arun Isaac Date: Tue, 1 Aug 2023 22:08:07 +0100 Subject: acme: Add ACME service. * guix/forge/acme.scm: Import shadow from (gnu packages admin), nss-certs from (gnu packages certs), (gnu services), (gnu services mcron), (gnu system shadow), (guix diagnostics), (guix i18n), (guix profiles), (guix records), (srfi srfi-1) and (ice-9 match). (%letsencrypt-production-url, %letsencrypt-staging-url): New variables. (, , , ): New record types. (acme-http-01-webroot-authorization-hook, acme-http-01-webroot-cleanup-hook): New public functions. (acme-key-length, uacme-hook, acme-activation, acme-renew, acme-helper, acme-helper-sudo-wrapper, acme-special-files, acme-cron-job, raise-to-top): New functions. (%acme-accounts, acme-service-type): New variables. * doc/forge.skb (Services)[ACME service]: New section. --- doc/forge.skb | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) (limited to 'doc') diff --git a/doc/forge.skb b/doc/forge.skb index 3095947..c1c43c7 100644 --- a/doc/forge.skb +++ b/doc/forge.skb @@ -187,6 +187,100 @@ per your needs. The overall configuration used in this tutorial is repeated below for your reference.]) (prog (source :language scheme :file "doc/snippets/tutorial.scm"))) + (chapter :title [Services] + :ident "chapter-services" + (section :title [ACME service] + :ident "section-acme-service" + (p [,(abbr :short "ACME" :long "Automatic Certificate Management +Environment") is a protocol popularized by the Let's Encrypt +certificate authority for the automatic issue and renewal of TLS +certificates. The guix-forge ACME service featuers] + (itemize + (item [a ,(samp [/usr/bin/acme]) script to help with +certificate management tasks]) + (item [cron job that runs at a random minute during the day and +renews certificates older than 30 days]) + (item [HTTP-01 challenge support. The DNS-01 challenge and +wildcard certificates will be supported in the future.]) + (item [completely rootless operation]))) + (p [The first time the ACME service is set up or each time new +certificates are configured, self-signed certificates are created so +that processes (such as nginx) that depend on these certificates can +start up successfully. You must replace these with certificate +authority issued certificates by running ,(samp [/usr/bin/acme +renew]). ,(samp [/usr/bin/acme renew]) automatically registers an ACME +account unless one already exists and renews all configured +certificates. It uses parameters that were configured in the ACME +service and does not need any additional command-line arguments.]) + (p [The ACME service does not use ,(ref :url +"https://certbot.eff.org/" :text "certbot"), the official Let's +Encrypt client. It instead uses ,(ref :url +"https://github.com/ndilieto/uacme/" :text "uacme"). uacme is smaller, +simpler, manages far less state, does no magic, and is better suited +to automation. However, the choice of backend tool is an +implementation detail. The ACME service is an ,(emph [abstract]) +service that is largely independent of the backend tool that powers +it.]) + (p [By using the ACME service, you agree to the Terms of Service +of your ACME server.]) + (description + (record-documentation "guix/forge/acme.scm" ' + (record-field "uacme" + [,(code [uacme]) package to use]) + (record-field "email" + [Email ID to register ACME account with]) + (record-field "acme-url" + [URL of the ACME server to use. This field can be set to +,(code [%letsencrypt-staging-url]) when testing your deployment.]) + (record-field "state-directory" + [State directory in which private keys and certificates are +stored]) + (record-field "http-01-challenge-directory" + [Directory served by the web server at ,(samp +"/.well-known/acme-challenge/") in response to ACME HTTP-01 +challenges]) + (record-field "http-01-authorization-hook" + [Script invoked to complete a HTTP-01 challenge]) + (record-field "http-01-cleanup-hook" + [Script invoked after the completion of a HTTP-01 +challenge]) + (record-field "key" + [,(record-ref "") or ,(record-ref +"") object describing the ACME account and TLS +certificate keys. Changing this field does not affect keys already +generated and stored on disk.]) + (record-field "certificates" + [List of ,(record-ref "") objects +describing certificates to configure]))) + (p [The ,(code [http-01-authorization-hook]) and ,(code +[http-01-cleanup-hook]) scripts are invoked with the following three +command-line arguments.]) + (description + (item :key (code [identifier]) + [Primary domain name on the certificate]) + (item :key (code [token]) + [Filename of the resource requested under ,(samp +"/.well-known/acme-challenge/") during the HTTP-01 challenge]) + (item :key (code [auth]) + [Authorization string expected to be at the requested +resource])) + (description + (record-documentation "guix/forge/acme.scm" ' + (record-field "domains" + [List of domain names that the certificate is valid +for. Each domain name is a string.]) + (record-field "deploy-hook" + [Script invoked to deploy a new certificate after +successful renewal. This script is invoked without any command-line +arguments.])) + (record-documentation "guix/forge/acme.scm" ' + (record-field "length" + [Length of the RSA key in number of bits. Must be a multiple +of 8 between 2048 and 8192.])) + (record-documentation "guix/forge/acme.scm" ' + (record-field "length" + [Length of the ECDSA key in number of bits. Must be either +256 or 384.]))))) (chapter :title [Reference] :ident "chapter-reference" (description -- cgit v1.2.3