mailwolt-installer/scripts/95-woltguard.sh

190 lines
7.7 KiB
Bash
Raw 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
# 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
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
systemctl restart rspamd
sleep 2
ss -tln | grep -q ':11334' || echo "[WARN] Rspamd Controller Port 11334 nicht sichtbar"
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 "/usr/bin/rspamd"
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 port 25 protocol smtp then restart
if failed port 465 type tcpssl then restart
if failed port 587 type tcp 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