Laudende Default seite entfernen
parent
3c6185e291
commit
ce31a51b18
|
|
@ -2,17 +2,18 @@
|
|||
set -euo pipefail
|
||||
source ./lib.sh
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# ────────────────────────────────────────────────────────────────────────────
|
||||
# 21-le-deploy-hook.sh
|
||||
# - Legt /etc/mailwolt/installer.env (falls fehlt) an
|
||||
# - Erzeugt LE-Deploy-Hooks:
|
||||
# * 50-mailwolt-symlinks.sh → verlinkt LE-Zerts nach /etc/ssl/{ui,webmail,mail}
|
||||
# * 60-mailwolt-tlsa.sh → schreibt TLSA (3 1 1) für MX nach jedem Renew
|
||||
# -----------------------------------------------------------------------------
|
||||
# • legt /etc/mailwolt/installer.env an (falls fehlt)
|
||||
# • erzeugt Deploy-Hooks:
|
||||
# - 50-mailwolt-symlinks.sh → verlinkt LE-Zerts nach /etc/ssl/{ui,webmail,mail}
|
||||
# - 60-mailwolt-tlsa.sh → aktualisiert TLSA (3 1 1) für MX bei jedem Renew
|
||||
# • KEIN Reload von Postfix/Dovecot (kommt später im Installer)
|
||||
# ────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# 1) Sicherstellen, dass die Hosts persistent verfügbar sind
|
||||
# 0) Hostnamen persistent speichern (für spätere Deploys)
|
||||
install -d -m 0755 /etc/mailwolt
|
||||
if [[ ! -f /etc/mailwolt/installer.env ]]; then
|
||||
install -d -m 0755 /etc/mailwolt
|
||||
cat >/etc/mailwolt/installer.env <<EOF
|
||||
UI_HOST=${UI_HOST}
|
||||
WEBMAIL_HOST=${WEBMAIL_HOST}
|
||||
|
|
@ -21,91 +22,113 @@ EOF
|
|||
echo "[+] /etc/mailwolt/installer.env erstellt."
|
||||
fi
|
||||
|
||||
# 2) Deploy-Hooks-Verzeichnis anlegen
|
||||
# 1) Deploy-Hooks-Verzeichnis anlegen
|
||||
install -d -m 0755 /etc/letsencrypt/renewal-hooks/deploy
|
||||
|
||||
# 3) Hook: LE-Zertifikate nach /etc/ssl/* verlinken und Nginx reloaden
|
||||
cat >/etc/letsencrypt/renewal-hooks/deploy/50-mailwolt-symlinks.sh <<'HOOK'
|
||||
# ────────────────────────────────────────────────────────────────────────────
|
||||
# 2) 50-mailwolt-symlinks.sh
|
||||
# ────────────────────────────────────────────────────────────────────────────
|
||||
cat >/etc/letsencrypt/renewal-hooks/deploy/50-mailwolt-symlinks.sh <<HOOK
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Env aus dem Installer laden (falls vorhanden), aber unbound vermeiden
|
||||
set +u
|
||||
[ -r /etc/mailwolt/installer.env ] && . /etc/mailwolt/installer.env
|
||||
set -u
|
||||
UI_LE="/etc/letsencrypt/live/${UI_HOST}"
|
||||
WEBMAIL_LE="/etc/letsencrypt/live/${WEBMAIL_HOST}"
|
||||
MX_LE="/etc/letsencrypt/live/${MAIL_HOSTNAME}"
|
||||
|
||||
UI_SSL_DIR="/etc/ssl/ui"
|
||||
WEBMAIL_SSL_DIR="/etc/ssl/webmail"
|
||||
MAIL_SSL_DIR="/etc/ssl/mail"
|
||||
|
||||
# Falls Variablen nicht gesetzt sind → leere Defaults (vermeidet unbound)
|
||||
UI_HOST="${UI_HOST:-}"
|
||||
WEBMAIL_HOST="${WEBMAIL_HOST:-}"
|
||||
MX_HOST="${MAIL_HOSTNAME:-}"
|
||||
|
||||
UI_LE="/etc/letsencrypt/live/${UI_HOST}"
|
||||
WEBMAIL_LE="/etc/letsencrypt/live/${WEBMAIL_HOST}"
|
||||
MX_LE="/etc/letsencrypt/live/${MX_HOST}"
|
||||
# Zielverzeichnisse anlegen (einmalig)
|
||||
install -d -m 0755 "\$UI_SSL_DIR" "\$WEBMAIL_SSL_DIR" "\$MAIL_SSL_DIR"
|
||||
|
||||
link_if() {
|
||||
local le_base="$1" target_dir="$2"
|
||||
local cert="${le_base}/fullchain.pem"
|
||||
local key="${le_base}/privkey.pem"
|
||||
if [[ -f "$cert" && -f "$key" ]]; then
|
||||
install -d -m 0755 "$target_dir"
|
||||
ln -sf "$cert" "${target_dir}/fullchain.pem"
|
||||
ln -sf "$key" "${target_dir}/privkey.pem"
|
||||
echo "[+] Linked ${target_dir} -> ${le_base}"
|
||||
fi
|
||||
local le_base="\$1" target_dir="\$2"
|
||||
local cert="\${le_base}/fullchain.pem"
|
||||
local key="\${le_base}/privkey.pem"
|
||||
[[ -s "\$cert" && -s "\$key" ]] || return 0
|
||||
ln -sf "\$cert" "\${target_dir}/fullchain.pem"
|
||||
ln -sf "\$key" "\${target_dir}/privkey.pem"
|
||||
chmod 644 "\${target_dir}/fullchain.pem" 2>/dev/null || true
|
||||
chmod 600 "\${target_dir}/privkey.pem" 2>/dev/null || true
|
||||
echo "[+] Linked \${target_dir} -> \${le_base}"
|
||||
}
|
||||
|
||||
# Nur linken, wenn Hostnamen vorhanden sind
|
||||
[[ -n "$UI_HOST" ]] && link_if "$UI_LE" "$UI_SSL_DIR"
|
||||
[[ -n "$WEBMAIL_HOST" ]] && link_if "$WEBMAIL_LE" "$WEBMAIL_SSL_DIR"
|
||||
[[ -n "$MX_HOST" ]] && link_if "$MX_LE" "$MAIL_SSL_DIR"
|
||||
# Verlinken (nur wenn Host konfiguriert)
|
||||
[[ -n "${UI_HOST}" ]] && link_if "\$UI_LE" "\$UI_SSL_DIR"
|
||||
[[ -n "${WEBMAIL_HOST}" ]] && link_if "\$WEBMAIL_LE" "\$WEBMAIL_SSL_DIR"
|
||||
[[ -n "${MAIL_HOSTNAME}" ]] && link_if "\$MX_LE" "\$MAIL_SSL_DIR"
|
||||
|
||||
# sinnvolle Rechte (Key nur für root lesbar, Chain world-readable)
|
||||
chmod 640 "${UI_SSL_DIR}/privkey.pem" 2>/dev/null || true
|
||||
chmod 640 "${WEBMAIL_SSL_DIR}/privkey.pem" 2>/dev/null || true
|
||||
chmod 640 "${MAIL_SSL_DIR}/privkey.pem" 2>/dev/null || true
|
||||
chmod 644 "${UI_SSL_DIR}/fullchain.pem" 2>/dev/null || true
|
||||
chmod 644 "${WEBMAIL_SSL_DIR}/fullchain.pem" 2>/dev/null || true
|
||||
chmod 644 "${MAIL_SSL_DIR}/fullchain.pem" 2>/dev/null || true
|
||||
|
||||
# Nur Nginx neu laden – Postfix/Dovecot startet später im Installer
|
||||
systemctl reload nginx || true
|
||||
# Nur reloaden, wenn Nginx aktiv ist (Installer startet ihn später erst)
|
||||
if systemctl is-active --quiet nginx; then
|
||||
systemctl reload nginx || true
|
||||
fi
|
||||
HOOK
|
||||
chmod +x /etc/letsencrypt/renewal-hooks/deploy/50-mailwolt-symlinks.sh
|
||||
|
||||
# 4) Hook: TLSA (3 1 1) für MX nach jedem Renew/Issue generieren
|
||||
# ────────────────────────────────────────────────────────────────────────────
|
||||
# 3) 60-mailwolt-tlsa.sh
|
||||
# → nutzt Laravel, falls vorhanden; sonst Fallback mit OpenSSL.
|
||||
# → schreibt nur, wenn sich der Hash geändert hat (idempotent)
|
||||
# ────────────────────────────────────────────────────────────────────────────
|
||||
cat >/etc/letsencrypt/renewal-hooks/deploy/60-mailwolt-tlsa.sh <<'HOOK'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# MAIL_HOSTNAME kommt von certbot via Environment nicht automatisch,
|
||||
# daher direkt aus installer.env lesen, falls gesetzt.
|
||||
# installer.env lesen
|
||||
set +u
|
||||
[ -r /etc/mailwolt/installer.env ] && . /etc/mailwolt/installer.env
|
||||
set -u
|
||||
|
||||
APP_ENV_VAL="${APP_ENV:-production}"
|
||||
BASE_DOMAIN_VAL="${BASE_DOMAIN:-example.com}"
|
||||
|
||||
case "$APP_ENV_VAL" in
|
||||
local|dev|development) exit 0 ;;
|
||||
esac
|
||||
[ "$BASE_DOMAIN_VAL" = "example.com" ] && exit 0
|
||||
|
||||
MX_HOST="${MAIL_HOSTNAME:-}"
|
||||
SERVICE="_25._tcp"
|
||||
DNS_DIR="/etc/mailwolt/dns"
|
||||
OUT_FILE="${DNS_DIR}/${MX_HOST}.tlsa.txt"
|
||||
|
||||
[[ -n "$MX_HOST" ]] || exit 0
|
||||
|
||||
# Nur reagieren, wenn das MX-Zert in diesem Run drin war
|
||||
# Nur reagieren, wenn MX-Zertifikat betroffen war
|
||||
case " ${RENEWED_DOMAINS:-} " in
|
||||
*" ${MX_HOST} "*) ;; # ok
|
||||
*" ${MX_HOST} "*) ;;
|
||||
*) exit 0 ;;
|
||||
esac
|
||||
|
||||
CERT="${RENEWED_LINEAGE}/fullchain.pem"
|
||||
if [[ -s "$CERT" ]]; then
|
||||
HASH="$(openssl x509 -in "$CERT" -noout -pubkey \
|
||||
| openssl pkey -pubin -outform DER \
|
||||
| openssl dgst -sha256 | sed 's/^.*= //')"
|
||||
TLSA_LINE="_25._tcp.${MX_HOST}. IN TLSA 3 1 1 ${HASH}"
|
||||
install -d -m 0755 /etc/mailwolt/dns
|
||||
echo "${TLSA_LINE}" > "/etc/mailwolt/dns/${MX_HOST}.tlsa.txt"
|
||||
echo "[TLSA] ${TLSA_LINE}"
|
||||
[ -s "$CERT" ] || exit 0
|
||||
|
||||
# Wenn Laravel vorhanden ist → interner Command (DB + Datei idempotent)
|
||||
if command -v php >/dev/null 2>&1 && [ -d /var/www/mailwolt ]; then
|
||||
cd /var/www/mailwolt || exit 0
|
||||
php artisan dns:tlsa:refresh || true
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Fallback: nur Datei aktualisieren, wenn Hash sich ändert
|
||||
HASH="$(openssl x509 -in "$CERT" -noout -pubkey \
|
||||
| openssl pkey -pubin -outform DER \
|
||||
| openssl dgst -sha256 | sed 's/^.*= //')"
|
||||
NEW_LINE="${SERVICE}.${MX_HOST}. IN TLSA 3 1 1 ${HASH}"
|
||||
|
||||
mkdir -p "$DNS_DIR"
|
||||
|
||||
if [ -r "$OUT_FILE" ] && grep -q "IN TLSA" "$OUT_FILE"; then
|
||||
if grep -q "$HASH" "$OUT_FILE"; then
|
||||
echo "[TLSA] Unverändert – kein Update nötig."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$NEW_LINE" > "$OUT_FILE"
|
||||
echo "[TLSA] Aktualisiert: $NEW_LINE"
|
||||
HOOK
|
||||
chmod +x /etc/letsencrypt/renewal-hooks/deploy/60-mailwolt-tlsa.sh
|
||||
chmod +x /etc/letsencrypt/renewal-hooks/deploy/60-mailwolt-tlsa.sh
|
||||
|
||||
# ────────────────────────────────────────────────────────────────────────────
|
||||
echo "[✓] Deploy-Hooks installiert."
|
||||
|
|
@ -50,7 +50,8 @@ if [[ "$BASE_DOMAIN" != "example.com" ]]; then
|
|||
issue "$WEBMAIL_HOST"
|
||||
issue "$MAIL_HOSTNAME"
|
||||
|
||||
systemctl reload nginx || true
|
||||
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"
|
||||
|
|
|
|||
|
|
@ -3,12 +3,31 @@ set -euo pipefail
|
|||
source ./lib.sh
|
||||
|
||||
log "MOTD installieren …"
|
||||
|
||||
install -d /usr/local/bin
|
||||
|
||||
cat >/usr/local/bin/mw-motd <<'SH'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
NC="\033[0m"; CY="\033[1;36m"; GR="\033[1;32m"; YE="\033[1;33m"; RD="\033[1;31m"; GY="\033[0;90m"
|
||||
printf "\033[1;36m"
|
||||
|
||||
# Farben
|
||||
NC="\033[0m"; CY="\033[1;36m"; GR="\033[1;32m"; YE="\033[1;33m"; RD="\033[1;31m"; GY="\033[0;90m"; WH="\033[1;37m"
|
||||
|
||||
# Installer-Variablen (optional)
|
||||
UI_HOST=""; WEBMAIL_HOST=""; MAIL_HOSTNAME=""; LE_EMAIL=""; PROXY_MODE=""; NPM_IP=""
|
||||
if [ -r /etc/mailwolt/installer.env ]; then
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/mailwolt/installer.env || true
|
||||
fi
|
||||
# Aus .env (falls vorhanden)
|
||||
if [ -r /var/www/mailwolt/.env ]; then
|
||||
LE_EMAIL="${LE_EMAIL:-$(grep -E '^LE_EMAIL=' /var/www/mailwolt/.env 2>/dev/null | sed 's/^LE_EMAIL=//')}"
|
||||
PROXY_MODE="${PROXY_MODE:-$(grep -E '^PROXY_MODE=' /var/www/mailwolt/.env 2>/dev/null | sed 's/^PROXY_MODE=//')}"
|
||||
NPM_IP="${NPM_IP:-$(grep -E '^NPM_IP=' /var/www/mailwolt/.env 2>/dev/null | sed 's/^NPM_IP=//')}"
|
||||
fi
|
||||
|
||||
# ASCII-Header
|
||||
printf "${CY}"
|
||||
cat <<'ASCII'
|
||||
:::: :::: ::: ::::::::::: ::: ::: ::: :::::::: ::: :::::::::::
|
||||
+:+:+: :+:+:+ :+: :+: :+: :+: :+: :+: :+: :+: :+: :+:
|
||||
|
|
@ -18,25 +37,101 @@ cat <<'ASCII'
|
|||
#+# #+# #+# #+# #+# #+# #+#+# #+#+# #+# #+# #+# #+#
|
||||
### ### ### ### ########### ########## ### ### ######## ########## ###
|
||||
ASCII
|
||||
printf "\033[0m\n"
|
||||
printf "${NC}\n"
|
||||
|
||||
# Systemdaten
|
||||
now="$(date '+%Y-%m-%d %H:%M:%S %Z')"
|
||||
fqdn="$(hostname -f 2>/dev/null || hostname)"
|
||||
ip_int="$(hostname -I 2>/dev/null | awk '{print $1}')"
|
||||
ip_ext=""; command -v curl >/dev/null 2>&1 && ip_ext="$(curl -s --max-time 1 https://ifconfig.me || true)"
|
||||
ip_ext=""; command -v curl >/dev/null 2>&1 && ip_ext="$(curl -fsS --max-time 1 https://ifconfig.me 2>/dev/null || true)"
|
||||
upt="$(uptime -p 2>/dev/null || true)"
|
||||
cores="$(nproc 2>/dev/null || echo -n '?')"
|
||||
load="$(awk '{print $1" / "$2" / "$3}' /proc/loadavg 2>/dev/null)"
|
||||
svc(){ systemctl is-active --quiet "$1" && echo -e "${GR}OK${NC}" || echo -e "${RD}FAIL${NC}"; }
|
||||
|
||||
# RAM/SWAP (MiB)
|
||||
mem_total="$(awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo 2>/dev/null)"
|
||||
mem_avail="$(awk '/MemAvailable/ {print int($2/1024)}' /proc/meminfo 2>/dev/null)"
|
||||
mem_used=$(( (mem_total-mem_avail) ))
|
||||
swap_total="$(awk '/SwapTotal/ {print int($2/1024)}' /proc/meminfo 2>/dev/null)"
|
||||
swap_free="$(awk '/SwapFree/ {print int($2/1024)}' /proc/meminfo 2>/dev/null)"
|
||||
swap_used=$(( (swap_total-swap_free) ))
|
||||
|
||||
# Disks (/, /var)
|
||||
disk_line(){
|
||||
local mnt="$1"
|
||||
df -hP "$mnt" 2>/dev/null | awk 'NR==2{printf "%s/%s (%s used)", $3,$2,$5}'
|
||||
}
|
||||
disk_root="$(disk_line /)"
|
||||
disk_var="$(disk_line /var)"
|
||||
|
||||
svc_state(){
|
||||
local unit="$1"
|
||||
if systemctl is-active --quiet "$unit"; then
|
||||
printf "${GR}OK${NC}"
|
||||
else
|
||||
printf "${RD}FAIL${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Zeilen
|
||||
printf "${CY}Information as of:${NC} ${YE}%s${NC}\n" "$now"
|
||||
printf "${GY}FQDN :${NC} %s\n" "$fqdn"
|
||||
if [ -n "$ip_ext" ]; then printf "${GY}IP :${NC} %s ${GY}(ext:${NC} %s${GY})${NC}\n" "${ip_int:-?}" "$ip_ext"; else printf "${GY}IP :${NC} %s\n" "${ip_int:-?}"; fi
|
||||
if [ -n "$ip_ext" ]; then
|
||||
printf "${GY}IP :${NC} %s ${GY}(ext:${NC} %s${GY})${NC}\n" "${ip_int:-?}" "$ip_ext"
|
||||
else
|
||||
printf "${GY}IP :${NC} %s\n" "${ip_int:-?}"
|
||||
fi
|
||||
printf "${GY}Uptime :${NC} %s\n" "${upt:-?}"
|
||||
printf "${GY}Cores :${NC} %s\n" "$cores"
|
||||
printf "${GY}Load :${NC} %s (1/5/15)\n" "${load:-?}"
|
||||
printf "${GY}Svc :${NC} postfix: $(svc postfix) dovecot: $(svc dovecot) nginx: $(svc nginx) mariadb: $(svc mariadb) redis: $(svc redis)\n"
|
||||
printf "${GY}CPU :${NC} %s cores, load %s (1/5/15)\n" "$cores" "${load:-?}"
|
||||
printf "${GY}RAM :${NC} %s MiB used / %s MiB total\n" "${mem_used:-?}" "${mem_total:-?}"
|
||||
printf "${GY}SWAP :${NC} %s MiB used / %s MiB total\n" "${swap_used:-?}" "${swap_total:-?}"
|
||||
printf "${GY}Disk / :${NC} %s\n" "${disk_root:-?}"
|
||||
printf "${GY}Disk/var:${NC} %s\n" "${disk_var:-?}"
|
||||
|
||||
# App/Installer Infos
|
||||
[ -n "$LE_EMAIL" ] && printf "${GY}LE E-Mail:${NC} %s\n" "$LE_EMAIL"
|
||||
[ -n "$UI_HOST" ] && printf "${GY}UI Host :${NC} %s\n" "$UI_HOST"
|
||||
[ -n "$WEBMAIL_HOST" ] && printf "${GY}Webmail :${NC} %s\n" "$WEBMAIL_HOST"
|
||||
[ -n "$MAIL_HOSTNAME" ]&& printf "${GY}MX Host :${NC} %s\n" "$MAIL_HOSTNAME"
|
||||
if [ -n "${PROXY_MODE:-}" ]; then
|
||||
if [ "$PROXY_MODE" = "1" ]; then
|
||||
printf "${GY}Proxy :${NC} ja (NPM: %s)\n" "${NPM_IP:-unbekannt}"
|
||||
else
|
||||
printf "${GY}Proxy :${NC} nein\n"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Services
|
||||
printf "${WH}\nServices:${NC}\n"
|
||||
printf " nginx … %b\n" "$(svc_state nginx)"
|
||||
printf " mariadb … %b\n" "$(svc_state mariadb)"
|
||||
printf " redis-server … %b\n" "$(svc_state redis-server)"
|
||||
printf " postfix … %b\n" "$(svc_state postfix)"
|
||||
printf " dovecot … %b\n" "$(svc_state dovecot)"
|
||||
# App Units (optional)
|
||||
printf " mailwolt-ws … %b\n" "$(svc_state mailwolt-ws)"
|
||||
printf " mailwolt-queue… %b\n" "$(svc_state mailwolt-queue)"
|
||||
printf " mailwolt-schedule … %b\n" "$(svc_state mailwolt-schedule)"
|
||||
|
||||
# Zertifikate (kurzer Hinweis, optional)
|
||||
show_cert_hint(){
|
||||
local name="$1" path="$2"
|
||||
if [ -r "$path" ]; then
|
||||
local exp
|
||||
exp="$(openssl x509 -in "$path" -noout -enddate 2>/dev/null | sed 's/notAfter=//')"
|
||||
[ -n "$exp" ] && printf "${GY}%s cert:${NC} expires %s\n" "$name" "$exp"
|
||||
fi
|
||||
}
|
||||
show_cert_hint "UI" "/etc/ssl/ui/fullchain.pem"
|
||||
show_cert_hint "Webmail" "/etc/ssl/webmail/fullchain.pem"
|
||||
show_cert_hint "MX" "/etc/ssl/mail/fullchain.pem"
|
||||
|
||||
echo
|
||||
SH
|
||||
|
||||
chmod +x /usr/local/bin/mw-motd
|
||||
|
||||
# update-motd integration
|
||||
if [[ -d /etc/update-motd.d ]]; then
|
||||
cat >/etc/update-motd.d/10-mailwolt <<'SH'
|
||||
#!/usr/bin/env bash
|
||||
|
|
@ -45,8 +140,64 @@ SH
|
|||
chmod +x /etc/update-motd.d/10-mailwolt
|
||||
[[ -f /etc/update-motd.d/50-motd-news ]] && chmod -x /etc/update-motd.d/50-motd-news || true
|
||||
else
|
||||
# Fallback für Systeme ohne dynamic MOTD
|
||||
cat >/etc/profile.d/10-mailwolt-motd.sh <<'SH'
|
||||
case "$-" in *i*) /usr/local/bin/mw-motd ;; esac
|
||||
SH
|
||||
fi
|
||||
: > /etc/motd 2>/dev/null || true
|
||||
|
||||
# altes /etc/motd leeren (sonst doppelt)
|
||||
: > /etc/motd 2>/dev/null || true
|
||||
|
||||
##!/usr/bin/env bash
|
||||
#set -euo pipefail
|
||||
#source ./lib.sh
|
||||
#
|
||||
#log "MOTD installieren …"
|
||||
#install -d /usr/local/bin
|
||||
#cat >/usr/local/bin/mw-motd <<'SH'
|
||||
##!/usr/bin/env bash
|
||||
#set -euo pipefail
|
||||
#NC="\033[0m"; CY="\033[1;36m"; GR="\033[1;32m"; YE="\033[1;33m"; RD="\033[1;31m"; GY="\033[0;90m"
|
||||
#printf "\033[1;36m"
|
||||
#cat <<'ASCII'
|
||||
#:::: :::: ::: ::::::::::: ::: ::: ::: :::::::: ::: :::::::::::
|
||||
#+:+:+: :+:+:+ :+: :+: :+: :+: :+: :+: :+: :+: :+: :+:
|
||||
#+:+ +:+:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+
|
||||
#+#+ +:+ +#+ +#++:++#++: +#+ +#+ +#+ +:+ +#+ +#+ +:+ +#+ +#+
|
||||
#+#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+#+ +#+ +#+ +#+ +#+ +#+
|
||||
##+# #+# #+# #+# #+# #+# #+#+# #+#+# #+# #+# #+# #+#
|
||||
#### ### ### ### ########### ########## ### ### ######## ########## ###
|
||||
#ASCII
|
||||
#printf "\033[0m\n"
|
||||
#now="$(date '+%Y-%m-%d %H:%M:%S %Z')"
|
||||
#fqdn="$(hostname -f 2>/dev/null || hostname)"
|
||||
#ip_int="$(hostname -I 2>/dev/null | awk '{print $1}')"
|
||||
#ip_ext=""; command -v curl >/dev/null 2>&1 && ip_ext="$(curl -s --max-time 1 https://ifconfig.me || true)"
|
||||
#upt="$(uptime -p 2>/dev/null || true)"
|
||||
#cores="$(nproc 2>/dev/null || echo -n '?')"
|
||||
#load="$(awk '{print $1" / "$2" / "$3}' /proc/loadavg 2>/dev/null)"
|
||||
#svc(){ systemctl is-active --quiet "$1" && echo -e "${GR}OK${NC}" || echo -e "${RD}FAIL${NC}"; }
|
||||
#printf "${CY}Information as of:${NC} ${YE}%s${NC}\n" "$now"
|
||||
#printf "${GY}FQDN :${NC} %s\n" "$fqdn"
|
||||
#if [ -n "$ip_ext" ]; then printf "${GY}IP :${NC} %s ${GY}(ext:${NC} %s${GY})${NC}\n" "${ip_int:-?}" "$ip_ext"; else printf "${GY}IP :${NC} %s\n" "${ip_int:-?}"; fi
|
||||
#printf "${GY}Uptime :${NC} %s\n" "${upt:-?}"
|
||||
#printf "${GY}Cores :${NC} %s\n" "$cores"
|
||||
#printf "${GY}Load :${NC} %s (1/5/15)\n" "${load:-?}"
|
||||
#printf "${GY}Svc :${NC} postfix: $(svc postfix) dovecot: $(svc dovecot) nginx: $(svc nginx) mariadb: $(svc mariadb) redis: $(svc redis)\n"
|
||||
#SH
|
||||
#chmod +x /usr/local/bin/mw-motd
|
||||
#
|
||||
#if [[ -d /etc/update-motd.d ]]; then
|
||||
# cat >/etc/update-motd.d/10-mailwolt <<'SH'
|
||||
##!/usr/bin/env bash
|
||||
#/usr/local/bin/mw-motd
|
||||
#SH
|
||||
# chmod +x /etc/update-motd.d/10-mailwolt
|
||||
# [[ -f /etc/update-motd.d/50-motd-news ]] && chmod -x /etc/update-motd.d/50-motd-news || true
|
||||
#else
|
||||
# cat >/etc/profile.d/10-mailwolt-motd.sh <<'SH'
|
||||
#case "$-" in *i*) /usr/local/bin/mw-motd ;; esac
|
||||
#SH
|
||||
#fi
|
||||
#: > /etc/motd 2>/dev/null || true
|
||||
|
|
@ -2,82 +2,181 @@
|
|||
set -euo pipefail
|
||||
source ./lib.sh
|
||||
|
||||
log() { printf "\033[1;32m[+]\033[0m %s\n" "$*"; }
|
||||
ok() { printf " [\033[1;32mOK\033[0m]\n"; }
|
||||
fail() { printf " [\033[1;31mFAIL\033[0m]\n"; }
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# Schöner Abschluss-Summary mit Farben, Diensten & Smoke-Test
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
|
||||
# Farben & Symbole
|
||||
BOLD="\033[1m"; DIM="\033[2m"; NC="\033[0m"
|
||||
GREEN="\033[1;32m"; RED="\033[1;31m"; YELLOW="\033[1;33m"; CYAN="\033[1;36m"; GREY="\033[0;90m"
|
||||
OKS="${GREEN}OK${NC}"; FAILS="${RED}FAIL${NC}"; WARN="${YELLOW}!${NC}"
|
||||
PLUS="${GREEN}[+]${NC}"
|
||||
|
||||
bar(){ printf "${CYAN}%s${NC}\n" "──────────────────────────────────────────────────────────────────────────────"; }
|
||||
log(){ printf "${GREEN}[+]${NC} %s\n" "$*"; }
|
||||
ok() { printf " [${OKS}]\n"; }
|
||||
fail(){ printf " [${FAILS}]\n"; }
|
||||
|
||||
# Evtl. persistente Variablen laden (falls vom Installer geschrieben)
|
||||
set +u
|
||||
[ -r /etc/mailwolt/installer.env ] && . /etc/mailwolt/installer.env
|
||||
set -u
|
||||
|
||||
# Defaults / Umgebung
|
||||
APP_USER="${APP_USER:-mailwolt}"
|
||||
APP_GROUP="${APP_GROUP:-www-data}"
|
||||
APP_DIR="${APP_DIR:-/var/www/${APP_USER}}"
|
||||
|
||||
BASE_DOMAIN="${BASE_DOMAIN:-example.com}"
|
||||
UI_HOST="${UI_HOST:-}"
|
||||
WEBMAIL_HOST="${WEBMAIL_HOST:-}"
|
||||
MAIL_HOSTNAME="${MAIL_HOSTNAME:-}"
|
||||
|
||||
APP_ENV="${APP_ENV:-production}"
|
||||
PROXY_MODE="${PROXY_MODE:-0}"
|
||||
NPM_IP="${NPM_IP:-}"
|
||||
|
||||
LE_EMAIL="${LE_EMAIL:-admin@${BASE_DOMAIN}}"
|
||||
ACME_WEBROOT="/var/www/letsencrypt"
|
||||
|
||||
# Zert-Pfade (werden idR via Hook symlinked)
|
||||
UI_CERT="/etc/ssl/ui/fullchain.pem"
|
||||
UI_KEY="/etc/ssl/ui/privkey.pem"
|
||||
SCHEME="http"
|
||||
WEBMAIL_CERT="/etc/ssl/webmail/fullchain.pem"
|
||||
MAIL_CERT="/etc/ssl/mail/fullchain.pem"
|
||||
|
||||
SERVER_PUBLIC_IPV4="$(detect_ip)"
|
||||
# IPs
|
||||
SERVER_PUBLIC_IPV4="${SERVER_PUBLIC_IPV4:-$(detect_ip)}"
|
||||
SERVER_PUBLIC_IPV6="${SERVER_PUBLIC_IPV6:-$(detect_ipv6)}"
|
||||
|
||||
# Scheme/URLs ableiten
|
||||
SCHEME="http"
|
||||
[[ -s "$UI_CERT" && -s "$UI_KEY" ]] && SCHEME="https"
|
||||
|
||||
UI_HOST="${UI_HOST:-}"
|
||||
APP_URL="${APP_URL:-${SCHEME}://${SERVER_PUBLIC_IPV4}}"
|
||||
if [[ -n "$UI_HOST" ]]; then
|
||||
APP_URL="${SCHEME}://${UI_HOST}"
|
||||
fi
|
||||
APP_URL="${SCHEME}://${UI_HOST:-$SERVER_PUBLIC_IPV4}"
|
||||
WEBMAIL_URL="${SCHEME}://${WEBMAIL_HOST:-$SERVER_PUBLIC_IPV4}"
|
||||
|
||||
MAIL_HOSTNAME="${MAIL_HOSTNAME:-${SERVER_PUBLIC_IPV4}}"
|
||||
# Erkennen, ob die Zert-Symlinks auf LE zeigen (nur kosmetisch)
|
||||
real_target() { readlink -f -- "$1" 2>/dev/null || true; }
|
||||
UI_CERT_TARGET="$(real_target "$UI_CERT")"
|
||||
WEBMAIL_CERT_TARGET="$(real_target "$WEBMAIL_CERT")"
|
||||
MAIL_CERT_TARGET="$(real_target "$MAIL_CERT")"
|
||||
|
||||
is_le(){ [[ "$1" == /etc/letsencrypt/live/*/fullchain.pem ]]; }
|
||||
UI_LE=$([[ -n "$UI_CERT_TARGET" ]] && is_le "$UI_CERT_TARGET" && echo "LE" || echo "self-signed/none")
|
||||
WEBMAIL_LE=$([[ -n "$WEBMAIL_CERT_TARGET" ]] && is_le "$WEBMAIL_CERT_TARGET" && echo "LE" || echo "self-signed/none")
|
||||
MAIL_LE=$([[ -n "$MAIL_CERT_TARGET" ]] && is_le "$MAIL_CERT_TARGET" && echo "LE" || echo "self-signed/none")
|
||||
|
||||
echo
|
||||
echo "──────────────────────────────────────────────────────────────────────────────"
|
||||
echo "✔ MailWolt Bootstrap fertig"
|
||||
echo "──────────────────────────────────────────────────────────────────────────────"
|
||||
printf " Aufruf UI: %s\n" "${APP_URL}"
|
||||
printf " App Root: %s\n" "${APP_DIR}"
|
||||
printf " Nginx Site: %s\n" "/etc/nginx/sites-available/${APP_USER}.conf"
|
||||
printf " Mail-FQDN: %s\n" "${MAIL_HOSTNAME}"
|
||||
bar
|
||||
printf " %s %s\n" "✔ MailWolt Bootstrap fertig" ""
|
||||
bar
|
||||
|
||||
# Kopf-Infos
|
||||
printf " %-14s %s\n" "Aufruf UI:" "${APP_URL}"
|
||||
printf " %-14s %s\n" "Webmail:" "${WEBMAIL_URL}"
|
||||
printf " %-14s %s\n" "App Root:" "${APP_DIR}"
|
||||
printf " %-14s %s\n" "Mail-FQDN:" "${MAIL_HOSTNAME:-$SERVER_PUBLIC_IPV4}"
|
||||
printf " %-14s %s\n" "BASE_DOMAIN:" "${BASE_DOMAIN}"
|
||||
printf " %-14s %s\n" "LE-Email:" "${LE_EMAIL}"
|
||||
printf " %-14s %s\n" "APP_ENV:" "${APP_ENV}"
|
||||
[[ -v PROXY_MODE ]] && printf " %-14s %s\n" "Proxy-Mode:" "$([[ "$PROXY_MODE" = "1" ]] && echo "ja (NPM: ${NPM_IP:-unbekannt})" || echo "nein")"printf " %-14s %s\n" "Server IPv4:" "${SERVER_PUBLIC_IPV4}"
|
||||
printf " %-14s %s\n" "Server IPv6:" "${SERVER_PUBLIC_IPV6:-–}"
|
||||
printf " %-14s %s\n" "ACME Webroot:" "${ACME_WEBROOT}"
|
||||
|
||||
echo
|
||||
printf " %-14s UI=%s, Webmail=%s, MX=%s\n" "Zertifikate:" "$UI_LE" "$WEBMAIL_LE" "$MAIL_LE"
|
||||
echo
|
||||
|
||||
echo " Anmeldung: Keine vordefinierten Admin-Daten."
|
||||
echo " Bitte zuerst registrieren (Erst-User wird Admin, danach"
|
||||
echo " wird die Registrierung automatisch gesperrt)."
|
||||
echo
|
||||
|
||||
# -------- Services ----------
|
||||
printf "Services:\n"
|
||||
# Dienste-Status
|
||||
bar
|
||||
echo " Services"
|
||||
bar
|
||||
|
||||
OK_LIST=()
|
||||
FAIL_LIST=()
|
||||
|
||||
svc(){
|
||||
local name="$1"
|
||||
printf " • %-10s … " "$name"
|
||||
if systemctl is-active --quiet "$name"; then ok; else fail; fi
|
||||
local unit="$1" label="${2:-$1}"
|
||||
printf " • %-18s … " "$label"
|
||||
if systemctl is-active --quiet "$unit"; then
|
||||
ok
|
||||
OK_LIST+=("$label")
|
||||
else
|
||||
fail
|
||||
FAIL_LIST+=("$label")
|
||||
fi
|
||||
}
|
||||
|
||||
# Kern-Services
|
||||
svc nginx
|
||||
svc mariadb
|
||||
svc redis-server
|
||||
svc postfix
|
||||
svc dovecot
|
||||
svc "${APP_USER}-ws" || true
|
||||
svc "${APP_USER}-schedule" || true
|
||||
svc "${APP_USER}-queue" || true
|
||||
# App-Worker (tolerant)
|
||||
svc "${APP_USER}-ws" "mailwolt-ws" || true
|
||||
svc "${APP_USER}-schedule" "mailwolt-schedule" || true
|
||||
svc "${APP_USER}-queue" "mailwolt-queue" || true
|
||||
|
||||
# Kurze Zusammenfassung
|
||||
echo
|
||||
if ((${#OK_LIST[@]})); then
|
||||
printf " ${GREEN}OK:${NC} %s\n" "$(IFS=', '; echo "${OK_LIST[*]}")"
|
||||
fi
|
||||
if ((${#FAIL_LIST[@]})); then
|
||||
printf " ${RED}FAIL:${NC} %s\n" "$(IFS=', '; echo "${FAIL_LIST[*]}")"
|
||||
echo " ${YELLOW}Hinweis:${NC} Details mit: journalctl -u <dienst> -b --no-pager"
|
||||
fi
|
||||
echo
|
||||
|
||||
# -------- Ports / Smoke Test ----------
|
||||
echo "──────────────────────────────────────────────────────────────────────────────"
|
||||
# Smoke-Test
|
||||
bar
|
||||
echo " Smoke-Test (SMTP/IMAP/POP3 mit/ohne TLS)"
|
||||
echo "──────────────────────────────────────────────────────────────────────────────"
|
||||
bar
|
||||
|
||||
check_port(){
|
||||
local label="$1" cmd="$2"
|
||||
printf "[%-3s] %-35s … " "$label" "$3"
|
||||
local tag="$1" cmd="$2" desc="$3"
|
||||
printf " [%-3s] %-35s … " "$tag" "$desc"
|
||||
if timeout 8s bash -lc "$cmd" >/dev/null 2>&1; then ok; else fail; fi
|
||||
}
|
||||
|
||||
# ein kurzes Delay, damit frisch gestartete Dienste lauschen
|
||||
sleep 6 || true
|
||||
|
||||
# SMTP family
|
||||
check_port "25" 'printf "QUIT\r\n" | nc -w 3 127.0.0.1 25' "SMTP (EHLO)"
|
||||
check_port "465" 'printf "QUIT\r\n" | openssl s_client -connect 127.0.0.1:465 -quiet -ign_eof' "SMTPS (TLS + EHLO)"
|
||||
check_port "587" 'printf "EHLO x\r\nSTARTTLS\r\nQUIT\r\n" | openssl s_client -starttls smtp -connect 127.0.0.1:587 -quiet -ign_eof' "Submission (STARTTLS)"
|
||||
# SMTP
|
||||
check_port "25" 'printf "EHLO x\r\nQUIT\r\n" | nc -w 3 127.0.0.1 25' \
|
||||
"SMTP (EHLO)"
|
||||
check_port "465" 'printf "QUIT\r\n" | openssl s_client -connect 127.0.0.1:465 -quiet -ign_eof' \
|
||||
"SMTPS (TLS + EHLO)"
|
||||
check_port "587" 'printf "EHLO x\r\nSTARTTLS\r\nQUIT\r\n" | openssl s_client -starttls smtp -connect 127.0.0.1:587 -quiet -ign_eof' \
|
||||
"Submission (STARTTLS)"
|
||||
|
||||
# POP/IMAP
|
||||
check_port "110" 'printf "QUIT\r\n" | nc -w 3 127.0.0.1 110' "POP3 (QUIT)"
|
||||
check_port "995" 'printf "QUIT\r\n" | openssl s_client -connect 127.0.0.1:995 -quiet -ign_eof' "POP3S (TLS + QUIT)"
|
||||
check_port "143" 'printf ". CAPABILITY\r\n. LOGOUT\r\n" | nc -w 3 127.0.0.1 143' "IMAP (CAPABILITY/LOGOUT)"
|
||||
check_port "993" 'printf ". CAPABILITY\r\n. LOGOUT\r\n" | openssl s_client -connect 127.0.0.1:993 -quiet -ign_eof' "IMAPS (TLS + CAPABILITY/LOGOUT)"
|
||||
check_port "110" 'printf "QUIT\r\n" | nc -w 3 127.0.0.1 110' \
|
||||
"POP3 (QUIT)"
|
||||
check_port "995" 'printf "QUIT\r\n" | openssl s_client -connect 127.0.0.1:995 -quiet -ign_eof' \
|
||||
"POP3S (TLS + QUIT)"
|
||||
check_port "143" 'printf ". CAPABILITY\r\n. LOGOUT\r\n" | nc -w 3 127.0.0.1 143' \
|
||||
"IMAP (CAPABILITY/LOGOUT)"
|
||||
check_port "993" 'printf ". CAPABILITY\r\n. LOGOUT\r\n" | openssl s_client -connect 127.0.0.1:993 -quiet -ign_eof' \
|
||||
"IMAPS (TLS + CAPABILITY/LOGOUT)"
|
||||
|
||||
echo
|
||||
echo
|
||||
|
||||
# Nützliche Hinweise am Ende
|
||||
if [[ "$UI_LE" != "LE" || "$WEBMAIL_LE" != "LE" ]]; then
|
||||
echo -e " ${YELLOW}Hinweis:${NC} UI/Webmail verwenden noch kein Let's-Encrypt-Zertifikat."
|
||||
echo -e " Prüfe Symlinks unter /etc/ssl/{ui,webmail} und den LE-Hook (21/75-Skripte)."
|
||||
echo
|
||||
fi
|
||||
|
||||
if [[ "$PROXY_MODE" = "1" ]]; then
|
||||
echo -e " ${GREY}Proxy-Hinweis:${NC} App erwartet TLS am Proxy (keine https-Redirects im Backend)."
|
||||
echo
|
||||
fi
|
||||
Loading…
Reference in New Issue