From c83a7199cf0e3104174ce57e59fb1bd017b5ead8 Mon Sep 17 00:00:00 2001 From: Anthony Date: Sat, 9 Aug 2025 01:29:17 +0800 Subject: [PATCH] Fixed SSL Verification --- mbadmin.jps | 28 ++++++++++++++ scripts/fix-cert-trust.sh | 73 ++++++++++++++++++++++++++++++++++++ scripts/wp-search-replace.sh | 67 +++++++++++++++++++++++++++++++-- 3 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 scripts/fix-cert-trust.sh diff --git a/mbadmin.jps b/mbadmin.jps index 942521c..8de038d 100644 --- a/mbadmin.jps +++ b/mbadmin.jps @@ -29,6 +29,9 @@ onInstall: # Download WP search-replace wrapper script with verification - curl -OL https://deploy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/wp-search-replace.sh - if [ ! -f wp-search-replace.sh ]; then echo "Failed to download wp-search-replace.sh"; exit 1; fi + # Download CA trust repair script + - curl -OL https://deploy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/fix-cert-trust.sh + - if [ ! -f fix-cert-trust.sh ]; then echo "Failed to download fix-cert-trust.sh"; exit 1; fi # Download LiteSpeed scripts with verification - curl -OL https://deploy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/check_litespeed.php - if [ ! -f check_litespeed.php ]; then echo "Failed to download check_litespeed.php"; exit 1; fi @@ -248,6 +251,12 @@ menu: action: issue_ssl_cert settings: sslCertConfig successText: "SSL certificate for '${settings.domain}' has been issued successfully." + - confirmText: Rebuild fullchain and refresh system CA trust for this domain? + loadingText: Fixing certificate trust... + caption: Fix Certificate Trust + action: fix_cert_trust + settings: fixCertTrustConfig + successText: "Certificate trust repair completed for '${settings.domain}'." - confirmText: Check if the domain is resolving to the expected IP address? loadingText: Checking Domain... caption: Check Domain IP @@ -441,6 +450,17 @@ settings: type: text caption: Email Address (Optional) default: "${EMAIL}" + fixCertTrustConfig: + submitUnchanged: true + fields: + - name: domain + type: text + caption: Domain Name + required: true + - name: keys_dir + type: text + caption: Keys Directory + default: "/var/lib/jelastic/keys" redisObjectCacheConfig: submitUnchanged: true fields: @@ -905,6 +925,14 @@ actions: - return: type: info message: "SSL certificate removal process completed." + fix_cert_trust: + - cmd[cp]: + user: root + commands: + - bash /home/litespeed/mbmanager/scripts/fix-cert-trust.sh "${settings.domain}" "${settings.keys_dir}" + - return: + type: info + message: "${response.out}" diagnose_litespeed_config: - cmd[cp]: user: root diff --git a/scripts/fix-cert-trust.sh b/scripts/fix-cert-trust.sh new file mode 100644 index 0000000..6efa7a3 --- /dev/null +++ b/scripts/fix-cert-trust.sh @@ -0,0 +1,73 @@ +#!/bin/bash +set -euo pipefail + +# Fix/refresh system CA trust and reconstruct a proper fullchain for a given domain on AlmaLinux/RHEL/CentOS. +# Usage: fix-cert-trust.sh [keys_dir] +# - domain: FQDN of site (e.g., example.com) +# - keys_dir: directory containing cert/key files. Default: /var/lib/jelastic/keys + +DOMAIN="${1:-}" +KEYS_DIR="${2:-/var/lib/jelastic/keys}" + +if [[ -z "$DOMAIN" ]]; then + echo "Usage: $0 [keys_dir]" >&2 + exit 1 +fi + +echo "[INFO] Refreshing system CA trust (update-ca-trust)…" +if command -v update-ca-trust >/dev/null 2>&1; then + sudo update-ca-trust || true +else + echo "[WARNING] update-ca-trust not available; skipping." +fi + +echo "[INFO] Looking for certificate files in: $KEYS_DIR" +CERT_PEM="$KEYS_DIR/cert.pem" +CHAIN_PEM="$KEYS_DIR/fullchain.pem" +CA_CER="$KEYS_DIR/ca.cer" +DOMAIN_CRT="$KEYS_DIR/${DOMAIN}.cer" +OUT_FULLCHAIN="$KEYS_DIR/${DOMAIN}.fullchain.pem" + +if [[ ! -f "$CERT_PEM" && ! -f "$DOMAIN_CRT" ]]; then + echo "[ERROR] Could not find leaf certificate (cert.pem or ${DOMAIN}.cer) in $KEYS_DIR" >&2 + exit 2 +fi + +# Prefer domain-specific cert, fallback to cert.pem +LEAF_CERT="$DOMAIN_CRT" +[[ -f "$LEAF_CERT" ]] || LEAF_CERT="$CERT_PEM" + +# Determine chain source +CHAIN_SRC="" +if [[ -f "$CHAIN_PEM" ]]; then + CHAIN_SRC="$CHAIN_PEM" +elif [[ -f "$CA_CER" ]]; then + CHAIN_SRC="$CA_CER" +else + echo "[WARNING] No chain file found (fullchain.pem/ca.cer). Creating fullchain from leaf only." +fi + +echo "[INFO] Writing reconstructed fullchain to: $OUT_FULLCHAIN" +{ + cat "$LEAF_CERT" + [[ -n "$CHAIN_SRC" ]] && echo && cat "$CHAIN_SRC" +} > "$OUT_FULLCHAIN" + +chmod 0644 "$OUT_FULLCHAIN" +echo "[SUCCESS] Fullchain rebuilt at $OUT_FULLCHAIN" + +echo "[INFO] Detecting system CA bundle for PHP/cURL/WP-CLI" +for candidate in \ + /etc/pki/tls/certs/ca-bundle.crt \ + /etc/ssl/certs/ca-bundle.crt \ + /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem +do + if [[ -f "$candidate" ]]; then + echo "[SUCCESS] System CA bundle: $candidate" + exit 0 + fi +done + +echo "[WARNING] Could not locate system CA bundle automatically. Ensure ca-certificates are installed." +exit 0 + diff --git a/scripts/wp-search-replace.sh b/scripts/wp-search-replace.sh index e39deec..f904aec 100644 --- a/scripts/wp-search-replace.sh +++ b/scripts/wp-search-replace.sh @@ -121,6 +121,27 @@ fi if ! id "$WEB_USER" &>/dev/null; then error_exit "Web user '$WEB_USER' does not exist."; fi success "Prerequisites seem OK." +# Discover CA bundle path for HTTPS requests executed by PHP/cURL +CA_BUNDLE="" +for candidate in \ + /etc/pki/tls/certs/ca-bundle.crt \ + /etc/ssl/certs/ca-bundle.crt \ + /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem +do + if [[ -f "$candidate" ]]; then + CA_BUNDLE="$candidate" + break + fi +done + +if [[ -n "$CA_BUNDLE" ]]; then + info "Using CA bundle at: $CA_BUNDLE" + ENV_PREFIX=(env SSL_CERT_FILE="$CA_BUNDLE" CURL_CA_BUNDLE="$CA_BUNDLE") +else + warning "Could not locate a system CA bundle; HTTPS requests may fail." + ENV_PREFIX=() +fi + # --- WP-CLI Execution Context Setup --- # This logic is adapted from install-wordpress.sh to ensure commands run as the correct user. @@ -197,6 +218,10 @@ for pair in "${TASKS[@]}"; do # shellcheck disable=SC2206 CMD=($SUDO_CMD) fi + # Prepend environment variables to ensure cURL trusts system CA store + if [[ ${#ENV_PREFIX[@]} -gt 0 ]]; then + CMD+=("${ENV_PREFIX[@]}") + fi CMD+=("$WP_EXECUTABLE" "search-replace" "$OLD_PART" "$NEW_PART" "${WP_RUN_ARGS[@]}") SEARCH_OUTPUT=$( "${CMD[@]}" 2>&1 ) @@ -285,6 +310,7 @@ fi info "Attempting LiteSpeed Cache purge (wp litespeed-purge all)…" PURGE_URL_HTTPS="$TARGET_URL" PURGE_URL_HTTP="http://$HOST_ONLY" +FIX_TRUST_SCRIPT="/home/litespeed/mbmanager/scripts/fix-cert-trust.sh" # First attempt with HTTPS LS_CMD=() @@ -292,21 +318,50 @@ if [[ -n "$SUDO_CMD" ]]; then # shellcheck disable=SC2206 LS_CMD=($SUDO_CMD) fi +if [[ ${#ENV_PREFIX[@]} -gt 0 ]]; then + LS_CMD+=("${ENV_PREFIX[@]}") +fi LS_CMD+=("$WP_EXECUTABLE" "litespeed-purge" "all" "${WP_RUN_ARGS[@]}" "--url=$PURGE_URL_HTTPS") PURGE_OUTPUT=$( "${LS_CMD[@]}" 2>&1 ) || true printf "%s\n" "$PURGE_OUTPUT" -# If SSL verification fails, retry over HTTP +# If SSL verification fails, attempt trust repair, retry HTTPS, then fallback to HTTP if echo "$PURGE_OUTPUT" | grep -qiE "cURL error 60|SSL certificate problem"; then - warning "LiteSpeed purge failed due to SSL verification. Retrying over HTTP…" + warning "LiteSpeed purge failed due to SSL verification. Attempting to repair trust and retry over HTTPS…" + if [[ -x "$FIX_TRUST_SCRIPT" ]]; then + "$FIX_TRUST_SCRIPT" "$HOST_ONLY" "/var/lib/jelastic/keys" || warning "Trust repair script encountered an error." + else + warning "Trust repair script not found at $FIX_TRUST_SCRIPT; skipping repair." + fi + + # Retry HTTPS LS_CMD=() if [[ -n "$SUDO_CMD" ]]; then # shellcheck disable=SC2206 LS_CMD=($SUDO_CMD) fi - LS_CMD+=("$WP_EXECUTABLE" "litespeed-purge" "all" "${WP_RUN_ARGS[@]}" "--url=$PURGE_URL_HTTP") + if [[ ${#ENV_PREFIX[@]} -gt 0 ]]; then + LS_CMD+=("${ENV_PREFIX[@]}") + fi + LS_CMD+=("$WP_EXECUTABLE" "litespeed-purge" "all" "${WP_RUN_ARGS[@]}" "--url=$PURGE_URL_HTTPS") PURGE_OUTPUT=$( "${LS_CMD[@]}" 2>&1 ) || true printf "%s\n" "$PURGE_OUTPUT" + + # If HTTPS still fails due to SSL, fallback to HTTP + if echo "$PURGE_OUTPUT" | grep -qiE "cURL error 60|SSL certificate problem"; then + warning "HTTPS purge still failing. Retrying over HTTP…" + LS_CMD=() + if [[ -n "$SUDO_CMD" ]]; then + # shellcheck disable=SC2206 + LS_CMD=($SUDO_CMD) + fi + if [[ ${#ENV_PREFIX[@]} -gt 0 ]]; then + LS_CMD+=("${ENV_PREFIX[@]}") + fi + LS_CMD+=("$WP_EXECUTABLE" "litespeed-purge" "all" "${WP_RUN_ARGS[@]}" "--url=$PURGE_URL_HTTP") + PURGE_OUTPUT=$( "${LS_CMD[@]}" 2>&1 ) || true + printf "%s\n" "$PURGE_OUTPUT" + fi fi if echo "$PURGE_OUTPUT" | grep -qiE "Error|Warning"; then @@ -320,6 +375,9 @@ if [[ -n "$SUDO_CMD" ]]; then # shellcheck disable=SC2206 TRANS_CMD=($SUDO_CMD) fi +if [[ ${#ENV_PREFIX[@]} -gt 0 ]]; then + TRANS_CMD+=("${ENV_PREFIX[@]}") +fi TRANS_CMD+=("$WP_EXECUTABLE" "transient" "delete" "--all" "${WP_RUN_ARGS[@]}") "${TRANS_CMD[@]}" || warning "Transient delete command returned non-zero exit status." @@ -330,6 +388,9 @@ if [[ -n "$SUDO_CMD" ]]; then # shellcheck disable=SC2206 FLUSH_CMD=($SUDO_CMD) fi +if [[ ${#ENV_PREFIX[@]} -gt 0 ]]; then + FLUSH_CMD+=("${ENV_PREFIX[@]}") +fi FLUSH_CMD+=("$WP_EXECUTABLE" "cache" "flush" "${WP_RUN_ARGS[@]}") "${FLUSH_CMD[@]}" || warning "Cache flush command returned non-zero exit status."