#!/usr/bin/env bash # ============================================================================= # Entrypoint — stack nginx + varnish + backend HTTP + ja4ebpf # Ordre : backend → varnish → nginx → ja4ebpf # ============================================================================= set -eo pipefail log() { echo "[entrypoint:nginx-varnish] $(date +%H:%M:%S) $*"; } BACKEND_PID="" VARNISH_PID="" NGINX_PID="" JA4EBPF_PID="" cleanup() { log "Arrêt des processus…" for pid in "$JA4EBPF_PID" "$NGINX_PID" "$VARNISH_PID" "$BACKEND_PID"; do [ -n "$pid" ] && kill "$pid" 2>/dev/null || true done wait 2>/dev/null || true } trap cleanup EXIT SIGTERM SIGINT # ── 1. Backend HTTP simple (Python) ────────────────────────────────────────── log "Démarrage du backend HTTP (port 8080)…" python3 -c " import http.server, socketserver, json class H(http.server.BaseHTTPRequestHandler): def log_message(self, *a): pass def do_GET(self): body = json.dumps({'status':'ok','backend':'python','path':self.path}).encode() self.send_response(200) self.send_header('Content-Type','application/json') self.send_header('Content-Length', len(body)) self.end_headers() self.wfile.write(body) def do_POST(self): n = int(self.headers.get('Content-Length',0)) self.rfile.read(n) body = b'{\"result\":\"accepted\"}' self.send_response(200) self.send_header('Content-Type','application/json') self.send_header('Content-Length', len(body)) self.end_headers() self.wfile.write(body) with socketserver.TCPServer(('127.0.0.1', 8080), H) as s: s.serve_forever() " & BACKEND_PID=$! sleep 1 log "Backend HTTP démarré (PID $BACKEND_PID)" # ── 2. Démarrage de Varnish ─────────────────────────────────────────────────── log "Démarrage de Varnish (port 6081)…" varnishd \ -F \ -f /etc/varnish/default.vcl \ -a "0.0.0.0:6081,HTTP" \ -p feature=+http2 \ -s malloc,64m \ -T 127.0.0.1:6082 & VARNISH_PID=$! for i in $(seq 1 20); do if varnishadm -T 127.0.0.1:6082 status 2>/dev/null | grep -q "Child in state running"; then log "Varnish opérationnel (PID $VARNISH_PID)"; break fi sleep 0.5 done # ── 3. Démarrage de nginx ───────────────────────────────────────────────────── log "Démarrage de nginx…" nginx NGINX_PID=$(cat /run/nginx/nginx.pid 2>/dev/null || echo "") for i in $(seq 1 20); do if curl -sf http://localhost/health >/dev/null 2>&1; then log "nginx opérationnel (PID $NGINX_PID)"; break fi sleep 0.5 done # ── 4. Démarrage de ja4ebpf ─────────────────────────────────────────────────── # Attendre que ClickHouse soit prêt (connection refused possible sinon) log "Attente de ClickHouse (max 30s)…" for i in $(seq 1 30); do if curl -sf http://clickhouse:8123/ping >/dev/null 2>&1; then log "ClickHouse est prêt (http://clickhouse:8123/ping OK)" break fi if [ $i -eq 30 ]; then log "⚠ ClickHouse toujours pas prêt après 30s, démarrage ja4ebpf quand même" fi sleep 1 done log "Démarrage de ja4ebpf (uprobes nginx/libssl + hook TC)…" ja4ebpf -config /etc/ja4ebpf/config.yml & JA4EBPF_PID=$! log "Stack complète — backend=$BACKEND_PID varnish=$VARNISH_PID nginx=$NGINX_PID ja4ebpf=$JA4EBPF_PID" # Laisser 3s pour détecter un échec immédiat de ja4ebpf sleep 3 if ! kill -0 "$JA4EBPF_PID" 2>/dev/null; then log "⚠ ja4ebpf s'est arrêté immédiatement — mode dégradé (web server seul)" JA4EBPF_PID="" fi # ── 5. Supervision ──────────────────────────────────────────────────────────── while true; do for pid_var in BACKEND_PID VARNISH_PID; do pid="${!pid_var}" if [ -n "$pid" ] && ! kill -0 "$pid" 2>/dev/null; then log "$pid_var (PID $pid) s'est arrêté — fin" exit 1 fi done # ja4ebpf est optionnel : loguer si arrêté mais ne pas quitter if [ -n "$JA4EBPF_PID" ] && ! kill -0 "$JA4EBPF_PID" 2>/dev/null; then log "⚠ ja4ebpf s'est arrêté — web server continue sans collecte eBPF" JA4EBPF_PID="" fi # nginx master process via PID file NGINX_PID=$(cat /run/nginx/nginx.pid 2>/dev/null || echo "") if [ -z "$NGINX_PID" ] || ! kill -0 "$NGINX_PID" 2>/dev/null; then log "nginx master s'est arrêté — fin" exit 1 fi sleep 2 done