#!/usr/bin/env bash set -euo pipefail source ./lib.sh ACME_WEBROOT="/var/www/letsencrypt" install -d -m 0755 "${ACME_WEBROOT}/.well-known/acme-challenge" CERTBOT_EXTRA=() LE_STAGING="${LE_STAGING:-0}" # 1 = Let's Encrypt Staging aktivieren [[ "$LE_STAGING" = "1" ]] && CERTBOT_EXTRA+=(--test-cert) resolve_ok() { local host="$1" local pats=() [[ -n "${SERVER_PUBLIC_IPV4:-}" ]] && pats+=("${SERVER_PUBLIC_IPV4//./\\.}") [[ -n "${SERVER_PUBLIC_IPV6:-}" ]] && pats+=("${SERVER_PUBLIC_IPV6//:/\\:}") # Wenn gar nichts bekannt ist, lieber nicht blockieren: [[ ${#pats[@]} -eq 0 ]] && return 0 getent ahosts "$host" | awk '{print $1}' | sort -u \ | grep -Eq "^($(IFS='|'; echo "${pats[*]}"))$" } probe_http() { local host="$1" echo test > "${ACME_WEBROOT}/.well-known/acme-challenge/_probe" curl -fsS --max-time 5 -4 "http://${host}/.well-known/acme-challenge/_probe" >/dev/null \ || curl -fsS --max-time 5 -6 "http://${host}/.well-known/acme-challenge/_probe" >/dev/null } issue() { local host="$1" echo "[i] Versuche LE für ${host} …" resolve_ok "$host" || { echo "[!] DNS zeigt (noch) nicht hierher – skip ${host}"; return 0; } if ! probe_http "$host"; then echo "[!] ACME-HTTP-Check für ${host} fehlgeschlagen (Port 80/IPv6/Firewall/Nginx prüfen)." fi # MX: Key beibehalten (TLSA 3 1 1 bleibt stabil) EXTRA_ARGS=() [[ "$host" == "$MAIL_HOSTNAME" ]] && EXTRA_ARGS+=(--reuse-key) certbot certonly --agree-tos -m "${LE_EMAIL:-admin@${BASE_DOMAIN}}" \ --non-interactive --webroot -w "$ACME_WEBROOT" -d "$host" \ "${EXTRA_ARGS[@]}" "${CERTBOT_EXTRA[@]}" || true } if [[ "$BASE_DOMAIN" != "example.com" ]]; then issue "$UI_HOST" issue "$WEBMAIL_HOST" issue "$MAIL_HOSTNAME" run-parts /etc/letsencrypt/renewal-hooks/deploy || true systemctl reload nginx || true # # TLSA direkt einmal schreiben (Hook macht es bei Renewals sowieso) # MX_CERT="/etc/letsencrypt/live/${MAIL_HOSTNAME}/fullchain.pem" # if [[ -s "$MX_CERT" ]]; then # HASH="$(openssl x509 -in "$MX_CERT" -noout -pubkey \ # | openssl pkey -pubin -outform DER \ # | openssl dgst -sha256 | sed 's/^.*= //')" # TLSA_LINE="_25._tcp.${MAIL_HOSTNAME}. IN TLSA 3 1 1 ${HASH}" # install -d -m 0755 /etc/mailwolt/dns # echo "${TLSA_LINE}" > "/etc/mailwolt/dns/${MAIL_HOSTNAME}.tlsa.txt" # echo "[TLSA] ${TLSA_LINE}" # fi else echo "[i] BASE_DOMAIN=example.com – LE wird übersprungen." fi ##!/usr/bin/env bash #set -euo pipefail #source ./lib.sh # #ACME_WEBROOT="/var/www/letsencrypt" #install -d -m 0755 "${ACME_WEBROOT}/.well-known/acme-challenge" # ## Let's Encrypt: Staging optional (für Tests) #CERTBOT_EXTRA=() #LE_STAGING="${LE_STAGING:-0}" #[[ "$LE_STAGING" = "1" ]] && CERTBOT_EXTRA+=(--test-cert) # ## Einheitliche LE-E-Mail mit Fallback #LE_MAIL="${LE_EMAIL:-admin@${BASE_DOMAIN}}" # ## DNS zeigt auf diese Kiste? #resolve_ok() { # local host="$1" # local pats=() # [[ -n "${SERVER_PUBLIC_IPV4:-}" ]] && pats+=("${SERVER_PUBLIC_IPV4//./\\.}") # [[ -n "${SERVER_PUBLIC_IPV6:-}" ]] && pats+=("${SERVER_PUBLIC_IPV6//:/\\:}") # [[ ${#pats[@]} -eq 0 ]] && return 0 # getent ahosts "$host" | awk '{print $1}' | sort -u \ # | grep -Eq "^($(IFS='|'; echo "${pats[*]}"))$" #} # ## HTTP-01 erreichbar? #probe_http() { # local host="$1" # echo test > "${ACME_WEBROOT}/.well-known/acme-challenge/_probe" # curl -fsS --max-time 5 -4 "http://${host}/.well-known/acme-challenge/_probe" >/dev/null \ # || curl -fsS --max-time 5 -6 "http://${host}/.well-known/acme-challenge/_probe" >/dev/null #} # ## Ein Zertifikat ausstellen #issue() { # local host="$1" # [[ -z "$host" ]] && return 0 # # echo "[i] Versuche LE für ${host} …" # # if ! resolve_ok "$host"; then # echo "[!] DNS zeigt (noch) nicht hierher – überspringe: ${host}" # return 0 # fi # # if ! probe_http "$host"; then # echo "[!] ACME-HTTP-Check für ${host} fehlgeschlagen (Port 80/IPv6/Firewall/Nginx prüfen)." # fi # # EXTRA_ARGS=() # # MX: Key wiederverwenden → stabiler TLSA-Hash (3 1 1) # [[ "${host}" == "${MAIL_HOSTNAME}" ]] && EXTRA_ARGS+=(--reuse-key) # #certbot certonly \ # --agree-tos -m "${LE_MAIL}" --non-interactive \ # --webroot -w "${ACME_WEBROOT}" -d "${host}" \ # "${EXTRA_ARGS[@]}" "${CERTBOT_EXTRA[@]}" || true #} # ## ------------------- Hauptlauf ------------------- #if [[ "${BASE_DOMAIN}" != "example.com" ]]; then # issue "${UI_HOST:-}" # issue "${WEBMAIL_HOST:-}" # issue "${MAIL_HOSTNAME:-}" # # # Falls Deploy-Hook erst JETZT angelegt wurde: einmal manuell ausführen # if [[ -x /usr/local/sbin/mw-deploy.sh ]]; then # /usr/local/sbin/mw-deploy.sh || true # fi # # # Nginx nur neu laden, wenn aktiv # if systemctl is-active --quiet nginx; then # systemctl reload nginx || true # fi #else # echo "[i] BASE_DOMAIN=example.com – LE wird übersprungen." #fi ##!/usr/bin/env bash #set -euo pipefail #source ./lib.sh # #ACME_WEBROOT="/var/www/letsencrypt" #install -d -m 0755 "${ACME_WEBROOT}/.well-known/acme-challenge" # ## Let's Encrypt: Staging optional aktivieren (keine echten Zertifikate) #CERTBOT_EXTRA=() #LE_STAGING="${LE_STAGING:-0}" # 1 = Staging #[[ "$LE_STAGING" = "1" ]] && CERTBOT_EXTRA+=(--test-cert) # ## Einheitliche LE-E-Mail mit Fallback #LE_MAIL="${LE_EMAIL:-admin@${BASE_DOMAIN}}" # ## DNS-Auflösung gegen unsere bekannte(n) IP(s) prüfen (nur als Warnsignal) #resolve_ok() { # local host="$1" # local pats=() # [[ -n "${SERVER_PUBLIC_IPV4:-}" ]] && pats+=("${SERVER_PUBLIC_IPV4//./\\.}") # [[ -n "${SERVER_PUBLIC_IPV6:-}" ]] && pats+=("${SERVER_PUBLIC_IPV6//:/\\:}") # [[ ${#pats[@]} -eq 0 ]] && return 0 # getent ahosts "$host" | awk '{print $1}' | sort -u \ # | grep -Eq "^($(IFS='|'; echo "${pats[*]}"))$" #} # ## HTTP-01 Erreichbarkeit schnell antesten (IPv4/IPv6) #probe_http() { # local host="$1" # echo test > "${ACME_WEBROOT}/.well-known/acme-challenge/_probe" # curl -fsS --max-time 5 -4 "http://${host}/.well-known/acme-challenge/_probe" >/dev/null \ # || curl -fsS --max-time 5 -6 "http://${host}/.well-known/acme-challenge/_probe" >/dev/null #} # ## Ein Zertifikat für einen Host ausstellen #issue() { # local host="$1" # [[ -z "$host" ]] && return 0 # # echo "[i] Versuche LE für ${host} …" # # if ! resolve_ok "$host"; then # echo "[!] DNS zeigt (noch) nicht hierher – überspringe: ${host}" # return 0 # fi # # if ! probe_http "$host"; then # echo "[!] ACME-HTTP-Check für ${host} fehlgeschlagen (Port 80/IPv6/Firewall/Nginx prüfen)." # # wir versuchen es trotzdem – Certbot meldet sich, falls es scheitert # fi # # # Für MX den Key wiederverwenden (stabiler TLSA-Hash 3 1 1) # EXTRA_ARGS=() # [[ "${host}" == "${MAIL_HOSTNAME}" ]] && EXTRA_ARGS+=(--reuse-key) # # certbot certonly \ # --agree-tos -m "${LE_MAIL}" --non-interactive \ # --webroot -w "${ACME_WEBROOT}" -d "${host}" \ # --deploy-hook /usr/local/sbin/mw-deploy.sh \ # "${EXTRA_ARGS[@]}" "${CERTBOT_EXTRA[@]}" || true #} # ## ----------------------------------------------------------------------------- ## Hauptlauf ## ----------------------------------------------------------------------------- #if [[ "${BASE_DOMAIN}" != "example.com" ]]; then # issue "${UI_HOST:-}" # issue "${WEBMAIL_HOST:-}" # issue "${MAIL_HOSTNAME:-}" # # # Der Deploy-Hook hat Symlinks bereits gesetzt und nginx ggf. neu geladen. # # Optional trotzdem manuell ausführen (harmlos, hilft bei exotischen Setups): # if [[ -d /etc/letsencrypt/renewal-hooks/deploy ]]; then # run-parts /etc/letsencrypt/renewal-hooks/deploy || true # fi # if systemctl is-active --quiet nginx; then # systemctl reload nginx || true # fi #else # echo "[i] BASE_DOMAIN=example.com – LE-Ausstellung wird übersprungen." #fi #