]>
Commit | Line | Data |
---|---|---|
5765eca7 ER |
1 | #!/bin/sh |
2 | ||
6c474061 ER |
3 | set -eu |
4 | ||
623687d0 ER |
5 | # concat file atomic way |
6 | atomic_concat() { | |
7 | local file=$1; shift | |
8 | > $file.new | |
9 | chmod 600 $file.new | |
10 | cat "$@" > $file.new | |
11 | cp -f $file $file.dehydrated~ | |
12 | mv -f $file.new $file | |
13 | } | |
14 | ||
15 | lighttpd_reload() { | |
16 | if [ ! -x /usr/sbin/lighttpd ] || [ ! -f /etc/lighttpd/server.pem ]; then | |
17 | return | |
18 | fi | |
19 | ||
20 | echo " + Hook: Overwritting /etc/lighttpd/server.pem and reloading lighttpd..." | |
6c474061 | 21 | atomic_concat /etc/lighttpd/server.pem "$FULLCHAINFILE" "$KEYFILE" |
623687d0 ER |
22 | /sbin/service lighttpd reload |
23 | } | |
24 | ||
25 | haproxy_reload() { | |
26 | if [ ! -x /usr/sbin/haproxy ] || [ ! -f /etc/haproxy/server.pem ]; then | |
27 | return | |
28 | fi | |
29 | ||
30 | echo " + Hook: Overwritting /etc/haproxy/server.pem and restarting haproxy..." | |
6c474061 | 31 | atomic_concat /etc/haproxy/server.pem "$FULLCHAINFILE" "$KEYFILE" |
623687d0 ER |
32 | /sbin/service haproxy reload |
33 | } | |
34 | ||
35 | nginx_reload() { | |
36 | if [ ! -f /etc/nginx/server.crt ] || [ ! -f /etc/nginx/server.key ]; then | |
37 | return | |
38 | fi | |
39 | ||
40 | echo " + Hook: Overwritting /etc/nginx/server.{crt,key} and reloading nginx..." | |
6c474061 ER |
41 | atomic_concat /etc/nginx/server.crt "$FULLCHAINFILE" |
42 | atomic_concat /etc/nginx/server.key "$KEYFILE" | |
623687d0 ER |
43 | /sbin/service nginx reload |
44 | } | |
45 | ||
46 | httpd_reload() { | |
47 | if [ ! -x /etc/rc.d/init.d/httpd ]; then | |
48 | return | |
49 | fi | |
50 | ||
30b951d8 | 51 | echo " + Hook: Reloading Apache 2..." |
6c474061 ER |
52 | atomic_concat /etc/httpd/ssl/server.crt "$FULLCHAINFILE" |
53 | atomic_concat /etc/httpd/ssl/server.key "$KEYFILE" | |
623687d0 ER |
54 | /sbin/service httpd graceful |
55 | } | |
56 | ||
6c474061 ER |
57 | deploy_challenge() { |
58 | local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}" | |
59 | ||
60 | # This hook is called once for every domain that needs to be | |
61 | # validated, including any alternative names you may have listed. | |
62 | # | |
63 | # Parameters: | |
64 | # - DOMAIN | |
65 | # The domain name (CN or subject alternative name) being | |
66 | # validated. | |
67 | # - TOKEN_FILENAME | |
68 | # The name of the file containing the token to be served for HTTP | |
69 | # validation. Should be served by your web server as | |
70 | # /.well-known/acme-challenge/${TOKEN_FILENAME}. | |
71 | # - TOKEN_VALUE | |
72 | # The token value that needs to be served for validation. For DNS | |
73 | # validation, this is what you want to put in the _acme-challenge | |
74 | # TXT record. For HTTP validation it is the value that is expected | |
75 | # be found in the $TOKEN_FILENAME file. | |
76 | ||
77 | # Simple example: Use nsupdate with local named | |
78 | # printf 'server 127.0.0.1\nupdate add _acme-challenge.%s 300 IN TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key | |
79 | } | |
80 | ||
81 | clean_challenge() { | |
82 | local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}" | |
83 | ||
84 | # This hook is called after attempting to validate each domain, | |
85 | # whether or not validation was successful. Here you can delete | |
86 | # files or DNS records that are no longer needed. | |
87 | # | |
88 | # The parameters are the same as for deploy_challenge. | |
89 | ||
90 | # Simple example: Use nsupdate with local named | |
91 | # printf 'server 127.0.0.1\nupdate delete _acme-challenge.%s TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key | |
92 | } | |
93 | ||
94 | deploy_cert() { | |
95 | local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" TIMESTAMP="${6}" | |
96 | ||
97 | # This hook is called once for each certificate that has been | |
98 | # produced. Here you might, for instance, copy your new certificates | |
99 | # to service-specific locations and reload the service. | |
100 | # | |
101 | # Parameters: | |
102 | # - DOMAIN | |
103 | # The primary domain name, i.e. the certificate common | |
104 | # name (CN). | |
105 | # - KEYFILE | |
106 | # The path of the file containing the private key. | |
107 | # - CERTFILE | |
108 | # The path of the file containing the signed certificate. | |
109 | # - FULLCHAINFILE | |
110 | # The path of the file containing the full certificate chain. | |
111 | # - CHAINFILE | |
112 | # The path of the file containing the intermediate certificate(s). | |
113 | # - TIMESTAMP | |
114 | # Timestamp when the specified certificate was created. | |
115 | ||
116 | # Simple example: Copy file to nginx config | |
117 | # cp "${KEYFILE}" "${FULLCHAINFILE}" /etc/nginx/ssl/; chown -R nginx: /etc/nginx/ssl | |
118 | # systemctl reload nginx | |
623687d0 ER |
119 | |
120 | lighttpd_reload | |
121 | nginx_reload | |
122 | httpd_reload | |
123 | haproxy_reload | |
6c474061 ER |
124 | } |
125 | ||
126 | deploy_ocsp() { | |
127 | local DOMAIN="${1}" OCSPFILE="${2}" TIMESTAMP="${3}" | |
128 | ||
129 | # This hook is called once for each updated ocsp stapling file that has | |
130 | # been produced. Here you might, for instance, copy your new ocsp stapling | |
131 | # files to service-specific locations and reload the service. | |
132 | # | |
133 | # Parameters: | |
134 | # - DOMAIN | |
135 | # The primary domain name, i.e. the certificate common | |
136 | # name (CN). | |
137 | # - OCSPFILE | |
138 | # The path of the ocsp stapling file | |
139 | # - TIMESTAMP | |
140 | # Timestamp when the specified ocsp stapling file was created. | |
141 | ||
142 | # Simple example: Copy file to nginx config | |
143 | # cp "${OCSPFILE}" /etc/nginx/ssl/; chown -R nginx: /etc/nginx/ssl | |
144 | # systemctl reload nginx | |
145 | } | |
146 | ||
147 | unchanged_cert() { | |
148 | local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" | |
149 | ||
150 | # This hook is called once for each certificate that is still | |
151 | # valid and therefore wasn't reissued. | |
152 | # | |
153 | # Parameters: | |
154 | # - DOMAIN | |
155 | # The primary domain name, i.e. the certificate common | |
156 | # name (CN). | |
157 | # - KEYFILE | |
158 | # The path of the file containing the private key. | |
159 | # - CERTFILE | |
160 | # The path of the file containing the signed certificate. | |
161 | # - FULLCHAINFILE | |
162 | # The path of the file containing the full certificate chain. | |
163 | # - CHAINFILE | |
164 | # The path of the file containing the intermediate certificate(s). | |
165 | } | |
166 | ||
167 | invalid_challenge() { | |
168 | local DOMAIN="${1}" RESPONSE="${2}" | |
169 | ||
170 | # This hook is called if the challenge response has failed, so domain | |
171 | # owners can be aware and act accordingly. | |
172 | # | |
173 | # Parameters: | |
174 | # - DOMAIN | |
175 | # The primary domain name, i.e. the certificate common | |
176 | # name (CN). | |
177 | # - RESPONSE | |
178 | # The response that the verification server returned | |
179 | ||
180 | # Simple example: Send mail to root | |
181 | # printf "Subject: Validation of ${DOMAIN} failed!\n\nOh noez!" | sendmail root | |
182 | } | |
183 | ||
184 | request_failure() { | |
185 | local STATUSCODE="${1}" REASON="${2}" REQTYPE="${3}" HEADERS="${4}" | |
186 | ||
187 | # This hook is called when an HTTP request fails (e.g., when the ACME | |
188 | # server is busy, returns an error, etc). It will be called upon any | |
189 | # response code that does not start with '2'. Useful to alert admins | |
190 | # about problems with requests. | |
191 | # | |
192 | # Parameters: | |
193 | # - STATUSCODE | |
194 | # The HTML status code that originated the error. | |
195 | # - REASON | |
196 | # The specified reason for the error. | |
197 | # - REQTYPE | |
198 | # The kind of request that was made (GET, POST...) | |
199 | # - HEADERS | |
200 | # HTTP headers returned by the CA | |
201 | ||
202 | # Simple example: Send mail to root | |
203 | # printf "Subject: HTTP request failed failed!\n\nA http request failed with status ${STATUSCODE}!" | sendmail root | |
204 | } | |
205 | ||
206 | generate_csr() { | |
207 | local DOMAIN="${1}" CERTDIR="${2}" ALTNAMES="${3}" | |
208 | ||
209 | # This hook is called before any certificate signing operation takes place. | |
210 | # It can be used to generate or fetch a certificate signing request with external | |
211 | # tools. | |
212 | # The output should be just the cerificate signing request formatted as PEM. | |
213 | # | |
214 | # Parameters: | |
215 | # - DOMAIN | |
216 | # The primary domain as specified in domains.txt. This does not need to | |
217 | # match with the domains in the CSR, it's basically just the directory name. | |
218 | # - CERTDIR | |
219 | # Certificate output directory for this particular certificate. Can be used | |
220 | # for storing additional files. | |
221 | # - ALTNAMES | |
222 | # All domain names for the current certificate as specified in domains.txt. | |
223 | # Again, this doesn't need to match with the CSR, it's just there for convenience. | |
224 | ||
225 | # Simple example: Look for pre-generated CSRs | |
226 | # if [ -e "${CERTDIR}/pre-generated.csr" ]; then | |
227 | # cat "${CERTDIR}/pre-generated.csr" | |
228 | # fi | |
229 | } | |
230 | ||
231 | startup_hook() { | |
232 | # This hook is called before the cron command to do some initial tasks | |
233 | # (e.g. starting a webserver). | |
234 | ||
235 | : | |
236 | } | |
237 | ||
238 | exit_hook() { | |
239 | # This hook is called at the end of the cron command and can be used to | |
240 | # do some final (cleanup or other) tasks. | |
241 | ||
242 | : | |
243 | } | |
244 | ||
245 | HANDLER="$1"; shift | |
246 | ||
247 | case "$HANDLER" in | |
248 | deploy_challenge|clean_challenge|deploy_cert|deploy_ocsp|unchanged_cert|invalid_challenge|request_failure|generate_csr|startup_hook|exit_hook) | |
249 | "$HANDLER" "$@" | |
5765eca7 ER |
250 | ;; |
251 | *) | |
6c474061 | 252 | echo " + Hook: $HANDLER: Nothing to do..." |
5765eca7 ER |
253 | ;; |
254 | esac | |
6c474061 ER |
255 | |
256 | exit 0 |