123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- #!/usr/bin/env sh
- # Here is the script to deploy the cert to your cpanel using the cpanel API.
- # Uses command line uapi. --user option is needed only if run as root.
- # Returns 0 when success.
- #
- # Configure DEPLOY_CPANEL_AUTO_<...> options to enable or restrict automatic
- # detection of deployment targets through UAPI (if not set, defaults below are used.)
- # - ENABLED : 'true' for multi-site / wildcard capability; otherwise single-site mode.
- # - NOMATCH : 'true' to allow deployment to sites that do not match the certificate.
- # - INCLUDE : Comma-separated list - sites must match this field.
- # - EXCLUDE : Comma-separated list - sites must NOT match this field.
- # INCLUDE/EXCLUDE both support non-lexical, glob-style matches using '*'
- #
- # Please note that I am no longer using Github. If you want to report an issue
- # or contact me, visit https://forum.webseodesigners.com/web-design-seo-and-hosting-f16/
- #
- # Written by Santeri Kannisto <santeri.kannisto@webseodesigners.com>
- # Public domain, 2017-2018
- #
- # export DEPLOY_CPANEL_USER=myusername
- # export DEPLOY_CPANEL_AUTO_ENABLED='true'
- # export DEPLOY_CPANEL_AUTO_NOMATCH='false'
- # export DEPLOY_CPANEL_AUTO_INCLUDE='*'
- # export DEPLOY_CPANEL_AUTO_EXCLUDE=''
- ######## Public functions #####################
- #domain keyfile certfile cafile fullchain
- cpanel_uapi_deploy() {
- _cdomain="$1"
- _ckey="$2"
- _ccert="$3"
- _cca="$4"
- _cfullchain="$5"
- # re-declare vars inherited from acme.sh but not passed to make ShellCheck happy
- : "${Le_Alt:=""}"
- _debug _cdomain "$_cdomain"
- _debug _ckey "$_ckey"
- _debug _ccert "$_ccert"
- _debug _cca "$_cca"
- _debug _cfullchain "$_cfullchain"
- if ! _exists uapi; then
- _err "The command uapi is not found."
- return 1
- fi
- # declare useful constants
- uapi_error_response='status: 0'
- # read cert and key files and urlencode both
- _cert=$(_url_encode <"$_ccert")
- _key=$(_url_encode <"$_ckey")
- _debug2 _cert "$_cert"
- _debug2 _key "$_key"
- if [ "$(id -u)" = 0 ]; then
- _getdeployconf DEPLOY_CPANEL_USER
- # fallback to _readdomainconf for old installs
- if [ -z "${DEPLOY_CPANEL_USER:=$(_readdomainconf DEPLOY_CPANEL_USER)}" ]; then
- _err "It seems that you are root, please define the target user name: export DEPLOY_CPANEL_USER=username"
- return 1
- fi
- _debug DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER"
- _savedeployconf DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER"
- _uapi_user="$DEPLOY_CPANEL_USER"
- fi
- # Load all AUTO envars and set defaults - see above for usage
- __cpanel_initautoparam ENABLED 'true'
- __cpanel_initautoparam NOMATCH 'false'
- __cpanel_initautoparam INCLUDE '*'
- __cpanel_initautoparam EXCLUDE ''
- # Auto mode
- if [ "$DEPLOY_CPANEL_AUTO_ENABLED" = "true" ]; then
- # call API for site config
- _response=$(uapi DomainInfo list_domains)
- # exit if error in response
- if [ -z "$_response" ] || [ "${_response#*"$uapi_error_response"}" != "$_response" ]; then
- _err "Error in deploying certificate - cannot retrieve sitelist:"
- _err "\n$_response"
- return 1
- fi
- # parse response to create site list
- sitelist=$(__cpanel_parse_response "$_response")
- _debug "UAPI sites found: $sitelist"
- # filter sitelist using configured domains
- # skip if NOMATCH is "true"
- if [ "$DEPLOY_CPANEL_AUTO_NOMATCH" = "true" ]; then
- _debug "DEPLOY_CPANEL_AUTO_NOMATCH is true"
- _info "UAPI nomatch mode is enabled - Will not validate sites are valid for the certificate"
- else
- _debug "DEPLOY_CPANEL_AUTO_NOMATCH is false"
- d="$(echo "${Le_Alt}," | sed -e "s/^$_cdomain,//" -e "s/,$_cdomain,/,/")"
- d="$(echo "$_cdomain,$d" | tr ',' '\n' | sed -e 's/\./\\./g' -e 's/\*/\[\^\.\]\*/g')"
- sitelist="$(echo "$sitelist" | grep -ix "$d")"
- _debug2 "Matched UAPI sites: $sitelist"
- fi
- # filter sites that do not match $DEPLOY_CPANEL_AUTO_INCLUDE
- _info "Applying sitelist filter DEPLOY_CPANEL_AUTO_INCLUDE: $DEPLOY_CPANEL_AUTO_INCLUDE"
- sitelist="$(echo "$sitelist" | grep -ix "$(echo "$DEPLOY_CPANEL_AUTO_INCLUDE" | tr ',' '\n' | sed -e 's/\./\\./g' -e 's/\*/\.\*/g')")"
- _debug2 "Remaining sites: $sitelist"
- # filter sites that match $DEPLOY_CPANEL_AUTO_EXCLUDE
- _info "Applying sitelist filter DEPLOY_CPANEL_AUTO_EXCLUDE: $DEPLOY_CPANEL_AUTO_EXCLUDE"
- sitelist="$(echo "$sitelist" | grep -vix "$(echo "$DEPLOY_CPANEL_AUTO_EXCLUDE" | tr ',' '\n' | sed -e 's/\./\\./g' -e 's/\*/\.\*/g')")"
- _debug2 "Remaining sites: $sitelist"
- # counter for success / failure check
- successes=0
- if [ -n "$sitelist" ]; then
- sitetotal="$(echo "$sitelist" | wc -l)"
- _debug "$sitetotal sites to deploy"
- else
- sitetotal=0
- _debug "No sites to deploy"
- fi
- # for each site: call uapi to publish cert and log result. Only return failure if all fail
- for site in $sitelist; do
- # call uapi to publish cert, check response for errors and log them.
- if [ -n "$_uapi_user" ]; then
- _response=$(uapi --user="$_uapi_user" SSL install_ssl domain="$site" cert="$_cert" key="$_key")
- else
- _response=$(uapi SSL install_ssl domain="$site" cert="$_cert" key="$_key")
- fi
- if [ "${_response#*"$uapi_error_response"}" != "$_response" ]; then
- _err "Error in deploying certificate to $site:"
- _err "$_response"
- else
- successes=$((successes + 1))
- _debug "$_response"
- _info "Succcessfully deployed to $site"
- fi
- done
- # Raise error if all updates fail
- if [ "$sitetotal" -gt 0 ] && [ "$successes" -eq 0 ]; then
- _err "Could not deploy to any of $sitetotal sites via UAPI"
- _debug "successes: $successes, sitetotal: $sitetotal"
- return 1
- fi
- _info "Successfully deployed certificate to $successes of $sitetotal sites via UAPI"
- return 0
- else
- # "classic" mode - will only try to deploy to the primary domain; will not check UAPI first
- if [ -n "$_uapi_user" ]; then
- _response=$(uapi --user="$_uapi_user" SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
- else
- _response=$(uapi SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
- fi
- if [ "${_response#*"$uapi_error_response"}" != "$_response" ]; then
- _err "Error in deploying certificate:"
- _err "$_response"
- return 1
- fi
- _debug response "$_response"
- _info "Certificate successfully deployed"
- return 0
- fi
- }
- ######## Private functions #####################
- # Internal utility to process YML from UAPI - only looks at main_domain and sub_domains
- #[response]
- __cpanel_parse_response() {
- if [ $# -gt 0 ]; then resp="$*"; else resp="$(cat)"; fi
- echo "$resp" |
- sed -En \
- -e 's/\r$//' \
- -e 's/^( *)([_.[:alnum:]]+) *: *(.*)/\1,\2,\3/p' \
- -e 's/^( *)- (.*)/\1,-,\2/p' |
- awk -F, '{
- level = length($1)/2;
- section[level] = $2;
- for (i in section) {if (i > level) {delete section[i]}}
- if (length($3) > 0) {
- prefix="";
- for (i=0; i < level; i++)
- { prefix = (prefix)(section[i])("/") }
- printf("%s%s=%s\n", prefix, $2, $3);
- }
- }' |
- sed -En -e 's/^result\/data\/(main_domain|sub_domains\/-)=(.*)$/\2/p'
- }
- # Load parameter by prefix+name - fallback to default if not set, and save to config
- #pname pdefault
- __cpanel_initautoparam() {
- pname="$1"
- pdefault="$2"
- pkey="DEPLOY_CPANEL_AUTO_$pname"
- _getdeployconf "$pkey"
- [ -n "$(eval echo "\"\$$pkey\"")" ] || eval "$pkey=\"$pdefault\""
- _debug2 "$pkey" "$(eval echo "\"\$$pkey\"")"
- _savedeployconf "$pkey" "$(eval echo "\"\$$pkey\"")"
- }
|