1#!/usr/local/bin/bash 2 3deploy_challenge() { 4 local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}" 5 6 # This hook is called once for every domain that needs to be 7 # validated, including any alternative names you may have listed. 8 # 9 # Parameters: 10 # - DOMAIN 11 # The domain name (CN or subject alternative name) being 12 # validated. 13 # - TOKEN_FILENAME 14 # The name of the file containing the token to be served for HTTP 15 # validation. Should be served by your web server as 16 # /.well-known/acme-challenge/${TOKEN_FILENAME}. 17 # - TOKEN_VALUE 18 # The token value that needs to be served for validation. For DNS 19 # validation, this is what you want to put in the _acme-challenge 20 # TXT record. For HTTP validation it is the value that is expected 21 # be found in the $TOKEN_FILENAME file. 22 23 # Simple example: Use nsupdate with local named 24 # 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 25} 26 27clean_challenge() { 28 local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}" 29 30 # This hook is called after attempting to validate each domain, 31 # whether or not validation was successful. Here you can delete 32 # files or DNS records that are no longer needed. 33 # 34 # The parameters are the same as for deploy_challenge. 35 36 # Simple example: Use nsupdate with local named 37 # 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 38} 39 40sync_cert() { 41 local KEYFILE="${1}" CERTFILE="${2}" FULLCHAINFILE="${3}" CHAINFILE="${4}" REQUESTFILE="${5}" 42 43 # This hook is called after the certificates have been created but before 44 # they are symlinked. This allows you to sync the files to disk to prevent 45 # creating a symlink to empty files on unexpected system crashes. 46 # 47 # This hook is not intended to be used for further processing of certificate 48 # files, see deploy_cert for that. 49 # 50 # Parameters: 51 # - KEYFILE 52 # The path of the file containing the private key. 53 # - CERTFILE 54 # The path of the file containing the signed certificate. 55 # - FULLCHAINFILE 56 # The path of the file containing the full certificate chain. 57 # - CHAINFILE 58 # The path of the file containing the intermediate certificate(s). 59 # - REQUESTFILE 60 # The path of the file containing the certificate signing request. 61 62 # Simple example: sync the files before symlinking them 63 # sync "${KEYFILE}" "${CERTFILE}" "${FULLCHAINFILE}" "${CHAINFILE}" "${REQUESTFILE}" 64} 65 66deploy_cert() { 67 local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" TIMESTAMP="${6}" 68 69 # This hook is called once for each certificate that has been 70 # produced. Here you might, for instance, copy your new certificates 71 # to service-specific locations and reload the service. 72 # 73 # Parameters: 74 # - DOMAIN 75 # The primary domain name, i.e. the certificate common 76 # name (CN). 77 # - KEYFILE 78 # The path of the file containing the private key. 79 # - CERTFILE 80 # The path of the file containing the signed certificate. 81 # - FULLCHAINFILE 82 # The path of the file containing the full certificate chain. 83 # - CHAINFILE 84 # The path of the file containing the intermediate certificate(s). 85 # - TIMESTAMP 86 # Timestamp when the specified certificate was created. 87 88 # Simple example: Copy file to nginx config 89 # cp "${KEYFILE}" "${FULLCHAINFILE}" /etc/nginx/ssl/; chown -R nginx: /etc/nginx/ssl 90 # systemctl reload nginx 91} 92 93deploy_ocsp() { 94 local DOMAIN="${1}" OCSPFILE="${2}" TIMESTAMP="${3}" 95 96 # This hook is called once for each updated ocsp stapling file that has 97 # been produced. Here you might, for instance, copy your new ocsp stapling 98 # files to service-specific locations and reload the service. 99 # 100 # Parameters: 101 # - DOMAIN 102 # The primary domain name, i.e. the certificate common 103 # name (CN). 104 # - OCSPFILE 105 # The path of the ocsp stapling file 106 # - TIMESTAMP 107 # Timestamp when the specified ocsp stapling file was created. 108 109 # Simple example: Copy file to nginx config 110 # cp "${OCSPFILE}" /etc/nginx/ssl/; chown -R nginx: /etc/nginx/ssl 111 # systemctl reload nginx 112} 113 114 115unchanged_cert() { 116 local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" 117 118 # This hook is called once for each certificate that is still 119 # valid and therefore wasn't reissued. 120 # 121 # Parameters: 122 # - DOMAIN 123 # The primary domain name, i.e. the certificate common 124 # name (CN). 125 # - KEYFILE 126 # The path of the file containing the private key. 127 # - CERTFILE 128 # The path of the file containing the signed certificate. 129 # - FULLCHAINFILE 130 # The path of the file containing the full certificate chain. 131 # - CHAINFILE 132 # The path of the file containing the intermediate certificate(s). 133} 134 135invalid_challenge() { 136 local DOMAIN="${1}" RESPONSE="${2}" 137 138 # This hook is called if the challenge response has failed, so domain 139 # owners can be aware and act accordingly. 140 # 141 # Parameters: 142 # - DOMAIN 143 # The primary domain name, i.e. the certificate common 144 # name (CN). 145 # - RESPONSE 146 # The response that the verification server returned 147 148 # Simple example: Send mail to root 149 # printf "Subject: Validation of ${DOMAIN} failed!\n\nOh noez!" | sendmail root 150} 151 152request_failure() { 153 local STATUSCODE="${1}" REASON="${2}" REQTYPE="${3}" HEADERS="${4}" 154 155 # This hook is called when an HTTP request fails (e.g., when the ACME 156 # server is busy, returns an error, etc). It will be called upon any 157 # response code that does not start with '2'. Useful to alert admins 158 # about problems with requests. 159 # 160 # Parameters: 161 # - STATUSCODE 162 # The HTML status code that originated the error. 163 # - REASON 164 # The specified reason for the error. 165 # - REQTYPE 166 # The kind of request that was made (GET, POST...) 167 # - HEADERS 168 # HTTP headers returned by the CA 169 170 # Simple example: Send mail to root 171 # printf "Subject: HTTP request failed failed!\n\nA http request failed with status ${STATUSCODE}!" | sendmail root 172} 173 174generate_csr() { 175 local DOMAIN="${1}" CERTDIR="${2}" ALTNAMES="${3}" 176 177 # This hook is called before any certificate signing operation takes place. 178 # It can be used to generate or fetch a certificate signing request with external 179 # tools. 180 # The output should be just the certificate signing request formatted as PEM. 181 # 182 # Parameters: 183 # - DOMAIN 184 # The primary domain as specified in domains.txt. This does not need to 185 # match with the domains in the CSR, it's basically just the directory name. 186 # - CERTDIR 187 # Certificate output directory for this particular certificate. Can be used 188 # for storing additional files. 189 # - ALTNAMES 190 # All domain names for the current certificate as specified in domains.txt. 191 # Again, this doesn't need to match with the CSR, it's just there for convenience. 192 193 # Simple example: Look for pre-generated CSRs 194 # if [ -e "${CERTDIR}/pre-generated.csr" ]; then 195 # cat "${CERTDIR}/pre-generated.csr" 196 # fi 197} 198 199startup_hook() { 200 # This hook is called before the cron command to do some initial tasks 201 # (e.g. starting a webserver). 202 203 : 204} 205 206exit_hook() { 207 local ERROR="${1:-}" 208 209 # This hook is called at the end of the cron command and can be used to 210 # do some final (cleanup or other) tasks. 211 # 212 # Parameters: 213 # - ERROR 214 # Contains error message if dehydrated exits with error 215} 216 217HANDLER="$1"; shift 218if [[ "${HANDLER}" =~ ^(deploy_challenge|clean_challenge|sync_cert|deploy_cert|deploy_ocsp|unchanged_cert|invalid_challenge|request_failure|generate_csr|startup_hook|exit_hook)$ ]]; then 219 "$HANDLER" "$@" 220fi 221