178 lines
No EOL
6.9 KiB
Bash
178 lines
No EOL
6.9 KiB
Bash
#!/bin/bash
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# 00-bootstrap-host.sh
|
|
# Bootstrap firewalld + Docker pour USINE_APPLICATIONS
|
|
#
|
|
# A lancer une fois sur chaque host Fedora avant tout déploiement.
|
|
# Idempotent. peut être relancé sans risque.
|
|
#
|
|
# Usage. sudo ./00-bootstrap-host.sh
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
set -euo pipefail
|
|
|
|
# ── Configuration ─────────────────────────────────────────────
|
|
DNS_PRIMARY="${DNS_PRIMARY:-8.8.8.8}"
|
|
DNS_SECONDARY="${DNS_SECONDARY:-8.8.4.4}"
|
|
DOCKER_DAEMON_CONF="/etc/docker/daemon.json"
|
|
TEST_IMAGE="alpine:latest"
|
|
LOG_PREFIX="[bootstrap-host]"
|
|
|
|
# ── Helpers ───────────────────────────────────────────────────
|
|
log() { echo "${LOG_PREFIX} $*"; }
|
|
warn() { echo "${LOG_PREFIX} WARN. $*" >&2; }
|
|
err() { echo "${LOG_PREFIX} ERREUR. $*" >&2; }
|
|
die() { err "$*"; exit 1; }
|
|
|
|
confirm() {
|
|
local prompt="${1:-Continuer ?} [o/N] "
|
|
read -r -p "$prompt" response
|
|
[[ "$response" =~ ^[oOyY]$ ]] || die "Annulation utilisateur."
|
|
}
|
|
|
|
# ── Phase 0. Vérifications préalables ─────────────────────────
|
|
log "Phase 0. vérifications préalables..."
|
|
|
|
[[ $EUID -eq 0 ]] || die "Script à lancer en root (sudo $0)."
|
|
|
|
[[ -f /etc/fedora-release ]] || warn "Système non-Fedora détecté. Le script peut nécessiter des adaptations."
|
|
|
|
command -v docker >/dev/null 2>&1 || die "Docker non installé."
|
|
command -v firewall-cmd >/dev/null 2>&1 || die "firewalld non installé."
|
|
|
|
systemctl is-active --quiet firewalld || die "firewalld non actif. systemctl start firewalld"
|
|
systemctl is-active --quiet docker || die "Docker non actif. systemctl start docker"
|
|
|
|
log " Toutes les vérifications passent."
|
|
|
|
# ── Avertissement utilisateur ─────────────────────────────────
|
|
log ""
|
|
log "Ce script va."
|
|
log " 1. Réécrire ${DOCKER_DAEMON_CONF} (backup automatique)"
|
|
log " 2. Modifier la configuration firewalld (zone trusted + masquerade)"
|
|
log " 3. Redémarrer le service Docker (tous les containers vont stopper)"
|
|
log " 4. Exécuter des tests de validation (pull image alpine)"
|
|
log ""
|
|
|
|
if [[ "${1:-}" != "--force" ]]; then
|
|
confirm "Confirmer le bootstrap ?"
|
|
fi
|
|
|
|
# ── Phase 1. Configuration daemon Docker ──────────────────────
|
|
log ""
|
|
log "Phase 1. configuration de ${DOCKER_DAEMON_CONF}..."
|
|
|
|
mkdir -p /etc/docker
|
|
|
|
if [[ -f "${DOCKER_DAEMON_CONF}" ]]; then
|
|
BACKUP="${DOCKER_DAEMON_CONF}.bak.$(date +%Y%m%d-%H%M%S)"
|
|
cp "${DOCKER_DAEMON_CONF}" "${BACKUP}"
|
|
log " Backup. ${BACKUP}"
|
|
fi
|
|
|
|
cat > "${DOCKER_DAEMON_CONF}" <<EOF
|
|
{
|
|
"iptables": true,
|
|
"ip-masq": true,
|
|
"dns": ["${DNS_PRIMARY}", "${DNS_SECONDARY}"],
|
|
"log-driver": "json-file",
|
|
"log-opts": {
|
|
"max-size": "10m",
|
|
"max-file": "3"
|
|
}
|
|
}
|
|
EOF
|
|
|
|
log " daemon.json écrit."
|
|
|
|
# ── Phase 2. Configuration firewalld ──────────────────────────
|
|
log ""
|
|
log "Phase 2. configuration firewalld..."
|
|
|
|
DEFAULT_ZONE=$(firewall-cmd --get-default-zone)
|
|
log " Zone par défaut. ${DEFAULT_ZONE}"
|
|
|
|
# docker0 (toujours présent quand Docker est installé)
|
|
firewall-cmd --permanent --zone=trusted --add-interface=docker0 2>/dev/null || true
|
|
log " docker0 ajouté à la zone trusted."
|
|
|
|
# Bridges Docker custom (br-*)
|
|
BRIDGES=$(ip -o link show | awk -F: '/br-/{print $2}' | tr -d ' ' | cut -d@ -f1)
|
|
|
|
if [[ -n "${BRIDGES}" ]]; then
|
|
BRIDGE_COUNT=$(echo "${BRIDGES}" | wc -l)
|
|
log " ${BRIDGE_COUNT} bridge(s) custom détecté(s)."
|
|
while IFS= read -r iface; do
|
|
firewall-cmd --permanent --zone=trusted --add-interface="${iface}" 2>/dev/null || true
|
|
log " + ${iface}"
|
|
done <<< "${BRIDGES}"
|
|
else
|
|
log " Aucun bridge custom détecté."
|
|
fi
|
|
|
|
# Masquerade sur la zone par défaut
|
|
firewall-cmd --permanent --zone="${DEFAULT_ZONE}" --add-masquerade 2>/dev/null || true
|
|
log " Masquerade activé sur la zone ${DEFAULT_ZONE}."
|
|
|
|
# Reload
|
|
firewall-cmd --reload
|
|
log " firewalld rechargé."
|
|
|
|
# ── Phase 3. Redémarrage Docker ───────────────────────────────
|
|
log ""
|
|
log "Phase 3. redémarrage du service Docker..."
|
|
|
|
systemctl restart docker
|
|
|
|
# Attente que Docker soit pleinement opérationnel
|
|
for i in {1..15}; do
|
|
if docker info >/dev/null 2>&1; then
|
|
log " Docker opérationnel après ${i}s."
|
|
break
|
|
fi
|
|
sleep 1
|
|
if [[ $i -eq 15 ]]; then
|
|
die "Docker ne répond pas après 15s."
|
|
fi
|
|
done
|
|
|
|
# ── Phase 4. Tests de validation ──────────────────────────────
|
|
log ""
|
|
log "Phase 4. tests de validation..."
|
|
|
|
log " Test 1. pull image de test (${TEST_IMAGE})..."
|
|
docker pull "${TEST_IMAGE}" >/dev/null 2>&1 || die "Pull image échoué. DNS du host probablement HS."
|
|
log " OK"
|
|
|
|
log " Test 2. résolution DNS depuis un container..."
|
|
if docker run --rm "${TEST_IMAGE}" nslookup archive.ubuntu.com >/dev/null 2>&1; then
|
|
log " OK"
|
|
else
|
|
err " Échec résolution DNS."
|
|
err " Lancer manuellement. docker run --rm alpine nslookup archive.ubuntu.com"
|
|
exit 2
|
|
fi
|
|
|
|
log " Test 3. connectivité HTTPS sortante depuis un container..."
|
|
if docker run --rm "${TEST_IMAGE}" wget -q --spider https://www.cloudflare.com 2>/dev/null; then
|
|
log " OK"
|
|
else
|
|
err " Échec connectivité HTTPS sortante."
|
|
exit 2
|
|
fi
|
|
|
|
# ── Phase 5. Résumé ───────────────────────────────────────────
|
|
log ""
|
|
log "═══════════════════════════════════════════════════════════"
|
|
log " Bootstrap terminé avec succès."
|
|
log "═══════════════════════════════════════════════════════════"
|
|
log " Zone par défaut. ${DEFAULT_ZONE}"
|
|
log " Masquerade. actif"
|
|
log " DNS Docker. ${DNS_PRIMARY}, ${DNS_SECONDARY}"
|
|
log " Daemon config. ${DOCKER_DAEMON_CONF}"
|
|
log ""
|
|
log " Interfaces en zone trusted."
|
|
firewall-cmd --zone=trusted --list-interfaces | tr ' ' '\n' | sed 's/^/ - /'
|
|
log ""
|
|
log " USINE_APPLICATIONS prêt pour déploiement."
|
|
log "═══════════════════════════════════════════════════════════" |