#!/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" # Staging optional (verbraucht kein Live-Limit) CERTBOT_EXTRA=() LE_STAGING="${LE_STAGING:-0}" [[ "$LE_STAGING" = "1" ]] && CERTBOT_EXTRA+=(--test-cert) # Einheitliche LE-Mail (Fallback) LE_MAIL="${LE_EMAIL:-admin@${BASE_DOMAIN}}" 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[*]}"))$" } 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:-}" [[ -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 trotzdem – Certbot meldet sich, falls es scheitert fi EXTRA_ARGS=() # Für MX den Key wiederverwenden → stabiler TLSA (3 1 1) [[ "$host" == "${MAIL_HOSTNAME}" ]] && EXTRA_ARGS+=(--reuse-key) # WICHTIG: Deploy-Wrapper anhängen, damit Symlinks/Nginx gesetzt werden 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 } if [[ "${BASE_DOMAIN}" != "example.com" ]]; then issue "${UI_HOST:-}" issue "${WEBMAIL_HOST:-}" issue "${MAIL_HOSTNAME:-}" # Falls der Deploy-Wrapper gerade erst installiert wurde: # 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" # #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 #