mailwolt-installer/scripts/95-woltguard.sh

439 lines
17 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/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