Add LPLDF HTTPS watchdog systemd units for 4NK proxy

**Motivations:**
- Alert when the LPLDF storefront HTTPS endpoint is down from the proxy

**Root causes:**
- N/A (monitoring gap)

**Correctifs:**
- N/A

**Evolutions:**
- watch-https-lpldf.sh: curl check, state file, syslog tag lpldf-https-watch, optional webhook/email via env file
- systemd oneshot + 5-minute timer; install script via SSH/scp

**Pages affectées:**
- tools/proxy-https-watch-lpldf.sh
- tools/proxy-https-watch-lpldf.env.example
- deploy/proxy-units/lpldf-https-watch.service
- deploy/proxy-units/lpldf-https-watch.timer
- deploy/scripts/install-lpldf-https-watch-on-proxy.sh
- deploy/README-lpldf-https-watch.md
This commit is contained in:
Nicolas Cantu 2026-03-22 23:35:43 +01:00
parent 0198ff7813
commit 4a0b031b89
6 changed files with 198 additions and 0 deletions

View File

@ -0,0 +1,32 @@
# LPLDF HTTPS watchdog on the 4NK proxy
## Purpose
Detect downtime of `https://xn--lespetitesleonsdefrdric-89b1db.fr/` from the proxy and emit alerts (syslog tag `lpldf-https-watch`, optional webhooks / mail). Acts as an availability watchdog; a SIEM (e.g. Wazuh) can ingest these syslog lines.
## Repository paths
- Watch script (installed to `/opt/proxy-config/scripts/watch-https-lpldf.sh`): `tools/proxy-https-watch-lpldf.sh`
- Optional env example: `tools/proxy-https-watch-lpldf.env.example`
- Systemd units: `deploy/proxy-units/lpldf-https-watch.service`, `deploy/proxy-units/lpldf-https-watch.timer`
- Installer (from ia_dev root): `./deploy/scripts/install-lpldf-https-watch-on-proxy.sh`
## Behaviour
- Accepts HTTP status 200, 301, 302, 307, 308.
- State under `/var/lib/lpldf-https-watch/`.
- First DOWN: `daemon.warning` + optional `ALERT_WEBHOOK_URL` / `ALERT_EMAIL_TO`.
- Repeats while down at most every `ALERT_REPEAT_SECONDS` (default 3600).
- Recovery: `daemon.info` + optional `ALERT_WEBHOOK_URL_RECOVER`.
## Optional proxy config
Create `/opt/proxy-config/scripts/env/watch-https-lpldf.env` (e.g. `chmod 600`), see `tools/proxy-https-watch-lpldf.env.example`.
## Operations
- Manual run on proxy: `sudo /opt/proxy-config/scripts/watch-https-lpldf.sh`
- Logs: `sudo journalctl -t lpldf-https-watch`
- Timer: `systemctl status lpldf-https-watch.timer`
Nginx is not modified for this check.

View File

@ -0,0 +1,8 @@
[Unit]
Description=HTTPS availability check for LPLDF (Les Petites Lecons)
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/opt/proxy-config/scripts/watch-https-lpldf.sh

View File

@ -0,0 +1,10 @@
[Unit]
Description=Run LPLDF HTTPS watch every 5 minutes
[Timer]
OnBootSec=3min
OnUnitActiveSec=5min
Persistent=true
[Install]
WantedBy=timers.target

View File

@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Install HTTPS watchdog + systemd timer on the 4NK proxy (192.168.1.100).
# Does not modify Nginx. Run from ia_dev root: ./deploy/scripts/install-lpldf-https-watch-on-proxy.sh
set -euo pipefail
IA_DEV_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# shellcheck source=deploy/_lib/ssh.sh
source "${IA_DEV_ROOT}/deploy/_lib/ssh.sh"
readonly SSH_KEY="${DEPLOY_SSH_KEY:-${HOME}/.ssh/id_ed25519}"
readonly SSH_USER="${DEPLOY_SSH_USER:-ncantu}"
readonly PROXY_HOST="${DEPLOY_PROXY_HOST:-192.168.1.100}"
export DEPLOY_SSH_PROXY_HOST="${DEPLOY_SSH_PROXY_HOST:-4nk.myftp.biz}"
readonly REMOTE_SCRIPT="/opt/proxy-config/scripts/watch-https-lpldf.sh"
readonly REMOTE_ENV_DIR="/opt/proxy-config/scripts/env"
readonly REMOTE_ENV="${REMOTE_ENV_DIR}/watch-https-lpldf.env"
readonly SERVICE_NAME="lpldf-https-watch"
scp_copy "$SSH_KEY" "${IA_DEV_ROOT}/tools/proxy-https-watch-lpldf.sh" "$SSH_USER" "$PROXY_HOST" "/tmp/watch-https-lpldf.sh" "false"
scp_copy "$SSH_KEY" "${IA_DEV_ROOT}/deploy/proxy-units/${SERVICE_NAME}.service" "$SSH_USER" "$PROXY_HOST" "/tmp/${SERVICE_NAME}.service" "false"
scp_copy "$SSH_KEY" "${IA_DEV_ROOT}/deploy/proxy-units/${SERVICE_NAME}.timer" "$SSH_USER" "$PROXY_HOST" "/tmp/${SERVICE_NAME}.timer" "false"
ssh_run "$SSH_KEY" "$SSH_USER" "$PROXY_HOST" \
"sudo install -d -m 755 /opt/proxy-config/scripts && \
sudo install -d -m 700 ${REMOTE_ENV_DIR} && \
sudo install -m 755 /tmp/watch-https-lpldf.sh ${REMOTE_SCRIPT} && \
sudo rm -f /tmp/watch-https-lpldf.sh && \
sudo install -d -m 755 /var/lib/lpldf-https-watch && \
sudo install -m 644 /tmp/${SERVICE_NAME}.service /etc/systemd/system/${SERVICE_NAME}.service && \
sudo install -m 644 /tmp/${SERVICE_NAME}.timer /etc/systemd/system/${SERVICE_NAME}.timer && \
sudo rm -f /tmp/${SERVICE_NAME}.service /tmp/${SERVICE_NAME}.timer && \
sudo systemctl daemon-reload && \
sudo systemctl enable --now ${SERVICE_NAME}.timer && \
sudo systemctl start ${SERVICE_NAME}.service || true && \
systemctl --no-pager --full status ${SERVICE_NAME}.timer"
echo "[install-lpldf-https-watch] Installed ${REMOTE_SCRIPT} and ${SERVICE_NAME}.timer on ${PROXY_HOST}"
echo "[install-lpldf-https-watch] Optional: create ${REMOTE_ENV} (chmod 600); see tools/proxy-https-watch-lpldf.env.example"

View File

@ -0,0 +1,11 @@
# Copy to /opt/proxy-config/scripts/env/watch-https-lpldf.env on the proxy (chmod 600).
# Optional: webhook for down alerts (plain text POST body).
# ALERT_WEBHOOK_URL=https://example.com/hook
# Optional: separate webhook when the site recovers.
# ALERT_WEBHOOK_URL_RECOVER=https://example.com/hook-recover
# Optional: repeat down notifications at most every N seconds while still failing.
# ALERT_REPEAT_SECONDS=3600
# Optional: if `mail` is configured on the host.
# ALERT_EMAIL_TO=ops@example.com
# Override URL if needed (default is punycode LPLDF front URL).
# WATCH_URL=https://xn--lespetitesleonsdefrdric-89b1db.fr/

View File

@ -0,0 +1,98 @@
#!/usr/bin/env bash
# HTTPS availability watchdog for Les Petites Leçons de Frédéric (punycode host).
# Intended path on proxy: /opt/proxy-config/scripts/watch-https-lpldf.sh
# Optional env file (root-only recommended): /opt/proxy-config/scripts/env/watch-https-lpldf.env
# Syslog identifier: lpldf-https-watch (for SIEM / Wazuh-style log collection).
set -euo pipefail
readonly WATCH_URL="${WATCH_URL:-https://xn--lespetitesleonsdefrdric-89b1db.fr/}"
readonly STATE_DIR="${STATE_DIR:-/var/lib/lpldf-https-watch}"
readonly STATE_FILE="${STATE_DIR}/last_state"
readonly LAST_ALERT_FILE="${STATE_DIR}/last_alert_epoch"
readonly LOG_TAG="lpldf-https-watch"
ENV_FILE="${ENV_FILE:-/opt/proxy-config/scripts/env/watch-https-lpldf.env}"
if [[ -f "$ENV_FILE" ]]; then
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
fi
readonly ALERT_REPEAT_SECONDS="${ALERT_REPEAT_SECONDS:-3600}"
mkdir -p "$STATE_DIR"
last="OK"
if [[ -f "$STATE_FILE" ]]; then
last="$(tr -d '\n' <"$STATE_FILE" || true)"
fi
[[ -z "$last" ]] && last="OK"
http_code="000"
if ! http_code="$(curl -sS -o /dev/null -w '%{http_code}' --max-time 25 "$WATCH_URL" 2>/dev/null)"; then
http_code="000"
fi
[[ -z "$http_code" ]] && http_code="000"
is_ok="false"
if [[ "$http_code" =~ ^(200|301|302|307|308)$ ]]; then
is_ok="true"
fi
send_notifications() {
local message="$1"
logger -t "$LOG_TAG" -p daemon.warning "$message"
if [[ -n "${ALERT_WEBHOOK_URL:-}" ]]; then
curl -sS -X POST "${ALERT_WEBHOOK_URL}" \
-H "Content-Type: text/plain; charset=utf-8" \
--data-binary "$message" \
--max-time 15 || logger -t "$LOG_TAG" -p daemon.err "ALERT_WEBHOOK_URL post failed"
fi
if [[ -n "${ALERT_EMAIL_TO:-}" ]] && command -v mail >/dev/null 2>&1; then
printf '%s\n' "$message" | mail -s "LPLDF HTTPS down" "$ALERT_EMAIL_TO" || logger -t "$LOG_TAG" -p daemon.err "mail alert failed"
fi
}
notify_recovery() {
local message="$1"
logger -t "$LOG_TAG" -p daemon.info "$message"
if [[ -n "${ALERT_WEBHOOK_URL_RECOVER:-}" ]]; then
curl -sS -X POST "${ALERT_WEBHOOK_URL_RECOVER}" \
-H "Content-Type: text/plain; charset=utf-8" \
--data-binary "$message" \
--max-time 15 || true
fi
}
now_epoch="$(date +%s)"
if [[ "$is_ok" == "true" ]]; then
if [[ "$last" == "DOWN" ]]; then
notify_recovery "LPLDF HTTPS recovered: ${WATCH_URL} HTTP ${http_code}"
fi
printf '%s\n' "OK" >"$STATE_FILE"
exit 0
fi
msg="LPLDF HTTPS check FAIL: ${WATCH_URL} HTTP=${http_code}"
if [[ "$last" != "DOWN" ]]; then
printf '%s\n' "DOWN" >"$STATE_FILE"
printf '%s\n' "$now_epoch" >"$LAST_ALERT_FILE"
send_notifications "$msg"
exit 1
fi
last_alert="0"
if [[ -f "$LAST_ALERT_FILE" ]]; then
last_alert="$(tr -d '\n' <"$LAST_ALERT_FILE" || echo 0)"
fi
[[ -z "$last_alert" ]] && last_alert="0"
if [[ "$((now_epoch - last_alert))" -ge "$ALERT_REPEAT_SECONDS" ]]; then
printf '%s\n' "$now_epoch" >"$LAST_ALERT_FILE"
send_notifications "$msg (still down, repeat every ${ALERT_REPEAT_SECONDS}s)"
fi
exit 1