#!/usr/bin/env bash set -euo pipefail # Flags laden (falls vorhanden) INSTALLER_ENV="/etc/mailwolt/installer.env" : "${CLAMAV_ENABLE:=}"; : "${OPENDMARC_ENABLE:=}"; : "${FAIL2BAN_ENABLE:=}"; : "${MONIT_HTTP:=}" if [[ -z "${CLAMAV_ENABLE}${OPENDMARC_ENABLE}${FAIL2BAN_ENABLE}" && -r "$INSTALLER_ENV" ]]; then . "$INSTALLER_ENV" fi CLAMAV_ENABLE="${CLAMAV_ENABLE:-1}" OPENDMARC_ENABLE="${OPENDMARC_ENABLE:-1}" FAIL2BAN_ENABLE="${FAIL2BAN_ENABLE:-1}" MONIT_HTTP="${MONIT_HTTP:-1}" # ── Monit so konfigurieren, dass NUR monitrc.d/* geladen wird ──────────────── install -d -m 0755 /etc/monit/monitrc.d install -d -m 0755 /etc/monit/conf.d # passiver Ablageort (NICHT includiert) # Poll-Intervall (30s) sed -i 's/^set daemon .*/set daemon 30/' /etc/monit/monitrc || true # alle alten include-Zeilen raus und monitrc.d setzen sed -i 's|^#\?\s*include .*$||g' /etc/monit/monitrc grep -q '^include /etc/monit/monitrc.d/\*' /etc/monit/monitrc \ || echo 'include /etc/monit/monitrc.d/*' >> /etc/monit/monitrc # Optional: HTTP-UI nur einschalten, wenn explizit gewünscht if [[ "$MONIT_HTTP" = "1" ]]; then grep -q '^set httpd port 2812' /etc/monit/monitrc || cat >>/etc/monit/monitrc <<'HTTP' set httpd port 2812 and use address localhost allow localhost HTTP fi # KEIN Löschen mehr der Dateien – wir verschieben je nach Status # (vorher stand hier rm -rf /etc/monit/monitrc.d/* und rm -f /etc/monit/conf.d/*.conf) # ── Helper-Skripte ────────────────────────────────────────────────────────── install -d -m 0755 /usr/local/sbin # Redis-Ping (Password: REDIS_PASSWORD aus installer.env oder .env) cat >/usr/local/sbin/mailwolt-redis-ping.sh <<'EOSH' #!/usr/bin/env bash set -euo pipefail INSTALLER_ENV="/etc/mailwolt/installer.env" APP_ENV="/var/www/mailwolt/.env" REDIS_HOST="${REDIS_HOST:-127.0.0.1}" REDIS_PORT="${REDIS_PORT:-6379}" REDIS_PASSWORD="${REDIS_PASSWORD:-}" REDIS_PASS="${REDIS_PASS:-}" [[ -r "$INSTALLER_ENV" ]] && . "$INSTALLER_ENV" || true if [[ -r "$APP_ENV" ]]; then [[ -z "${REDIS_HOST}" ]] && REDIS_HOST="$(grep -m1 '^REDIS_HOST=' "$APP_ENV" | cut -d= -f2- || true)" [[ -z "${REDIS_PORT}" ]] && REDIS_PORT="$(grep -m1 '^REDIS_PORT=' "$APP_ENV" | cut -d= -f2- || true)" [[ -z "${REDIS_PASSWORD}" ]] && REDIS_PASSWORD="$(grep -m1 '^REDIS_PASSWORD=' "$APP_ENV" | cut -d= -f2- || true)" fi [[ -z "${REDIS_PASSWORD}" && -n "${REDIS_PASS}" ]] && REDIS_PASSWORD="$REDIS_PASS" strip(){ printf '%s' "$1" | sed -E 's/^"(.*)"$/\1/; s/^'"'"'(.*)'"'"'$/\1/'; } REDIS_HOST="$(strip "${REDIS_HOST:-}")" REDIS_PORT="$(strip "${REDIS_PORT:-}")" REDIS_PASSWORD="$(strip "${REDIS_PASSWORD:-}")" command -v redis-cli >/dev/null 2>&1 || exit 1 BASE=(timeout 2 redis-cli --no-auth-warning --raw -h "$REDIS_HOST" -p "$REDIS_PORT") [[ -n "$REDIS_PASSWORD" ]] && CMD=("${BASE[@]}" -a "$REDIS_PASSWORD" ping) || CMD=("${BASE[@]}" ping) [[ "$("${CMD[@]}" 2>/dev/null || true)" == "PONG" ]] EOSH chmod 0755 /usr/local/sbin/mailwolt-redis-ping.sh # Rspamd-Heal (Socke aufräumen, restart, Mini-Port-Check) cat >/usr/local/sbin/mailwolt-rspamd-heal.sh <<'EOSH' #!/usr/bin/env bash set -euo pipefail INSTALLER_ENV="/etc/mailwolt/installer.env" APP_ENV="/var/www/mailwolt/.env" REDIS_HOST="${REDIS_HOST:-127.0.0.1}" REDIS_PORT="${REDIS_PORT:-6379}" REDIS_PASS="${REDIS_PASS:-}" [[ -r "$INSTALLER_ENV" ]] && . "$INSTALLER_ENV" if [[ -z "${REDIS_PASS}" && -r "$APP_ENV" ]]; then REDIS_PASS="$(grep -E '^REDIS_PASS=' "$APP_ENV" | head -n1 | cut -d= -f2- || true)" fi # Rspamd Runtime fixen install -d -m 0755 -o _rspamd -g _rspamd /run/rspamd || true [[ -S /var/lib/rspamd/rspamd.sock ]] && rm -f /var/lib/rspamd/rspamd.sock || true echo "$(date '+%F %T') heal run" >> /var/log/rspamd-heal.log # Neustart systemctl restart rspamd # Mini-Healthcheck sleep 2 ss -tln | grep -q ':11334' || echo "[WARN] Rspamd Controller Port 11334 nicht sichtbar" exit 0 EOSH chmod 0755 /usr/local/sbin/mailwolt-rspamd-heal.sh # ── Monit-Checks (nummeriert) – fixe Dienste immer aktiv ──────────────────── # 10 – Redis cat >/etc/monit/monitrc.d/10-redis.conf <<'EOF' check process redis with pidfile /run/redis/redis-server.pid start program = "/bin/systemctl start redis-server" stop program = "/bin/systemctl stop redis-server" if failed host 127.0.0.1 port 6379 for 2 cycles then restart if 5 restarts within 5 cycles then alert check program redis_ping path "/usr/local/sbin/mailwolt-redis-ping.sh" if status != 0 for 2 cycles then exec "/bin/systemctl restart redis-server" EOF # 20 – Rspamd (robust via process-matching + Heal) cat >/etc/monit/monitrc.d/20-rspamd.conf <<'EOF' check process rspamd matching "rspamd: main process" start program = "/bin/systemctl start rspamd" with timeout 120 seconds stop program = "/bin/systemctl stop rspamd" depends on redis if failed host 127.0.0.1 port 11333 for 3 cycles then exec "/usr/local/sbin/mailwolt-rspamd-heal.sh" if failed host 127.0.0.1 port 11334 for 3 cycles then exec "/usr/local/sbin/mailwolt-rspamd-heal.sh" if does not exist for 2 cycles then restart if 5 restarts within 10 cycles then unmonitor EOF # 30 – Postfix cat >/etc/monit/monitrc.d/30-postfix.conf <<'EOF' check process postfix with pidfile /var/spool/postfix/pid/master.pid start program = "/bin/systemctl start postfix" stop program = "/bin/systemctl stop postfix" if failed host 127.0.0.1 port 25 type tcp with timeout 15 seconds for 3 cycles then restart if failed host 127.0.0.1 port 465 type tcpssl with timeout 10 seconds then restart if failed host 127.0.0.1 port 587 type tcp with timeout 10 seconds then restart if 5 restarts within 5 cycles then alert EOF # 30 – Dovecot (IMAPS; LMTP oft Unix-Socket → kein TCP-Fehlalarm) cat >/etc/monit/monitrc.d/30-dovecot.conf <<'EOF' check process dovecot with pidfile /run/dovecot/master.pid start program = "/bin/systemctl start dovecot" stop program = "/bin/systemctl stop dovecot" if failed port 993 type tcpssl for 3 cycles then restart if 5 restarts within 10 cycles then alert EOF # 40 – Nginx cat >/etc/monit/monitrc.d/40-nginx.conf <<'EOF' check process nginx with pidfile /run/nginx.pid start program = "/bin/systemctl start nginx" stop program = "/bin/systemctl stop nginx" if failed port 80 type tcp then restart if failed port 443 type tcpssl then restart if 5 restarts within 5 cycles then alert EOF # 50 – OpenDKIM cat >/etc/monit/monitrc.d/50-opendkim.conf <<'EOF' check process opendkim with pidfile /run/opendkim/opendkim.pid start program = "/bin/systemctl start opendkim" stop program = "/bin/systemctl stop opendkim" if failed host 127.0.0.1 port 8891 type tcp for 2 cycles then restart if 5 restarts within 5 cycles then alert EOF move_monit_conf() { local name="$1" # z.B. 55-opendmarc local enabled="$2" # "0" oder "1" local src="/etc/monit/conf.d/${name}.conf" local dst="/etc/monit/monitrc.d/${name}.conf" mkdir -p /etc/monit/conf.d /etc/monit/monitrc.d # Falls Datei nirgends existiert → in conf.d anlegen (lesbare Quelle) if [[ ! -f "$src" && ! -f "$dst" ]]; then cat >"$src" <<'EOF_PAYLOAD' __PAYLOAD__ EOF_PAYLOAD fi if [[ "$enabled" = "1" ]]; then # Aktiv: in monitrc.d haben if [[ -f "$src" && ! -f "$dst" ]]; then mv -f "$src" "$dst" fi else # Inaktiv: in conf.d haben if [[ -f "$dst" && ! -f "$src" ]]; then mv -f "$dst" "$src" fi fi } move_monit_conf "55-opendmarc" "${OPENDMARC_ENABLE:-0}" <<'EOF' check process opendmarc with pidfile /run/opendmarc/opendmarc.pid start program = "/bin/systemctl start opendmarc" stop program = "/bin/systemctl stop opendmarc" if 5 restarts within 5 cycles then alert EOF move_monit_conf "60-clamav" "${CLAMAV_ENABLE:-0}" <<'EOF' check process clamd matching "clamd" start program = "/bin/systemctl start clamav-daemon" stop program = "/bin/systemctl stop clamav-daemon" if failed unixsocket /run/clamav/clamd.ctl for 3 cycles then restart if 5 restarts within 10 cycles then unmonitor EOF move_monit_conf "70-fail2ban" "${FAIL2BAN_ENABLE:-0}" <<'EOF' check process fail2ban with pidfile /run/fail2ban/fail2ban.pid start program = "/bin/systemctl start fail2ban" stop program = "/bin/systemctl stop fail2ban" if 5 restarts within 5 cycles then alert EOF # ── Monit neu laden ───────────────────────────────────────────────────────── monit -t systemctl reload monit || systemctl restart monit # Optionaler Sichttest (CLI funktioniert auch ohne HTTP-UI) # sleep 2 # monit summary || true ##!/usr/bin/env bash #set -euo pipefail # ## Flags laden (falls vorhanden) #INSTALLER_ENV="/etc/mailwolt/installer.env" #: "${CLAMAV_ENABLE:=}"; : "${OPENDMARC_ENABLE:=}"; : "${FAIL2BAN_ENABLE:=}"; : "${MONIT_HTTP:=}" #if [[ -z "${CLAMAV_ENABLE}${OPENDMARC_ENABLE}${FAIL2BAN_ENABLE}" && -r "$INSTALLER_ENV" ]]; then # . "$INSTALLER_ENV" #fi #CLAMAV_ENABLE="${CLAMAV_ENABLE:-1}" #OPENDMARC_ENABLE="${OPENDMARC_ENABLE:-1}" #FAIL2BAN_ENABLE="${FAIL2BAN_ENABLE:-1}" #MONIT_HTTP="${MONIT_HTTP:-1}" # ## ── Monit so konfigurieren, dass NUR monitrc.d/* geladen wird ──────────────── #install -d -m 0755 /etc/monit/monitrc.d ## Poll-Intervall (30s) #sed -i 's/^set daemon .*/set daemon 30/' /etc/monit/monitrc || true ## alle alten include-Zeilen raus und monitrc.d setzen #sed -i 's|^#\?\s*include .*$||g' /etc/monit/monitrc #grep -q '^include /etc/monit/monitrc.d/\*' /etc/monit/monitrc \ # || echo 'include /etc/monit/monitrc.d/*' >> /etc/monit/monitrc # ## Optional: HTTP-UI nur einschalten, wenn explizit gewünscht #if [[ "$MONIT_HTTP" = "1" ]]; then # grep -q '^set httpd port 2812' /etc/monit/monitrc || cat >>/etc/monit/monitrc <<'HTTP' #set httpd port 2812 and # use address localhost # allow localhost #HTTP #fi # #sudo mkdir -p /etc/monit/monitrc.d #sudo rm -rf /etc/monit/monitrc.d/* 2>/dev/null || true #sudo rm -f /etc/monit/conf.d/*.conf 2>/dev/null || true # ## ── Helper-Skripte ────────────────────────────────────────────────────────── #install -d -m 0755 /usr/local/sbin # ## Redis-Ping (Password: REDIS_PASSWORD aus installer.env oder .env) #cat >/usr/local/sbin/mailwolt-redis-ping.sh <<'EOSH' ##!/usr/bin/env bash #set -euo pipefail #INSTALLER_ENV="/etc/mailwolt/installer.env" #APP_ENV="/var/www/mailwolt/.env" #REDIS_HOST="${REDIS_HOST:-127.0.0.1}" #REDIS_PORT="${REDIS_PORT:-6379}" #REDIS_PASSWORD="${REDIS_PASSWORD:-}" #REDIS_PASS="${REDIS_PASS:-}" # #[[ -r "$INSTALLER_ENV" ]] && . "$INSTALLER_ENV" || true #if [[ -r "$APP_ENV" ]]; then # [[ -z "${REDIS_HOST}" ]] && REDIS_HOST="$(grep -m1 '^REDIS_HOST=' "$APP_ENV" | cut -d= -f2- || true)" # [[ -z "${REDIS_PORT}" ]] && REDIS_PORT="$(grep -m1 '^REDIS_PORT=' "$APP_ENV" | cut -d= -f2- || true)" # [[ -z "${REDIS_PASSWORD}" ]] && REDIS_PASSWORD="$(grep -m1 '^REDIS_PASSWORD=' "$APP_ENV" | cut -d= -f2- || true)" #fi #[[ -z "${REDIS_PASSWORD}" && -n "${REDIS_PASS}" ]] && REDIS_PASSWORD="$REDIS_PASS" # #strip(){ printf '%s' "$1" | sed -E 's/^"(.*)"$/\1/; s/^'"'"'(.*)'"'"'$/\1/'; } #REDIS_HOST="$(strip "${REDIS_HOST:-}")" #REDIS_PORT="$(strip "${REDIS_PORT:-}")" #REDIS_PASSWORD="$(strip "${REDIS_PASSWORD:-}")" # #command -v redis-cli >/dev/null 2>&1 || exit 1 #BASE=(timeout 2 redis-cli --no-auth-warning --raw -h "$REDIS_HOST" -p "$REDIS_PORT") #[[ -n "$REDIS_PASSWORD" ]] && CMD=("${BASE[@]}" -a "$REDIS_PASSWORD" ping) || CMD=("${BASE[@]}" ping) #[[ "$("${CMD[@]}" 2>/dev/null || true)" == "PONG" ]] #EOSH #chmod 0755 /usr/local/sbin/mailwolt-redis-ping.sh # ## Rspamd-Heal (Socke aufräumen, restart, Mini-Port-Check) #cat >/usr/local/sbin/mailwolt-rspamd-heal.sh <<'EOSH' ##!/usr/bin/env bash #set -euo pipefail # #INSTALLER_ENV="/etc/mailwolt/installer.env" #APP_ENV="/var/www/mailwolt/.env" # #REDIS_HOST="${REDIS_HOST:-127.0.0.1}" #REDIS_PORT="${REDIS_PORT:-6379}" #REDIS_PASS="${REDIS_PASS:-}" # #[[ -r "$INSTALLER_ENV" ]] && . "$INSTALLER_ENV" #if [[ -z "${REDIS_PASS}" && -r "$APP_ENV" ]]; then # REDIS_PASS="$(grep -E '^REDIS_PASS=' "$APP_ENV" | head -n1 | cut -d= -f2- || true)" #fi # ## Rspamd Runtime fixen #install -d -m 0755 -o _rspamd -g _rspamd /run/rspamd || true #[[ -S /var/lib/rspamd/rspamd.sock ]] && rm -f /var/lib/rspamd/rspamd.sock || true # #echo "$(date '+%F %T') heal run" >> /var/log/rspamd-heal.log # ## Neustart #systemctl restart rspamd # ## Mini-Healthcheck #sleep 2 #ss -tln | grep -q ':11334' || echo "[WARN] Rspamd Controller Port 11334 nicht sichtbar" # #exit 0 #EOSH #chmod 0755 /usr/local/sbin/mailwolt-rspamd-heal.sh # ## ── Monit-Checks (nummeriert) ─────────────────────────────────────────────── ## 10 – Redis #cat >/etc/monit/monitrc.d/10-redis.conf <<'EOF' #check process redis with pidfile /run/redis/redis-server.pid # start program = "/bin/systemctl start redis-server" # stop program = "/bin/systemctl stop redis-server" # if failed host 127.0.0.1 port 6379 for 2 cycles then restart # if 5 restarts within 5 cycles then alert # #check program redis_ping path "/usr/local/sbin/mailwolt-redis-ping.sh" # if status != 0 for 2 cycles then exec "/bin/systemctl restart redis-server" #EOF # ## 20 – Rspamd (robust via process-matching + Heal) #cat >/etc/monit/monitrc.d/20-rspamd.conf <<'EOF' #check process rspamd matching "rspamd: main process" # start program = "/bin/systemctl start rspamd" with timeout 120 seconds # stop program = "/bin/systemctl stop rspamd" # depends on redis # if failed host 127.0.0.1 port 11333 for 3 cycles then exec "/usr/local/sbin/mailwolt-rspamd-heal.sh" # if failed host 127.0.0.1 port 11334 for 3 cycles then exec "/usr/local/sbin/mailwolt-rspamd-heal.sh" # if does not exist for 2 cycles then restart # if 5 restarts within 10 cycles then unmonitor #EOF # ## 30 – Postfix #cat >/etc/monit/monitrc.d/30-postfix.conf <<'EOF' #check process postfix with pidfile /var/spool/postfix/pid/master.pid # start program = "/bin/systemctl start postfix" # stop program = "/bin/systemctl stop postfix" # if failed host 127.0.0.1 port 25 type tcp with timeout 15 seconds for 3 cycles then restart # if failed host 127.0.0.1 port 465 type tcpssl with timeout 10 seconds then restart # if failed host 127.0.0.1 port 587 type tcp with timeout 10 seconds then restart # if 5 restarts within 5 cycles then alert #EOF # ## 30 – Dovecot (IMAPS; LMTP oft Unix-Socket → kein TCP-Fehlalarm) #cat >/etc/monit/monitrc.d/30-dovecot.conf <<'EOF' #check process dovecot with pidfile /run/dovecot/master.pid # start program = "/bin/systemctl start dovecot" # stop program = "/bin/systemctl stop dovecot" # if failed port 993 type tcpssl for 3 cycles then restart # if 5 restarts within 10 cycles then alert #EOF # ## 40 – Nginx #cat >/etc/monit/monitrc.d/40-nginx.conf <<'EOF' #check process nginx with pidfile /run/nginx.pid # start program = "/bin/systemctl start nginx" # stop program = "/bin/systemctl stop nginx" # if failed port 80 type tcp then restart # if failed port 443 type tcpssl then restart # if 5 restarts within 5 cycles then alert #EOF # ## 50 – OpenDKIM #cat >/etc/monit/monitrc.d/50-opendkim.conf <<'EOF' #check process opendkim with pidfile /run/opendkim/opendkim.pid # start program = "/bin/systemctl start opendkim" # stop program = "/bin/systemctl stop opendkim" # if failed host 127.0.0.1 port 8891 type tcp for 2 cycles then restart # if 5 restarts within 5 cycles then alert #EOF # ## 55 – OpenDMARC (optional) #if [[ "$OPENDMARC_ENABLE" = "1" ]]; then # cat >/etc/monit/monitrc.d/55-opendmarc.conf <<'EOF' #check process opendmarc with pidfile /run/opendmarc/opendmarc.pid # start program = "/bin/systemctl start opendmarc" # stop program = "/bin/systemctl stop opendmarc" # if 5 restarts within 5 cycles then alert #EOF #else # rm -f /etc/monit/monitrc.d/55-opendmarc.conf || true #fi # ## 60 – ClamAV (über Socket) #if [[ "$CLAMAV_ENABLE" = "1" ]]; then # cat >/etc/monit/monitrc.d/60-clamav.conf <<'EOF' #check process clamd matching "clamd" # start program = "/bin/systemctl start clamav-daemon" # stop program = "/bin/systemctl stop clamav-daemon" # if failed unixsocket /run/clamav/clamd.ctl for 3 cycles then restart # if 5 restarts within 10 cycles then unmonitor #EOF #else # rm -f /etc/monit/monitrc.d/60-clamav.conf || true #fi # ## 70 – Fail2Ban (optional) #if [[ "$FAIL2BAN_ENABLE" = "1" ]]; then # cat >/etc/monit/monitrc.d/70-fail2ban.conf <<'EOF' #check process fail2ban with pidfile /run/fail2ban/fail2ban.pid # start program = "/bin/systemctl start fail2ban" # stop program = "/bin/systemctl stop fail2ban" # if 5 restarts within 5 cycles then alert #EOF #else # rm -f /etc/monit/monitrc.d/70-fail2ban.conf || true #fi # ## ── Monit neu laden ───────────────────────────────────────────────────────── #monit -t #systemctl reload monit || systemctl restart monit # ## Optionaler Sichttest (CLI funktioniert auch ohne HTTP-UI) ##sleep 2 ##monit summary || true