HestiaCP panel: Let’s encrypt finalize bad status 403

Linux Ubuntu  /  Linux Debian  /  Linux Mint  /  Tweaks  




Sometimes we can get error 403 when activating Let's Encrypt SSL.


The main problem is: Let's Encrypt's validation service working slower than HestiaCP, but HestiaCP doesn't wait until validation finish and doesn't check if validation is success.

To fix this problem we should add some code to file /usr/local/hestia/bin/v-add-letsencrypt-domain

The better way is just backup old file and overwrite it by code below


#!/bin/bash
# info: check letsencrypt domain
# options: USER DOMAIN [ALIASES] [MAIL]
#
# example: v-add-letsencrypt-domain admin wonderland.com www.wonderland.com,demo.wonderland.com
# example: v-add-letsencrypt-domain admin wonderland.com '' yes
#
# This function check and validates domain with Let's Encrypt

#----------------------------------------------------------#
#                Variables & Functions                     #
#----------------------------------------------------------#

# Argument definition
user=$1
domain=$2
aliases=$3
mail=${4// /}

# Includes
# shellcheck source=/etc/hestiacp/hestia.conf
source /etc/hestiacp/hestia.conf
# shellcheck source=/usr/local/hestia/func/main.sh
source $HESTIA/func/main.sh
# shellcheck source=/usr/local/hestia/func/domain.sh
source $HESTIA/func/domain.sh
# load config file
source_conf "$HESTIA/conf/hestia.conf"

# LE API
LE_API='https://acme-v02.api.letsencrypt.org'

if [[ "$LE_STAGING" = 'yes' ]]; then
	LE_API='https://acme-staging-v02.api.letsencrypt.org'
fi

# encode base64
encode_base64() {
	cat | base64 | tr '+/' '-_' | tr -d '\r\n='
}

# Let's Encrypt v2 curl function
query_le_v2() {
	protected='{"nonce": "'$3'",'
	protected=''$protected' "url": "'$1'",'
	protected=''$protected' "alg": "RS256", "kid": "'$KID'"}'
	content="Content-Type: application/jose+json"

	payload_=$(echo -n "$2" | encode_base64)
	protected_=$(echo -n "$protected" | encode_base64)
	signature_=$(printf "%s" "$protected_.$payload_" \
		| openssl dgst -sha256 -binary -sign $USER_DATA/ssl/user.key \
		| encode_base64)

	post_data='{"protected":"'"$protected_"'",'
	post_data=$post_data'"payload":"'"$payload_"'",'
	post_data=$post_data'"signature":"'"$signature_"'"}'

	# Save http response to file passed as "$4" arg or print to stdout if not provided
	# http response headers are always sent to stdout
	local save_to_file=${4:-"/dev/stdout"}
	curl --location --user-agent "HestiaCP" --insecure --retry 5 --retry-connrefused --silent --dump-header /dev/stdout --data "$post_data" "$1" --header "$content" --output "$save_to_file"
	debug_log "API call" "exit status: $?"
}

#----------------------------------------------------------#
#                    Verifications                         #
#----------------------------------------------------------#

check_args '2' "$#" 'USER DOMAIN [ALIASES] [MAIL]'
is_format_valid 'user' 'domain' 'aliases'
is_object_valid 'user' 'USER' "$user"
is_object_unsuspended 'user' 'USER' "$user"
if [ -n "$mail" ]; then
	is_boolean_format_valid "$mail" 'mail'
fi

# Set DNS CAA record retrieval commands
if [ -n "$DNS_SYSTEM" ]; then
	dns_domain=$($BIN/v-list-dns-domains "$user" | grep "$domain" | cut -d' ' -f1)
	caa_record=$($BIN/v-list-dns-records "$user" "$domain" | grep -i "CAA" | grep -i "letsencrypt.org" | cut -d' ' -f1)
fi

if [ -z "$mail" ] || [ "$mail" = 'no' ]; then
	mail=''
	is_system_enabled "$WEB_SYSTEM" 'WEB_SYSTEM'
	is_object_valid 'web' 'DOMAIN' "$domain"
	is_object_unsuspended 'web' 'DOMAIN' "$domain"
	get_domain_values 'web'
	# check if alias is the letsencrypt wildcard domain, if not, make the normal checks
	if [[ "$aliases" != "*.$domain" ]]; then
		for alias in $(echo "$aliases" | tr ',' '\n' | sort -u); do
			check_alias="$(echo $ALIAS | tr ',' '\n' | grep ^$alias$)"
			if [ -z "$check_alias" ]; then
				check_result "$E_NOTEXIST" "domain alias $alias doesn't exist"
			fi
		done
	fi
else
	is_system_enabled "$MAIL_SYSTEM" 'MAIL_SYSTEM'
	is_object_valid 'mail' 'DOMAIN' "$domain"
	is_object_unsuspended 'mail' 'DOMAIN' "$domain"
fi

# Dump debug info
debug_log() {
	echo -e "\n==[${1}]==\n${2}\n" >> "$log_file"
}

# Perform verification if read-only mode is enabled
check_hestia_demo_mode

#----------------------------------------------------------#
#                       Action                             #
#----------------------------------------------------------#

# Generate correct variables for mail domain SSL certificates
if [ -n "$mail" ]; then
	root_domain=$domain
	domain="mail.$root_domain"
	webmail=$(get_object_value "mail" "DOMAIN" "$root_domain" '$WEBMAIL')
	if [ -n "$webmail" ]; then
		aliases="$WEBMAIL_ALIAS.$root_domain"
	fi
else
	parse_object_kv_list $(grep "DOMAIN='$domain'" $USER_DATA/web.conf)

	domain_redirect="$REDIRECT"
	if [[ -n "$domain_redirect" ]]; then
		domain_redirect_code="$REDIRECT_CODE"
		$BIN/v-delete-web-domain-redirect $user $domain
	fi

	domain_forcessl="$SSL_FORCE"
	if [[ "$domain_forcessl" == 'yes' ]]; then
		$BIN/v-delete-web-domain-ssl-force $user $domain
	fi
fi

log_file="/var/log/hestia/LE-${user}-${domain}.log"
touch "$log_file"
chmod 600 "$log_file"

echo -e "\n\n=============================
Date Time: $(date +%Y-%m-%d) $(date +%H:%M:%S)
WEB_SYSTEM: ${WEB_SYSTEM}
PROXY_SYSTEM: ${PROXY_SYSTEM}
user: ${user}
domain: ${domain}
" >> "$log_file"

# Registering LetsEncrypt user account
$BIN/v-add-letsencrypt-user $user
if [ "$?" -ne 0 ]; then
	touch $HESTIA/data/queue/letsencrypt.pipe
	sed -i "/ $domain /d" $HESTIA/data/queue/letsencrypt.pipe
	send_notice "LETSENCRYPT" "Account registration failed ($user)"
	check_result "$E_CONNECT" "LE account registration ($user)" > /dev/null
fi

# Parsing LetsEncrypt account data
source $USER_DATA/ssl/le.conf

# Checking wildcard alias
if [ "$aliases" = "*.$domain" ]; then
	wildcard='yes'
	proto="dns-01"
	if [ ! -e "$HESTIA/data/users/$user/dns/$domain.conf" ]; then
		check_result "$E_NOTEXIST" "DNS domain $domain doesn't exist"
	fi
else
	proto="http-01"
fi

echo -e "
- aliases: ${aliases}
- proto: ${proto}
- wildcard: ${wildcard}
" >> "$log_file"

# Check if dns records exist for requested domain/aliases
if [ "$proto" = "http-01" ]; then
	for identifier in $(echo $domain,$aliases | tr ',' '\n' | sort -u); do
		if [[ "$identifier" = *[![:ascii:]]* ]]; then
			identifier=$(idn2 --quiet $identifier)
		fi
		if ! nslookup "${identifier}" > /dev/null 2>&1; then
			# Attempt against Cloudflare DNS
			if ! nslookup "${identifier}" 1.1.1.1 > /dev/null 2>&1; then
				check_result "$E_NOTEXIST" "DNS record for $identifier doesn't exist"
			fi
		fi
	done
fi

# Ensure DNS CAA record exists for Let's Encrypt before requesting certificate
if [ -n "$DNS_SYSTEM" ]; then
	# Check for DNS zone
	if [ "$dns_domain" = "$domain" ]; then
		# Replace DNS domain CAA records with Let's Encrypt values
		if [ -z "$caa_record" ]; then
			$BIN/v-add-dns-record "$user" "$domain" '@' 'CAA' '0 issue "letsencrypt.org"'
		else
			$BIN/v-delete-dns-record "$user" "$domain" "$caa_record"
			$BIN/v-add-dns-record "$user" "$domain" '@' 'CAA' '0 issue "letsencrypt.org"'
		fi
	fi
fi

# Requesting nonce / STEP 1
answer=$(curl --user-agent "HestiaCP" -s -I "$LE_API/directory")
nonce=$(echo "$answer" | grep -i nonce | cut -f2 -d \  | tr -d '\r\n')
status=$(echo "$answer" | grep HTTP/ | tail -n1 | cut -f 2 -d ' ')

debug_log "Step 1" "- status: ${status}\n- nonce: ${nonce}\n- answer: ${answer}"

if [[ "$status" -ne 200 ]]; then
	# Delete DNS CAA record
	if [ -n "$DNS_SYSTEM" ]; then
		if [ "$dns_domain" = "$domain" ]; then
			if [ -n "$caa_record" ]; then
				$BIN/v-delete-dns-record "$user" "$domain" "$caa_record"
			fi
		fi
	fi
	check_result "$E_CONNECT" "Let's Encrypt nonce request status $status ($domain)"
fi

# Placing new order / STEP 2
url="$LE_API/acme/new-order"
payload='{"identifiers":['
for identifier in $(echo $domain,$aliases | tr ',' '\n' | sort -u); do
	if [[ "$identifier" = *[![:ascii:]]* ]]; then
		identifier=$(idn2 --quiet $identifier)
	fi
	payload=$payload'{"type":"dns","value":"'$identifier'"},'
done
payload=$(echo "$payload" | sed "s/,$//")
payload=$payload']}'
answer=$(query_le_v2 "$url" "$payload" "$nonce")
nonce=$(echo "$answer" | grep -i nonce | cut -f2 -d \  | tr -d '\r\n')
authz=$(echo "$answer" | grep "acme/authz" | cut -f2 -d '"')
finalize=$(echo "$answer" | grep 'finalize":' | cut -f4 -d '"')
status=$(echo "$answer" | grep HTTP/ | tail -n1 | cut -f2 -d ' ')
order=$(echo -e "$answer" | grep -i location | cut -f2 -d \  | tr -d '\r\n')

debug_log "Step 2" "- status: ${status}\n- nonce: ${nonce}\n- authz: ${authz}\n- finalize: ${finalize}\n- payload: ${payload}\n- answer: ${answer}\n order: ${order}"

if [[ "$status" -ne 201 ]]; then
	# Delete DNS CAA record
	if [ -n "$DNS_SYSTEM" ]; then
		if [ "$dns_domain" = "$domain" ]; then
			if [ -n "$caa_record" ]; then
				$BIN/v-delete-dns-record "$user" "$domain" "$caa_record"
			fi
		fi
	fi
	check_result $E_CONNECT "Let's Encrypt new auth status $status ($domain)"
fi

# Requesting authorization token / STEP 3
for auth in $authz; do
	payload=''
	answer=$(query_le_v2 "$auth" "$payload" "$nonce")
	url=$(echo "$answer" | grep -A3 $proto | grep -m1 url | cut -f 4 -d \")
	token=$(echo "$answer" | grep -A3 $proto | grep token | cut -f 4 -d \")
	nonce=$(echo "$answer" | grep -i nonce | cut -f2 -d \  | tr -d '\r\n')
	status=$(echo "$answer" | grep HTTP/ | tail -n1 | cut -f 2 -d ' ')

	debug_log "Step 3" "- status: ${status}\n- nonce: ${nonce}\n- url: ${url}\n- token: ${token}\n- answer: ${answer}"

	if [[ "$status" -ne 200 ]]; then
		# Delete DNS CAA record
		if [ -n "$DNS_SYSTEM" ]; then
			dns_domain=$($BIN/v-list-dns-domains "$user" | grep "$domain" | cut -d' ' -f1)
			caa_record=$($BIN/v-list-dns-records "$user" "$domain" | grep -i "letsencrypt" | cut -d' ' -f1)

			if [ "$dns_domain" = "$domain" ]; then
				if [ -n "$caa_record" ]; then
					$BIN/v-delete-dns-record "$user" "$domain" "$caa_record"
				fi
			fi
		fi
		check_result "$E_CONNECT" "Let's Encrypt acme/authz bad status $status ($domain)"
	fi

	# Accepting challenge / STEP 4
	if [ "$wildcard" = 'yes' ]; then
		record=$(printf "%s" "$token.$THUMB" \
			| openssl dgst -sha256 -binary | encode_base64)
		old_records=$($BIN/v-list-dns-records "$user" "$domain" plain | grep 'TXT')
		old_records=$(echo "$old_records" | grep _acme-challenge | cut -f 1)
		for old_record in $old_records; do
			$BIN/v-delete-dns-record "$user" "$domain" "$old_record"
		done
		echo "Adding DNS record"
		$BIN/v-add-dns-record "$user" "$domain" "_acme-challenge" "TXT" "$record"
		check_result $? "DNS _acme-challenge record wasn't created ($domain)"
	else
		if [ -z "$mail" ]; then
			if [ "$WEB_SYSTEM" = 'nginx' ] || [ "$PROXY_SYSTEM" = 'nginx' ]; then
				conf="$HOMEDIR/$user/conf/web/$domain/nginx.conf_letsencrypt"
				sconf="$HOMEDIR/$user/conf/web/$domain/nginx.ssl.conf_letsencrypt"
				echo 'location ~ "^/\.well-known/acme-challenge/([-_A-Za-z0-9]+)$" {' \
					> $conf
				echo '    default_type text/plain;' >> $conf
				echo '    return 200 "$1.'$THUMB'";' >> $conf
				echo '}' >> $conf
				if [ ! -e "$sconf" ]; then
					ln -s "$conf" "$sconf"
				fi
				if [ -n "$PROXY_SYSTEM" ]; then
					$BIN/v-restart-proxy
					check_result $? "Proxy restart failed" > /dev/null
				fi
			else
				# Get root directory from configuration
				domain_config="$HOMEDIR/$user/conf/web/$domain"
				if [ -f "$domain_config/apache2.conf" ]; then
					well_known="$(cat $domain_config/apache2.conf | egrep \
						'^\s+DocumentRoot' | awk '{split($0, a, " "); \
                                print a[2]}')/.well-known"
				else
					well_known="$(cat $domain_config/nginx.conf | egrep '^\s+root' \
						| awk '{split($0, a, " "); print a[2]}' \
						| sed 's/;$//')/.well-known"
				fi
				acme_challenge="$well_known/acme-challenge"
				echo "Creating $acme_challenge..."
				mkdir -p $acme_challenge
				echo "$token.$THUMB" > $acme_challenge/$token
				chown -R $user:$user $well_known
			fi
		else
			if [ "$WEB_SYSTEM" = 'nginx' ] || [ "$PROXY_SYSTEM" = 'nginx' ]; then
				conf="$HOMEDIR/$user/conf/mail/$root_domain/nginx.conf_letsencrypt"
				sconf="$HOMEDIR/$user/conf/mail/$root_domain/nginx.ssl.conf_letsencrypt"
				echo 'location ~ "^/\.well-known/acme-challenge/([-_A-Za-z0-9]+)$" {' \
					> $conf
				echo '    default_type text/plain;' >> $conf
				echo '    return 200 "$1.'$THUMB'";' >> $conf
				echo '}' >> $conf
				if [ ! -e "$sconf" ]; then
					ln -s "$conf" "$sconf"
				fi
				if [ -n "$PROXY_SYSTEM" ]; then
					$BIN/v-restart-proxy
					check_result $? "Proxy restart failed" > /dev/null
				fi
			else
				get_object_value 'mail' 'DOMAIN' "$root_domain" "WEBMAIL"
				if [ -n "$WEBMAIL" ]; then
					well_known="/var/lib/$WEBMAIL/.well-known"
					acme_challenge="$well_known/acme-challenge"
					mkdir -p $acme_challenge
					echo "$token.$THUMB" > $acme_challenge/$token
					chown -R $user:$user $well_known
				fi
			fi
		fi
		if [ "$WEB_SYSTEM" = 'nginx' ]; then
			$BIN/v-restart-web
			service nginx restart
			check_result $? "Web restart failed" > /dev/null
		fi
	fi

	if [ "$DNS_CLUSTER" = "yes" ]; then
		$BIN/v-update-sys-queue dns-cluster
	fi

	# Requesting ACME validation / STEP 5
	validation_check=$(echo "$answer" | grep '"valid"')
	if [[ -n "$validation_check" ]]; then
		validation='valid'
	else
		validation='pending'
		sleep 5
	fi
	service nginx restart
	i=1
	while [ "$validation" = 'pending' ]; do
		while [[ true ]];do
			payload='{}'
			answer=$(query_le_v2 "$url" "$payload" "$nonce")
			validation=$(echo "$answer" | grep -A1 $proto | tail -n1 | cut -f4 -d \")
	    		nonce=$(echo "$answer" | grep -i nonce | cut -f2 -d \  | tr -d '\r\n')
			status=$(echo "$answer" | grep HTTP/ | tail -n1 | cut -f 2 -d ' ')
			details=$(echo "$answer" | grep detail | cut -f 1 -d ',' | cut -f 2-4 -d ':' | cut -f 2 -d '"')
			x=`curl "$url"`
			if [[ `echo "$x" | grep addressesResolved`  != "" ]];then break;fi
#			echo $x
			sleep 2
		done
		debug_log "Step 5" "- status: ${status}\n- url: ${url}\n- nonce: ${nonce}\n- validation: ${validation}\n- details: ${details}\n- answer: ${answer}"

		if [[ "$status" -ne 200 ]]; then
			# Delete DNS CAA record
			if [ -n "$DNS_SYSTEM" ]; then
				dns_domain=$($BIN/v-list-dns-domains "$user" | grep "$domain" | cut -d' ' -f1)
				caa_record=$($BIN/v-list-dns-records "$user" "$domain" | grep -i "letsencrypt" | cut -d' ' -f1)

				if [ "$dns_domain" = "$domain" ]; then
					if [ -n "$caa_record" ]; then
						$BIN/v-delete-dns-record "$user" "$domain" "$caa_record"
					fi
				fi
			fi
			# Download debug info from LE server
			result=$(wget -qO- $url)
			debug_log "Debug information Step 5" "$result"
			details=$(echo $result | jq '.error.detail')
			error_code=$(echo $result | jq '.error.status')

			debug_log "Abort Step 5" "=> Wrong status"
			check_result "$E_CONNECT" "Let's Encrypt validation status $status ($domain). Details: $error_code:$details"
		fi

		i=$((i + 1))
		if [ "$i" -gt 10 ]; then
			# Delete DNS CAA record
			if [ -n "$DNS_SYSTEM" ]; then
				dns_domain=$($BIN/v-list-dns-domains "$user" | grep "$domain" | cut -d' ' -f1)
				caa_record=$($BIN/v-list-dns-records "$user" "$domain" | grep -i "letsencrypt" | cut -d' ' -f1)

				if [ "$dns_domain" = "$domain" ]; then
					if [ -n "$caa_record" ]; then
						$BIN/v-delete-dns-record "$user" "$domain" "$caa_record"
					fi
				fi
			fi
			debug_log "Abort Step 5" "=> Too many validation retries"
			check_result "$E_CONNECT" "Let's Encrypt domain validation timeout ($domain)"
		fi
		sleep $((i * 2))
	done
	if [ "$validation" = 'invalid' ]; then
		# Delete DNS CAA record
		if [ -n "$DNS_SYSTEM" ]; then
			dns_domain=$($BIN/v-list-dns-domains "$user" | grep "$domain" | cut -d' ' -f1)
			caa_record=$($BIN/v-list-dns-records "$user" "$domain" | grep -i "letsencrypt" | cut -d' ' -f1)

			if [ "$dns_domain" = "$domain" ]; then
				if [ -n "$caa_record" ]; then
					$BIN/v-delete-dns-record "$user" "$domain" "$caa_record"
				fi
			fi
		fi
		check_result "$E_CONNECT" "Let's Encrypt domain verification failed ($domain)"
	fi
done

# Generating new ssl certificate
ssl_dir=$($BIN/v-generate-ssl-cert "$domain" "info@$domain" "US" "California" \
	"San Francisco" "Hestia" "IT" "$aliases" | tail -n1 | awk '{print $2}')

# Sending CSR to finalize order / STEP 6
csr=$(openssl req -in $ssl_dir/$domain.csr -outform DER | encode_base64)
payload='{"csr":"'$csr'"}'
answer=$(query_le_v2 "$finalize" "$payload" "$nonce")
nonce=$(echo "$answer" | grep -i nonce | cut -f2 -d \  | tr -d '\r\n')
status=$(echo "$answer" | grep HTTP/ | tail -n1 | cut -f 2 -d ' ')
certificate=$(echo "$answer" | grep 'certificate":' | cut -f4 -d '"')

debug_log "Step 6" "- status: ${status}\n- nonce: ${nonce}\n- payload: ${payload}\n- certificate: ${certificate}\n- answer: ${answer}"

if [[ "$status" -ne 200 ]]; then
	[ -d "$ssl_dir" ] && rm -rf "$ssl_dir"
	check_result "$E_CONNECT" "Let's Encrypt finalize bad status $status ($domain)"
fi

if [ -z "$certificate" ]; then
	validation="processing"
	i=1
	while [ "$validation" = "processing" ]; do
		answer=$(query_le_v2 "$order" "" "$nonce")
		i=$((i + 1))

		nonce=$(echo "$answer" | grep -i nonce | cut -f2 -d \  | tr -d '\r\n')
		status=$(echo "$answer" | grep HTTP/ | tail -n1 | cut -f 2 -d ' ')
		validation=$(echo "$answer" | grep 'status":' | cut -f4 -d '"')
		certificate=$(echo "$answer" | grep 'certificate":' | cut -f4 -d '"')
		sleep $((i * 2)) # Sleep for 2s, 4s, 6s, 8s
		if [ $i -gt 10 ]; then
			check_result "$E_CONNECT" "Certificate processing timeout ($domain)"
		fi
		debug_log "Step 7" "- status: ${status}\n- nonce: ${nonce}\n- payload: ${payload}\n- certificate: ${certificate}\n- answer: ${answer}"
	done
fi

# Downloading signed certificate / STEP 7
status=0
retry=0

while [[ $status != 200 && $retry -lt 3 ]]; do

	answer=$(query_le_v2 "$certificate" "" "$nonce" "$ssl_dir/$domain.pem")
	status=$(echo "$answer" | grep HTTP/ | tail -n1 | cut -f 2 -d ' ')

	debug_log "Step 8" "- status: ${status}\n- retry: ${retry}\n- answer: ${answer}"

	if [[ $status != 200 ]]; then
		retry=$((retry + 1))
		sleep $((retry * 2)) # Sleep for 2s, 4s, 6s, 8s
	fi

done

# Fallback on depreciated download method for certs (unauthenticated GET)
if [[ $status != 200 ]]; then
	answer=$(curl --insecure --user-agent "HestiaCP" --retry 5 --retry-connrefused --silent --dump-header /dev/stdout "$certificate" --output "$ssl_dir/$domain.pem")
	status=$(echo "$answer" | grep HTTP/ | tail -n1 | cut -f 2 -d ' ')

	debug_log "Step 8 - Fallback" "- status: ${status}\n- answer: ${answer}"
fi

debug_log "CERT DIR" "$(ls -las "$ssl_dir/")"
debug_log "CERT PEM" "$(cat "$ssl_dir/$domain.pem")"

if [[ "$status" -ne 200 ]]; then
	[ -d "$ssl_dir" ] && rm -rf "$ssl_dir"
	check_result "$E_NOTEXIST" "Let's Encrypt downloading signed cert failed status:$status ($domain)"
fi

# Splitting up downloaded pem
crt_end=$(grep -n 'END CERTIFICATE' $ssl_dir/$domain.pem | head -n1 | cut -f1 -d:)
head -n $crt_end $ssl_dir/$domain.pem > $ssl_dir/$domain.crt

pem_lines=$(wc -l $ssl_dir/$domain.pem | cut -f 1 -d ' ')
ca_end=$(grep -n 'BEGIN CERTIFICATE' $ssl_dir/$domain.pem | tail -n1 | cut -f 1 -d :)
ca_end=$((pem_lines - crt_end + 1))
tail -n $ca_end $ssl_dir/$domain.pem > $ssl_dir/$domain.ca

debug_log "CERT CRT" "$(cat "$ssl_dir/$domain.crt")"
debug_log "CERT CA-1" "$(cat "$ssl_dir/$domain.ca")"
# Temporary fix for double "END CERTIFICATE"
if [[ $(head -n 1 $ssl_dir/$domain.ca) = "-----END CERTIFICATE-----" ]]; then
	sed -i '1,2d' $ssl_dir/$domain.ca
fi
debug_log "CERT CA-2" "$(cat "$ssl_dir/$domain.ca")"

# Rename certs for mail
if [ -n "$mail" ]; then
	mv $ssl_dir/$domain.ca $ssl_dir/$root_domain.ca
	mv $ssl_dir/$domain.crt $ssl_dir/$root_domain.crt
	mv $ssl_dir/$domain.csr $ssl_dir/$root_domain.csr
	mv $ssl_dir/$domain.key $ssl_dir/$root_domain.key
	mv $ssl_dir/$domain.pem $ssl_dir/$root_domain.pem
fi

# Adding SSL
if [ -z "$mail" ]; then
	ssl_home="$(get_object_value 'web' 'DOMAIN' "$domain" '$SSL_HOME')"
	ssl_enabled="$(get_object_value 'web' 'DOMAIN' "$domain" '$SSL')"
	if [ "$ssl_enabled" = "yes" ]; then
		$BIN/v-update-web-domain-ssl "$user" "$domain" "$ssl_dir" "updatessl"
	else
		$BIN/v-add-web-domain-ssl "$user" "$domain" "$ssl_dir" "$ssl_home" "updatessl"
	fi
else
	# TODO replace with v-update-mail-domain-ssl if ssl is enabled
	ssl_enabled="$(get_object_value 'mail' 'DOMAIN' "$root_domain" '$SSL')"
	if [ "$ssl_enabled" = "yes" ]; then
		$BIN/v-update-mail-domain-ssl "$user" "$root_domain" "$ssl_dir" "updatessl"
	else
		$BIN/v-add-mail-domain-ssl "$user" "$root_domain" "$ssl_dir" "updatessl"
	fi
fi

if [ "$?" -ne '0' ]; then
	[ -d "$ssl_dir" ] && rm -rf "$ssl_dir"
	touch $HESTIA/data/queue/letsencrypt.pipe
	sed -i "/ $domain /d" $HESTIA/data/queue/letsencrypt.pipe
	send_notice 'LETSENCRYPT' "$domain certificate installation failed ($domain)"
	check_result $? "SSL install" > /dev/null
fi

# Adding LE autorenew cronjob
if [ -z "$(grep v-update-lets $HESTIA/data/users/admin/cron.conf)" ]; then
	min=$(generate_password '012345' '2')
	hour=$(generate_password '1234567' '1')
	cmd="sudo $BIN/v-update-letsencrypt-ssl"
	$BIN/v-add-cron-job admin "$min" "$hour" '*' '*' '*' "$cmd" > /dev/null
fi

# Updating letsencrypt key
if [ -z "$mail" ]; then
	if [ -z "$LETSENCRYPT" ]; then
		add_object_key "web" 'DOMAIN' "$domain" 'LETSENCRYPT' 'FTP_USER'
		add_object_key "web" 'DOMAIN' "$domain" 'LETSENCRYPT_FAIL_COUNT' 'LETSENCRYPT'
	fi
	update_object_value 'web' 'DOMAIN' "$domain" '$LETSENCRYPT' 'yes'
	update_object_value 'web' 'DOMAIN' "$domain" '$LETSENCRYPT_FAIL_COUNT' "0"

	if [[ "$domain_forcessl" == 'yes' ]]; then
		$BIN/v-add-web-domain-ssl-force $user $domain
	fi
	if [[ -n "$domain_redirect" ]]; then
		$BIN/v-add-web-domain-redirect $user $domain $domain_redirect $domain_redirect_code
	fi

else
	if [ -z "$LETSENCRYPT" ]; then
		add_object_key "mail" 'DOMAIN' "$root_domain" 'LETSENCRYPT'
		add_object_key "mail" 'DOMAIN' "$root_domain" 'LETSENCRYPT_FAIL_COUNT' 'LETSENCRYPT'
	fi
	update_object_value 'mail' 'DOMAIN' "$root_domain" '$LETSENCRYPT' 'yes'
	update_object_value 'mail' 'DOMAIN' "$root_domain" '$LETSENCRYPT_FAIL_COUNT' "0"
fi

# Remove challenge folder if exist vblats
# if [ -n "$well_known" ]; then
#	rm -fr $well_known
# fi

# Remove temporary SSL folder
[ -d "$ssl_dir" ] && rm -rf "$ssl_dir"

#----------------------------------------------------------#
#                        Hestia                            #
#----------------------------------------------------------#

# Deleting task from queue
touch $HESTIA/data/queue/letsencrypt.pipe
sed -i "/ $domain /d" $HESTIA/data/queue/letsencrypt.pipe

# Notifying user
send_notice 'LETSENCRYPT' "$domain SSL has been installed successfully"

# Logging
log_event "$OK" "$ARGUMENTS"

# Cleanup debug since the SSL was issues successfully
rm -f "$log_file"
service nginx restart
exit

Please pay attention: it's trick and no solution. There are no timeouts or retry limits. If your domain cannot be validated by some reason - you will get a loop.




Метки текста: hestiacp,letsencrypt 403,hestiacp SSL


https://minidevices.top/images/ava.png
https://minidevices.top/images/ava.png
2024-10-29 19:53:11
root
 29 октября 2024 в 19:53 
  7  

27
2024-10-29 19:53:11


Комментировать



Опубликовать запись
В этой строке мы предупреждаем Вас, что можем использовать так называемые cookies
Нам искренне плевать на введенную Вами информацию о себе. Мы просто запоминаем у Вас на устройстве то, что Вы же и настроили.