#!/bin/bash # Copyright (C) 2026 Cédric Abonnel # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. set -euo pipefail BASE_DIR="/opt/monitoring" CONF_DIR="${BASE_DIR}/conf" LOG_DIR="/var/log/monitoring" STATE_DIR="/var/lib/monitoring" LOCK_DIR="/var/lock/monitoring" TMP_DIR="/tmp/monitoring-install" UPDATE_BASE_URL="https://git.abonnel.fr/cedricAbonnel/scripts-bash/raw/branch/main/servers/linux" MANIFEST_URL="${UPDATE_BASE_URL}/manifest.txt" INSTALL_DEPS="${INSTALL_DEPS:-true}" CREATE_LOCAL_CONF="${CREATE_LOCAL_CONF:-true}" require_root() { if [ "${EUID}" -ne 0 ]; then echo "Ce script doit être exécuté en root." >&2 exit 1 fi } install_deps() { if [ "${INSTALL_DEPS}" != "true" ]; then return 0 fi if command -v apt-get >/dev/null 2>&1; then apt-get update apt-get install -y curl coreutils findutils grep sed gawk util-linux ca-certificates fi } prepare_dirs() { mkdir -p "${BASE_DIR}" "${CONF_DIR}" "${LOG_DIR}" "${STATE_DIR}" "${LOCK_DIR}" "${TMP_DIR}" chmod 755 "${BASE_DIR}" "${CONF_DIR}" "${LOG_DIR}" "${STATE_DIR}" "${LOCK_DIR}" } fetch_manifest() { curl -fsS "${MANIFEST_URL}" -o "${TMP_DIR}/manifest.txt" } validate_manifest() { awk ' NF == 3 && $1 ~ /^[0-9a-fA-F]{64}$/ && $2 ~ /^(644|755|600)$/ && $3 ~ /^(bin|lib|conf)\/[A-Za-z0-9._\/-]+$/ && $3 !~ /\.\./ ' "${TMP_DIR}/manifest.txt" >/dev/null } apply_mode() { local mode="$1" local file="$2" chmod "$mode" "$file" } download_one() { local expected_hash="$1" local mode="$2" local rel_path="$3" local url="${UPDATE_BASE_URL}/${rel_path}" local dst="${BASE_DIR}/${rel_path}" local tmp_file tmp_file="$(mktemp "${TMP_DIR}/file.XXXXXX")" curl -fsS "$url" -o "$tmp_file" local got_hash got_hash="$(sha256sum "$tmp_file" | awk '{print $1}')" if [ "$got_hash" != "$expected_hash" ]; then echo "Hash invalide pour ${rel_path}" >&2 rm -f "$tmp_file" return 1 fi mkdir -p "$(dirname "$dst")" apply_mode "$mode" "$tmp_file" mv -f "$tmp_file" "$dst" } install_from_manifest() { while read -r hash mode rel_path; do [ -n "${hash:-}" ] || continue download_one "$hash" "$mode" "$rel_path" done < "${TMP_DIR}/manifest.txt" } create_local_conf_if_missing() { if [ "${CREATE_LOCAL_CONF}" != "true" ]; then return 0 fi if [ ! -f "${CONF_DIR}/alert-engine.local.conf" ]; then cat > "${CONF_DIR}/alert-engine.local.conf" <<'EOF' #!/bin/bash NTFY_SERVER="https://ntfy.sh" NTFY_TOPIC="FjdJ7qex2oGqZkV3OMaqNIxe" NTFY_TOKEN="A_REMPLACER" DEST="root" EOF chmod 600 "${CONF_DIR}/alert-engine.local.conf" fi } show_next_steps() { cat <<'EOF' Installation terminée. Étapes suivantes : 1. Éditer /opt/monitoring/conf/alert-engine.local.conf 2. Remplacer NTFY_TOKEN par le vrai token 3. Tester : /opt/monitoring/bin/check_disk.sh /opt/monitoring/bin/alert-engine.sh 4. Ajouter cron ou systemd timer Exemple cron : */5 * * * * /opt/monitoring/bin/check_disk.sh */5 * * * * /opt/monitoring/bin/check_ram.sh 15 */6 * * * /opt/monitoring/bin/check_cert.sh 30 2 * * * /opt/monitoring/bin/check_backup.sh 10 3 * * * /opt/monitoring/bin/monitoring-update.sh * * * * * /opt/monitoring/bin/alert-engine.sh EOF } main() { require_root install_deps prepare_dirs fetch_manifest if ! validate_manifest; then echo "Le manifeste est invalide." >&2 exit 1 fi install_from_manifest create_local_conf_if_missing show_next_steps } main "$@"