]> git.proxmox.com Git - mirror_acme.sh.git/blame - deploy/lighttpd.sh
Merge pull request #4805 from acmesh-official/dev
[mirror_acme.sh.git] / deploy / lighttpd.sh
CommitLineData
f354e6de
MW
1#!/usr/bin/env sh
2
3# Script for acme.sh to deploy certificates to lighttpd
4#
5# The following variables can be exported:
6#
7# export DEPLOY_LIGHTTPD_PEM_NAME="${domain}.pem"
8#
9# Defines the name of the PEM file.
10# Defaults to "<domain>.pem"
11#
12# export DEPLOY_LIGHTTPD_PEM_PATH="/etc/lighttpd"
13#
14# Defines location of PEM file for Lighttpd.
15# Defaults to /etc/lighttpd
16#
17# export DEPLOY_LIGHTTPD_RELOAD="systemctl reload lighttpd"
18#
19# OPTIONAL: Reload command used post deploy
20# This defaults to be a no-op (ie "true").
21# It is strongly recommended to set this something that makes sense
22# for your distro.
23#
24# export DEPLOY_LIGHTTPD_ISSUER="yes"
25#
26# OPTIONAL: Places CA file as "${DEPLOY_LIGHTTPD_PEM}.issuer"
27# Note: Required for OCSP stapling to work
28#
29# export DEPLOY_LIGHTTPD_BUNDLE="no"
30#
31# OPTIONAL: Deploy this certificate as part of a multi-cert bundle
32# This adds a suffix to the certificate based on the certificate type
33# eg RSA certificates will have .rsa as a suffix to the file name
34# Lighttpd will load all certificates and provide one or the other
35# depending on client capabilities
36# Note: This functionality requires Lighttpd was compiled against
37# a version of OpenSSL that supports this.
38#
39
40######## Public functions #####################
41
42#domain keyfile certfile cafile fullchain
43lighttpd_deploy() {
44 _cdomain="$1"
45 _ckey="$2"
46 _ccert="$3"
47 _cca="$4"
48 _cfullchain="$5"
49
50 # Some defaults
51 DEPLOY_LIGHTTPD_PEM_PATH_DEFAULT="/etc/lighttpd"
52 DEPLOY_LIGHTTPD_PEM_NAME_DEFAULT="${_cdomain}.pem"
53 DEPLOY_LIGHTTPD_BUNDLE_DEFAULT="no"
54 DEPLOY_LIGHTTPD_ISSUER_DEFAULT="yes"
55 DEPLOY_LIGHTTPD_RELOAD_DEFAULT="true"
56
f354e6de
MW
57 _debug _cdomain "${_cdomain}"
58 _debug _ckey "${_ckey}"
59 _debug _ccert "${_ccert}"
60 _debug _cca "${_cca}"
61 _debug _cfullchain "${_cfullchain}"
62
63 # PEM_PATH is optional. If not provided then assume "${DEPLOY_LIGHTTPD_PEM_PATH_DEFAULT}"
c43c711f
GS
64 _getdeployconf DEPLOY_LIGHTTPD_PEM_PATH
65 _debug2 DEPLOY_LIGHTTPD_PEM_PATH "${DEPLOY_LIGHTTPD_PEM_PATH}"
f354e6de
MW
66 if [ -n "${DEPLOY_LIGHTTPD_PEM_PATH}" ]; then
67 Le_Deploy_lighttpd_pem_path="${DEPLOY_LIGHTTPD_PEM_PATH}"
68 _savedomainconf Le_Deploy_lighttpd_pem_path "${Le_Deploy_lighttpd_pem_path}"
69 elif [ -z "${Le_Deploy_lighttpd_pem_path}" ]; then
70 Le_Deploy_lighttpd_pem_path="${DEPLOY_LIGHTTPD_PEM_PATH_DEFAULT}"
71 fi
72
73 # Ensure PEM_PATH exists
74 if [ -d "${Le_Deploy_lighttpd_pem_path}" ]; then
75 _debug "PEM_PATH ${Le_Deploy_lighttpd_pem_path} exists"
76 else
77 _err "PEM_PATH ${Le_Deploy_lighttpd_pem_path} does not exist"
78 return 1
79 fi
80
81 # PEM_NAME is optional. If not provided then assume "${DEPLOY_LIGHTTPD_PEM_NAME_DEFAULT}"
c43c711f
GS
82 _getdeployconf DEPLOY_LIGHTTPD_PEM_NAME
83 _debug2 DEPLOY_LIGHTTPD_PEM_NAME "${DEPLOY_LIGHTTPD_PEM_NAME}"
f354e6de
MW
84 if [ -n "${DEPLOY_LIGHTTPD_PEM_NAME}" ]; then
85 Le_Deploy_lighttpd_pem_name="${DEPLOY_LIGHTTPD_PEM_NAME}"
86 _savedomainconf Le_Deploy_lighttpd_pem_name "${Le_Deploy_lighttpd_pem_name}"
87 elif [ -z "${Le_Deploy_lighttpd_pem_name}" ]; then
88 Le_Deploy_lighttpd_pem_name="${DEPLOY_LIGHTTPD_PEM_NAME_DEFAULT}"
89 fi
90
91 # BUNDLE is optional. If not provided then assume "${DEPLOY_LIGHTTPD_BUNDLE_DEFAULT}"
c43c711f
GS
92 _getdeployconf DEPLOY_LIGHTTPD_BUNDLE
93 _debug2 DEPLOY_LIGHTTPD_BUNDLE "${DEPLOY_LIGHTTPD_BUNDLE}"
f354e6de
MW
94 if [ -n "${DEPLOY_LIGHTTPD_BUNDLE}" ]; then
95 Le_Deploy_lighttpd_bundle="${DEPLOY_LIGHTTPD_BUNDLE}"
96 _savedomainconf Le_Deploy_lighttpd_bundle "${Le_Deploy_lighttpd_bundle}"
97 elif [ -z "${Le_Deploy_lighttpd_bundle}" ]; then
98 Le_Deploy_lighttpd_bundle="${DEPLOY_LIGHTTPD_BUNDLE_DEFAULT}"
99 fi
100
101 # ISSUER is optional. If not provided then assume "${DEPLOY_LIGHTTPD_ISSUER_DEFAULT}"
c43c711f
GS
102 _getdeployconf DEPLOY_LIGHTTPD_ISSUER
103 _debug2 DEPLOY_LIGHTTPD_ISSUER "${DEPLOY_LIGHTTPD_ISSUER}"
f354e6de
MW
104 if [ -n "${DEPLOY_LIGHTTPD_ISSUER}" ]; then
105 Le_Deploy_lighttpd_issuer="${DEPLOY_LIGHTTPD_ISSUER}"
106 _savedomainconf Le_Deploy_lighttpd_issuer "${Le_Deploy_lighttpd_issuer}"
107 elif [ -z "${Le_Deploy_lighttpd_issuer}" ]; then
108 Le_Deploy_lighttpd_issuer="${DEPLOY_LIGHTTPD_ISSUER_DEFAULT}"
109 fi
110
111 # RELOAD is optional. If not provided then assume "${DEPLOY_LIGHTTPD_RELOAD_DEFAULT}"
c43c711f
GS
112 _getdeployconf DEPLOY_LIGHTTPD_RELOAD
113 _debug2 DEPLOY_LIGHTTPD_RELOAD "${DEPLOY_LIGHTTPD_RELOAD}"
f354e6de
MW
114 if [ -n "${DEPLOY_LIGHTTPD_RELOAD}" ]; then
115 Le_Deploy_lighttpd_reload="${DEPLOY_LIGHTTPD_RELOAD}"
116 _savedomainconf Le_Deploy_lighttpd_reload "${Le_Deploy_lighttpd_reload}"
117 elif [ -z "${Le_Deploy_lighttpd_reload}" ]; then
118 Le_Deploy_lighttpd_reload="${DEPLOY_LIGHTTPD_RELOAD_DEFAULT}"
119 fi
120
121 # Set the suffix depending if we are creating a bundle or not
122 if [ "${Le_Deploy_lighttpd_bundle}" = "yes" ]; then
123 _info "Bundle creation requested"
124 # Initialise $Le_Keylength if its not already set
125 if [ -z "${Le_Keylength}" ]; then
126 Le_Keylength=""
127 fi
128 if _isEccKey "${Le_Keylength}"; then
129 _info "ECC key type detected"
130 _suffix=".ecdsa"
131 else
132 _info "RSA key type detected"
133 _suffix=".rsa"
134 fi
135 else
136 _suffix=""
137 fi
138 _debug _suffix "${_suffix}"
139
140 # Set variables for later
141 _pem="${Le_Deploy_lighttpd_pem_path}/${Le_Deploy_lighttpd_pem_name}${_suffix}"
142 _issuer="${_pem}.issuer"
143 _ocsp="${_pem}.ocsp"
144 _reload="${Le_Deploy_lighttpd_reload}"
145
146 _info "Deploying PEM file"
147 # Create a temporary PEM file
148 _temppem="$(_mktemp)"
149 _debug _temppem "${_temppem}"
150 cat "${_ckey}" "${_ccert}" "${_cca}" >"${_temppem}"
151 _ret="$?"
152
153 # Check that we could create the temporary file
154 if [ "${_ret}" != "0" ]; then
155 _err "Error code ${_ret} returned during PEM file creation"
156 [ -f "${_temppem}" ] && rm -f "${_temppem}"
157 return ${_ret}
158 fi
159
160 # Move PEM file into place
161 _info "Moving new certificate into place"
162 _debug _pem "${_pem}"
163 cat "${_temppem}" >"${_pem}"
164 _ret=$?
165
166 # Clean up temp file
167 [ -f "${_temppem}" ] && rm -f "${_temppem}"
168
169 # Deal with any failure of moving PEM file into place
170 if [ "${_ret}" != "0" ]; then
171 _err "Error code ${_ret} returned while moving new certificate into place"
172 return ${_ret}
173 fi
174
175 # Update .issuer file if requested
176 if [ "${Le_Deploy_lighttpd_issuer}" = "yes" ]; then
177 _info "Updating .issuer file"
178 _debug _issuer "${_issuer}"
179 cat "${_cca}" >"${_issuer}"
180 _ret="$?"
181
182 if [ "${_ret}" != "0" ]; then
183 _err "Error code ${_ret} returned while copying issuer/CA certificate into place"
184 return ${_ret}
185 fi
186 else
187 [ -f "${_issuer}" ] && _err "Issuer file update not requested but .issuer file exists"
188 fi
189
190 # Update .ocsp file if certificate was requested with --ocsp/--ocsp-must-staple option
191 if [ -z "${Le_OCSP_Staple}" ]; then
192 Le_OCSP_Staple="0"
193 fi
194 if [ "${Le_OCSP_Staple}" = "1" ]; then
195 _info "Updating OCSP stapling info"
196 _debug _ocsp "${_ocsp}"
197 _info "Extracting OCSP URL"
8419b42e 198 _ocsp_url=$(${ACME_OPENSSL_BIN:-openssl} x509 -noout -ocsp_uri -in "${_pem}")
f354e6de
MW
199 _debug _ocsp_url "${_ocsp_url}"
200
201 # Only process OCSP if URL was present
202 if [ "${_ocsp_url}" != "" ]; then
203 # Extract the hostname from the OCSP URL
204 _info "Extracting OCSP URL"
205 _ocsp_host=$(echo "${_ocsp_url}" | cut -d/ -f3)
206 _debug _ocsp_host "${_ocsp_host}"
207
208 # Only process the certificate if we have a .issuer file
209 if [ -r "${_issuer}" ]; then
210 # Check if issuer cert is also a root CA cert
8419b42e 211 _subjectdn=$(${ACME_OPENSSL_BIN:-openssl} x509 -in "${_issuer}" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)
f354e6de 212 _debug _subjectdn "${_subjectdn}"
8419b42e 213 _issuerdn=$(${ACME_OPENSSL_BIN:-openssl} x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)
f354e6de
MW
214 _debug _issuerdn "${_issuerdn}"
215 _info "Requesting OCSP response"
216 # If the issuer is a CA cert then our command line has "-CAfile" added
217 if [ "${_subjectdn}" = "${_issuerdn}" ]; then
218 _cafile_argument="-CAfile \"${_issuer}\""
219 else
220 _cafile_argument=""
221 fi
222 _debug _cafile_argument "${_cafile_argument}"
223 # if OpenSSL/LibreSSL is v1.1 or above, the format for the -header option has changed
8419b42e 224 _openssl_version=$(${ACME_OPENSSL_BIN:-openssl} version | cut -d' ' -f2)
f354e6de
MW
225 _debug _openssl_version "${_openssl_version}"
226 _openssl_major=$(echo "${_openssl_version}" | cut -d '.' -f1)
227 _openssl_minor=$(echo "${_openssl_version}" | cut -d '.' -f2)
228 if [ "${_openssl_major}" -eq "1" ] && [ "${_openssl_minor}" -ge "1" ] || [ "${_openssl_major}" -ge "2" ]; then
229 _header_sep="="
230 else
231 _header_sep=" "
232 fi
233 # Request the OCSP response from the issuer and store it
8419b42e 234 _openssl_ocsp_cmd="${ACME_OPENSSL_BIN:-openssl} ocsp \
f354e6de
MW
235 -issuer \"${_issuer}\" \
236 -cert \"${_pem}\" \
237 -url \"${_ocsp_url}\" \
238 -header Host${_header_sep}\"${_ocsp_host}\" \
239 -respout \"${_ocsp}\" \
240 -verify_other \"${_issuer}\" \
241 ${_cafile_argument} \
242 | grep -q \"${_pem}: good\""
243 _debug _openssl_ocsp_cmd "${_openssl_ocsp_cmd}"
244 eval "${_openssl_ocsp_cmd}"
245 _ret=$?
246 else
247 # Non fatal: No issuer file was present so no OCSP stapling file created
248 _err "OCSP stapling in use but no .issuer file was present"
249 fi
250 else
251 # Non fatal: No OCSP url was found int the certificate
252 _err "OCSP update requested but no OCSP URL was found in certificate"
253 fi
254
255 # Non fatal: Check return code of openssl command
256 if [ "${_ret}" != "0" ]; then
257 _err "Updating OCSP stapling failed with return code ${_ret}"
258 fi
259 else
260 # An OCSP file was already present but certificate did not have OCSP extension
261 if [ -f "${_ocsp}" ]; then
262 _err "OCSP was not requested but .ocsp file exists."
263 # Could remove the file at this step, although Lighttpd just ignores it in this case
264 # rm -f "${_ocsp}" || _err "Problem removing stale .ocsp file"
265 fi
266 fi
267
268 # Reload Lighttpd
269 _debug _reload "${_reload}"
270 eval "${_reload}"
271 _ret=$?
272 if [ "${_ret}" != "0" ]; then
273 _err "Error code ${_ret} during reload"
274 return ${_ret}
275 else
276 _info "Reload successful"
277 fi
278
279 return 0
280}