services: certbot: Rename 'host' to 'domain'.
[jackhill/guix/guix.git] / gnu / services / certbot.scm
CommitLineData
1115f140
AW
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2016 ng0 <ng0@we.make.ritual.n0.is>
3;;; Copyright © 2016 Sou Bunnbu <iyzsong@member.fsf.org>
70cd2239 4;;; Copyright © 2017, 2018 Clément Lassieur <clement@lassieur.org>
1115f140
AW
5;;;
6;;; This file is part of GNU Guix.
7;;;
8;;; GNU Guix is free software; you can redistribute it and/or modify it
9;;; under the terms of the GNU General Public License as published by
10;;; the Free Software Foundation; either version 3 of the License, or (at
11;;; your option) any later version.
12;;;
13;;; GNU Guix is distributed in the hope that it will be useful, but
14;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;;; GNU General Public License for more details.
17;;;
18;;; You should have received a copy of the GNU General Public License
19;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
20
21(define-module (gnu services certbot)
22 #:use-module (gnu services)
23 #:use-module (gnu services base)
24 #:use-module (gnu services shepherd)
25 #:use-module (gnu services mcron)
26 #:use-module (gnu services web)
27 #:use-module (gnu system shadow)
28 #:use-module (gnu packages tls)
29 #:use-module (guix records)
30 #:use-module (guix gexp)
31 #:use-module (srfi srfi-1)
32 #:use-module (ice-9 match)
33 #:export (certbot-service-type
34 certbot-configuration
35 certbot-configuration?))
36
37;;; Commentary:
38;;;
39;;; Automatically obtaining TLS certificates from Let's Encrypt.
40;;;
41;;; Code:
42
43\f
44(define-record-type* <certbot-configuration>
45 certbot-configuration make-certbot-configuration
46 certbot-configuration?
47 (package certbot-configuration-package
48 (default certbot))
49 (webroot certbot-configuration-webroot
50 (default "/var/www"))
966fd7b7 51 (domains certbot-configuration-domains
1115f140
AW
52 (default '()))
53 (default-location certbot-configuration-default-location
54 (default
55 (nginx-location-configuration
56 (uri "/")
57 (body
58 (list "return 301 https://$host$request_uri;"))))))
59
60(define certbot-renewal-jobs
61 (match-lambda
966fd7b7
CL
62 (($ <certbot-configuration> package webroot domains default-location)
63 (match domains
64 ;; Avoid pinging certbot if we have no domains.
1115f140
AW
65 (() '())
66 (_
67 (list
7ab04c17
CL
68 ;; Attempt to renew the certificates twice per day, at a random
69 ;; minute within the hour. See
70 ;; https://certbot.eff.org/all-instructions/.
71 #~(job '(next-minute-from (next-hour '(0 12)) (list (random 60)))
1115f140
AW
72 (string-append #$package "/bin/certbot renew"
73 (string-concatenate
966fd7b7
CL
74 (map (lambda (domain)
75 (string-append " -d " domain))
76 '#$domains))))))))))
1115f140
AW
77
78(define certbot-activation
79 (match-lambda
966fd7b7 80 (($ <certbot-configuration> package webroot domains default-location)
1115f140
AW
81 (with-imported-modules '((guix build utils))
82 #~(begin
30151863
CL
83 (use-modules (guix build utils))
84 (mkdir-p #$webroot)
1115f140 85 (for-each
966fd7b7
CL
86 (lambda (domain)
87 (unless (file-exists?
88 (in-vicinity "/etc/letsencrypt/live" domain))
1115f140
AW
89 (unless (zero? (system*
90 (string-append #$certbot "/bin/certbot")
91 "certonly" "--webroot" "-w" #$webroot
966fd7b7
CL
92 "-d" domain))
93 (error "failed to acquire cert for domain" domain))))
94 '#$domains))))))
1115f140
AW
95
96(define certbot-nginx-server-configurations
97 (match-lambda
966fd7b7 98 (($ <certbot-configuration> package webroot domains default-location)
1115f140 99 (map
966fd7b7 100 (lambda (domain)
1115f140 101 (nginx-server-configuration
70cd2239 102 (listen '("80" "[::]:80"))
1115f140
AW
103 (ssl-certificate #f)
104 (ssl-certificate-key #f)
966fd7b7 105 (server-name (list domain))
1115f140
AW
106 (locations
107 (filter identity
108 (list
109 (nginx-location-configuration
110 (uri "/.well-known")
111 (body (list (list "root " webroot ";"))))
112 default-location)))))
966fd7b7 113 domains))))
1115f140
AW
114
115(define certbot-service-type
116 (service-type (name 'certbot)
117 (extensions
118 (list (service-extension nginx-service-type
119 certbot-nginx-server-configurations)
120 (service-extension activation-service-type
121 certbot-activation)
122 (service-extension mcron-service-type
123 certbot-renewal-jobs)))
124 (compose concatenate)
966fd7b7 125 (extend (lambda (config additional-domains)
1115f140
AW
126 (certbot-configuration
127 (inherit config)
966fd7b7
CL
128 (domains (append
129 (certbot-configuration-domains config)
130 additional-domains)))))
3af03e59
LC
131 (default-value (certbot-configuration))
132 (description
133 "Automatically renew @url{https://letsencrypt.org, Let's
134Encrypt} HTTPS certificates by adjusting the nginx web server configuration
135and periodically invoking @command{certbot}.")))