190 lines
7.7 KiB
Bash
190 lines
7.7 KiB
Bash
#!/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 |