feat(e2e): add multi-IP endpoint architecture with dedicated traffic VM

Replace single-service-per-endpoint with all-ips mode running nginx, apache,
and hitch+varnish simultaneously on 3 dedicated IPs per VM (eth1 alias IPs).
Add a dedicated traffic VM with curl-impersonate for realistic TLS fingerprints,
parallelized traffic generation, and paired SNI_HOSTS/TARGET_IPS lists for
per-VM per-service hostname identification (e.g. rocky9-nginx-platform.test).

Key changes:
- run-tests-vm.sh: add setup_all_ips(), IP-specific Listen/bind directives
  with reset-before-apply pattern, graceful service availability checks
- run-e2e-test.sh: traffic VM architecture, all-ips mode, eth1 network,
  paired IP/SNI lists, updated cleanup for alias IPs
- generate-traffic.sh: parallel background jobs, curl-impersonate detection,
  auto source interface detection via ip route get, Host header in HTTP traffic
- Vagrantfile: add traffic VM with provision-traffic.sh
- provision-traffic.sh: install curl-impersonate and httpx for traffic gen
- test-rpm.sh: multi-interface TC check, updated ja4ebpf config
- clickhouse-init.sh: load CSV stubs for Anubis/bot-networks dictionaries
- Remove obsolete correlator/sentinel/mod-reqin-log docs
- Add h2_settings_ack column to http_logs schema
- Upgrade Go toolchain to 1.25.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jacquin Antoine
2026-04-16 14:25:24 +02:00
parent f0c8fe81c6
commit 36b5065a0a
17 changed files with 674 additions and 924 deletions

View File

@ -5,7 +5,7 @@
# Architecture :
# 3 VMs endpoint (centos8 / rocky9 / rocky10) : nginx + ja4ebpf
# 1 VM analysis (192.168.42.10) : ClickHouse + bot-detector + dashboard
# Host : orchestrateur + génération de trafic
# 1 VM traffic : curl-impersonate + httpx (génération de trafic externe)
#
# Pipeline testé :
# trafic host → endpoints → ja4ebpf → ClickHouse central →
@ -32,8 +32,9 @@ VM_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$VM_DIR/../.." && pwd)"
ANALYSIS_IP="192.168.42.10"
ENDPOINT_VMS="centos8 rocky9 rocky10"
ALL_VMS="centos8 rocky9 rocky10 analysis"
STACK="nginx"
TRAFFIC_VM="traffic"
ALL_VMS="centos8 rocky9 rocky10 analysis traffic"
STACK="all-ips"
# ── Paramètres par défaut (surchARGEABLES par CLI ou env) ──
TRAFFIC_COUNT="${TRAFFIC_COUNT:-500}"
@ -242,7 +243,7 @@ phase1_analysis() {
phase2_endpoints() {
echo ""
echo "╔══════════════════════════════════════════════════════════╗"
echo "║ Phase 2 : Endpoints (nginx + ja4ebpf → analysis CH) ║"
echo "║ Phase 2 : Endpoints (nginx+apache+hitch + ja4ebpf) ║"
echo "╚══════════════════════════════════════════════════════════╝"
echo ""
@ -251,38 +252,74 @@ phase2_endpoints() {
# Arrêter les services existants sur les endpoints (session précédente)
log "Arrêt des services existants sur les endpoints..."
for vm in $ENDPOINT_VMS; do
vagrant ssh "$vm" -- "sudo nginx -s stop 2>/dev/null; sudo pkill ja4ebpf 2>/dev/null; sudo pkill httpd 2>/dev/null; sudo pkill hitch 2>/dev/null; sudo pkill varnishd 2>/dev/null" 2>/dev/null || true
vagrant ssh "$vm" -- "sudo nginx -s stop 2>/dev/null; sudo pkill ja4ebpf 2>/dev/null; sudo pkill httpd 2>/dev/null; sudo pkill hitch 2>/dev/null; sudo pkill varnishd 2>/dev/null; sudo pkill -f 'TCPServer.*8080' 2>/dev/null; sudo pkill -f 'TCPServer.*:80' 2>/dev/null" 2>/dev/null || true
done
sleep 2
# Démarrer chaque endpoint en arrière-plan
# ja4ebpf pointe vers le ClickHouse de la VM analysis (CH_HOST=192.168.42.10)
PIDS=()
ENDPOINT_PIDS=()
for vm in $ENDPOINT_VMS; do
log "Démarrage $vm (nginx + ja4ebpf → ${ANALYSIS_IP})..."
vagrant ssh "$vm" -- "sudo rm -f /tmp/ja4ebpf-traffic-done" 2>/dev/null || true
vagrant ssh "$vm" -- "sudo CH_HOST=${ANALYSIS_IP} bash /ja4-platform/tests/vm/run-tests-vm.sh ${STACK} start" &
PIDS+=($!)
ENDPOINT_PIDS+=($!)
done
# Attendre que les services soient prêts
log "Attente démarrage des endpoints (30s)..."
sleep 30
log "Attente démarrage des endpoints (45s)..."
sleep 45
# Vérifier la connectivité HTTP de chaque endpoint
# Vérifier la connectivité de chaque endpoint (3 IPs × 2 ports)
# Les services sont sur le réseau ja4-e2e (eth1, 192.168.42.0/24)
for vm in $ENDPOINT_VMS; do
local vm_ip
vm_ip=$(vagrant ssh "$vm" -- 'ip -4 addr show eth0' 2>/dev/null \
local vm_ip1
vm_ip1=$(vagrant ssh "$vm" -- 'ip -4 addr show eth1' 2>/dev/null \
| awk '/inet / {sub(/\/.*/, "", $2); print $2; exit}')
if curl -sf "http://${vm_ip}/health" >/dev/null 2>&1; then
pass "$vm HTTP OK (${vm_ip}:80)"
else
warn "$vm HTTP injoignable (${vm_ip}:80)"
# Fallback eth0 si eth1 n'existe pas
if [ -z "$vm_ip1" ]; then
vm_ip1=$(vagrant ssh "$vm" -- 'ip -4 addr show eth0' 2>/dev/null \
| awk '/inet / {sub(/\/.*/, "", $2); print $2; exit}')
fi
if curl -sf -k "https://${vm_ip}/health" >/dev/null 2>&1; then
pass "$vm HTTPS OK (${vm_ip}:443)"
local np bl vm_ip2 vm_ip3
np=$(echo "$vm_ip1" | awk -F. '{print $1"."$2"."$3}')
bl=$(echo "$vm_ip1" | awk -F. '{print $4}')
# Même logique que setup_all_ips : base+50 et base+51
vm_ip2="${np}.$((bl + 50))"
vm_ip3="${np}.$((bl + 51))"
# nginx (IP1)
if curl -sf --connect-timeout 3 "http://${vm_ip1}/health" >/dev/null 2>&1; then
pass "$vm nginx:80 OK (${vm_ip1})"
else
warn "$vm HTTPS injoignable (${vm_ip}:443)"
warn "$vm nginx:80 injoignable (${vm_ip1})"
fi
if curl -sf -k --connect-timeout 3 "https://${vm_ip1}/health" >/dev/null 2>&1; then
pass "$vm nginx:443 OK (${vm_ip1})"
else
warn "$vm nginx:443 injoignable (${vm_ip1})"
fi
# apache (IP2)
if curl -sf --connect-timeout 3 "http://${vm_ip2}/health" >/dev/null 2>&1; then
pass "$vm apache:80 OK (${vm_ip2})"
else
warn "$vm apache:80 injoignable (${vm_ip2})"
fi
if curl -sf -k --connect-timeout 3 "https://${vm_ip2}/health" >/dev/null 2>&1; then
pass "$vm apache:443 OK (${vm_ip2})"
else
warn "$vm apache:443 injoignable (${vm_ip2})"
fi
# hitch+varnish (IP3)
if curl -sf --connect-timeout 3 "http://${vm_ip3}/health" >/dev/null 2>&1; then
pass "$vm hitch:80 OK (${vm_ip3})"
else
warn "$vm hitch:80 injoignable (${vm_ip3})"
fi
if curl -sf -k --connect-timeout 3 "https://${vm_ip3}/health" >/dev/null 2>&1; then
pass "$vm hitch:443 OK (${vm_ip3})"
else
warn "$vm hitch:443 injoignable (${vm_ip3})"
fi
done
}
@ -299,60 +336,97 @@ phase3_traffic() {
local total_ok=0
# Hostnames pour SNI (cert CN=platform.test, nginx accepte tout via server_name _)
local SNI_HOSTS_ALL=("platform.test" "api.platform.test" "www.platform.test" "app.platform.test")
local SNI_HOSTS=("${SNI_HOSTS_ALL[@]:0:${DNS_COUNT}}")
# Domaines pour SNI (cert CN=platform.test, nginx accepte tout via server_name _)
local DOMAIN_SUFFIXES_ALL=("platform.test" "api.platform.test" "www.platform.test" "app.platform.test")
local DOMAIN_SUFFIXES=("${DOMAIN_SUFFIXES_ALL[@]:0:${DNS_COUNT}}")
# ── Collecter les IPs de tous les endpoints ──
# ── Collecter les IPs de tous les endpoints (3 IPs par VM sur réseau ja4-e2e/eth1) ──
local -A VM_IPS_MAP
for vm in $ENDPOINT_VMS; do
VM_IPS_MAP[$vm]=$(vagrant ssh "$vm" -- 'ip -4 addr show eth0' 2>/dev/null \
local base_ip
base_ip=$(vagrant ssh "$vm" -- 'ip -4 addr show eth1' 2>/dev/null \
| awk '/inet / {sub(/\/.*/, "", $2); print $2; exit}')
# Fallback eth0
if [ -z "$base_ip" ]; then
base_ip=$(vagrant ssh "$vm" -- 'ip -4 addr show eth0' 2>/dev/null \
| awk '/inet / {sub(/\/.*/, "", $2); print $2; exit}')
fi
VM_IPS_MAP[$vm]="$base_ip"
# Calculer IP2 et IP3 (identique à setup_all_ips : base+50 et base+51)
local np bl
np=$(echo "$base_ip" | awk -F. '{print $1"."$2"."$3}')
bl=$(echo "$base_ip" | awk -F. '{print $4}')
VM_IPS_MAP["${vm}_ip2"]="${np}.$((bl + 50))"
VM_IPS_MAP["${vm}_ip3"]="${np}.$((bl + 51))"
done
# ── Ajouter des IPs alias sur chaque VM pour diversifier les sources ──
if [ "$SRC_IP_COUNT" -gt 1 ]; then
log "Ajout de ${SRC_IP_COUNT} IPs sources sur chaque VM..."
for vm in $ENDPOINT_VMS; do
local base_ip="${VM_IPS_MAP[$vm]}"
local net_prefix
net_prefix=$(echo "$base_ip" | awk -F. '{print $1"."$2"."$3}')
local base_last
base_last=$(echo "$base_ip" | awk -F. '{print $4}')
for i in $(seq 1 $((SRC_IP_COUNT - 1))); do
local alias_last=$((base_last + 100 + i))
[ "$alias_last" -gt 254 ] && alias_last=$((10 + i))
local alias_ip="${net_prefix}.${alias_last}"
vagrant ssh "$vm" -- "sudo ip addr add ${alias_ip}/24 dev eth0 2>/dev/null || true" 2>/dev/null || true
done
# ── Ajouter des IPs alias sur la VM traffic pour diversifier les sources ──
# Utiliser eth1 (réseau ja4-e2e, 192.168.42.x) car les cibles sont sur ce réseau.
local TRAFFIC_IP
TRAFFIC_IP=$(vagrant ssh "$TRAFFIC_VM" -- 'ip -4 addr show eth1' 2>/dev/null \
| awk '/inet / {sub(/\/.*/, "", $2); print $2; exit}')
# Fallback eth0 si eth1 n'existe pas
if [ -z "$TRAFFIC_IP" ]; then
TRAFFIC_IP=$(vagrant ssh "$TRAFFIC_VM" -- 'ip -4 addr show eth0' 2>/dev/null \
| awk '/inet / {sub(/\/.*/, "", $2); print $2; exit}')
fi
local TRAFFIC_IFACE
if [ -n "$TRAFFIC_IP" ]; then
case "$TRAFFIC_IP" in
192.168.42.*) TRAFFIC_IFACE="eth1" ;;
*) TRAFFIC_IFACE="eth0" ;;
esac
fi
if [ "$SRC_IP_COUNT" -gt 1 ] && [ -n "$TRAFFIC_IP" ]; then
log "Ajout de ${SRC_IP_COUNT} IPs sources sur ${TRAFFIC_VM} (${TRAFFIC_IFACE})..."
local net_prefix
net_prefix=$(echo "$TRAFFIC_IP" | awk -F. '{print $1"."$2"."$3}')
local base_last
base_last=$(echo "$TRAFFIC_IP" | awk -F. '{print $4}')
for i in $(seq 1 $((SRC_IP_COUNT - 1))); do
local alias_last=$((base_last + 100 + i))
[ "$alias_last" -gt 254 ] && alias_last=$((10 + i))
local alias_ip="${net_prefix}.${alias_last}"
vagrant ssh "$TRAFFIC_VM" -- "sudo ip addr add ${alias_ip}/24 dev ${TRAFFIC_IFACE} 2>/dev/null || true" 2>/dev/null || true
done
fi
# ── Construire les listes d'IPs cibles et SNI ──
# ── Construire les listes d'IPs cibles et SNI appariées ──
# Chaque entrée (VM, service, domaine) a un SNI unique : <vm>-<service>-<domaine>
# TARGET_IPS et SNI_HOSTS sont des listes parallèles de même longueur.
local TARGET_IPS=""
local SNI_HOSTS_STR=""
# Noms de services par clé IP
local SVC_NAMES_ip1="nginx" SVC_NAMES_ip2="apache" SVC_NAMES_ip3="hitch"
for target_vm in $ENDPOINT_VMS; do
TARGET_IPS="$TARGET_IPS ${VM_IPS_MAP[$target_vm]}"
local vm_base="${VM_IPS_MAP[$target_vm]}"
local vm_ip2="${VM_IPS_MAP[${target_vm}_ip2]}"
local vm_ip3="${VM_IPS_MAP[${target_vm}_ip3]}"
for ip_key in ip1 ip2 ip3; do
local svc_name_var="SVC_NAMES_${ip_key}"
local svc_name="${!svc_name_var}"
local map_key="${target_vm}_${ip_key}"
local target_ip="${VM_IPS_MAP[$map_key]:-$vm_base}"
for domain in "${DOMAIN_SUFFIXES[@]}"; do
local sni="${target_vm}-${svc_name}-${domain}"
TARGET_IPS="$TARGET_IPS $target_ip"
SNI_HOSTS_STR="$SNI_HOSTS_STR $sni"
done
done
done
TARGET_IPS=$(echo $TARGET_IPS)
local SNI_HOSTS_STR=""
for h in "${SNI_HOSTS[@]}"; do
SNI_HOSTS_STR="$SNI_HOSTS_STR $h"
done
SNI_HOSTS_STR=$(echo $SNI_HOSTS_STR)
log "Cibles : $(echo "$TARGET_IPS" | wc -w) paires IP/SNI ($(echo "$SNI_HOSTS_STR" | tr ' ' '\n' | sort -u | wc -l) uniques)"
# ── Synchroniser generate-traffic.sh vers les VMs ──
log "Synchronisation du script de trafic..."
for vm in $ENDPOINT_VMS; do
vagrant rsync "$vm" 2>&1 | tail -1
done
# ── Synchroniser generate-traffic.sh vers la VM traffic ──
log "Synchronisation du script de trafic vers ${TRAFFIC_VM}..."
vagrant rsync "$TRAFFIC_VM" 2>&1 | tail -1
# ── Écrire le config et lancer le trafic depuis chaque VM ──
for src_vm in $ENDPOINT_VMS; do
log "Génération depuis $src_vm : ${HTTPS_COUNT} HTTPS + ${HTTP_COUNT} HTTP (${SRC_IP_COUNT} IPs src)..."
# ── Écrire le config et lancer le trafic depuis la VM traffic ──
log "Génération depuis ${TRAFFIC_VM} : ${HTTPS_COUNT} HTTPS + ${HTTP_COUNT} HTTP..."
# Écrire le fichier de config sur la VM (heredoc quoté — pas d'expansion SSH)
vagrant ssh "$src_vm" -- "cat > /tmp/e2e-traffic.env << 'ENVEOF'
vagrant ssh "$TRAFFIC_VM" -- "cat > /tmp/e2e-traffic.env << 'ENVEOF'
export HITS=${HTTPS_COUNT}
export HITS_HTTP=${HTTP_COUNT}
export TARGET_IPS='${TARGET_IPS}'
@ -361,50 +435,46 @@ export TLS_FLAGS='${CURL_TLS_FLAGS}'
export SRC_IP_COUNT=${SRC_IP_COUNT}
ENVEOF"
# Lancer le générateur de trafic en arrière-plan
vagrant ssh "$src_vm" -- \
"source /tmp/e2e-traffic.env && bash /ja4-platform/tests/vm/generate-traffic.sh" \
> /tmp/e2e-traffic-${src_vm}.out 2>&1 &
# Lancer le générateur de trafic (curl-impersonate + curl)
vagrant ssh "$TRAFFIC_VM" -- \
"source /tmp/e2e-traffic.env && bash /ja4-platform/tests/vm/generate-traffic.sh" \
> /tmp/e2e-traffic.out 2>&1 &
# Attendre que le processus se termine (max 300s)
for i in $(seq 1 300); do
if [ -f /tmp/e2e-traffic.out ] && ! pgrep -f "vagrant ssh $TRAFFIC_VM.*generate-traffic" >/dev/null 2>&1; then
break
fi
sleep 1
done
local result
result=$(tail -1 /tmp/e2e-traffic.out 2>/dev/null || echo "0/${HTTPS_COUNT} 0/${HTTP_COUNT}")
# ── Collecter les résultats HTTPS + HTTP ──
for src_vm in $ENDPOINT_VMS; do
# Attendre que le processus se termine (max 300s)
for i in $(seq 1 300); do
if [ -f /tmp/e2e-traffic-${src_vm}.out ] && ! pgrep -f "vagrant ssh $src_vm.*generate-traffic" >/dev/null 2>&1; then
break
fi
sleep 1
done
local result
result=$(tail -1 /tmp/e2e-traffic-${src_vm}.out 2>/dev/null || echo "0/${HTTPS_COUNT} 0/${HTTP_COUNT}")
rm -f /tmp/e2e-traffic-${src_vm}.out 2>/dev/null
# Format: "ok_https/hits_https ok_http/hits_http"
local https_result http_result
https_result=$(echo "$result" | awk '{print $1}')
http_result=$(echo "$result" | awk '{print $2}')
local ok_https ok_http
ok_https=$(echo "$https_result" | cut -d/ -f1)
ok_http=$(echo "${http_result:-0/0}" | cut -d/ -f1)
# Format: "ok_https/hits_https ok_http/hits_http"
local https_result http_result
https_result=$(echo "$result" | awk '{print $1}')
http_result=$(echo "$result" | awk '{print $2}')
local ok_https ok_http
ok_https=$(echo "$https_result" | cut -d/ -f1)
ok_http=$(echo "${http_result:-0/0}" | cut -d/ -f1)
log " ${TRAFFIC_VM} HTTPS : ${https_result} HTTP : ${http_result:-0/0}"
total_ok=$((total_ok + ok_https + ok_http))
log " $src_vm HTTPS : ${https_result} HTTP : ${http_result:-0/0}"
total_ok=$((total_ok + ok_https + ok_http))
done
# ── HTTP/2 massif depuis la VM traffic si httpx est disponible ──
if vagrant ssh "$TRAFFIC_VM" -- 'python3 -c "import httpx"' 2>/dev/null; then
log "Génération HTTP/2 depuis ${TRAFFIC_VM} (${HTTPS_COUNT} requêtes, TLS=${TLS_VERSIONS}, DNS=${DNS_COUNT})..."
# ── HTTP/2 massif depuis les VMs si httpx est disponible ──
for src_vm in $ENDPOINT_VMS; do
if vagrant ssh "$src_vm" -- 'python3 -c "import httpx"' 2>/dev/null; then
local src_ip="${VM_IPS_MAP[$src_vm]}"
log "Génération HTTP/2 depuis $src_vm (${HTTPS_COUNT} requêtes, TLS=${TLS_VERSIONS}, DNS=${DNS_COUNT})..."
# Écrire le script httpx sur la VM (évite les problèmes d'échappement)
vagrant ssh "$src_vm" -- "cat > /tmp/e2e-h2-traffic.py << 'PYEOF'
# Écrire le script httpx sur la VM traffic
vagrant ssh "$TRAFFIC_VM" -- "cat > /tmp/e2e-h2-traffic.py << 'PYEOF'
import httpx, ssl as _ssl, warnings, random, os
warnings.filterwarnings('ignore')
paths = ['/', '/health', '/data', '/api/users', '/api/v1/status', '/login', '/api/search']
sni_hosts = os.environ.get('SNI_HOSTS', 'platform.test').split()
target_ips = os.environ.get('TARGET_IPS', '127.0.0.1').split()
# Les listes sont appariées : même index = même cible (vm-service-domaine)
assert len(sni_hosts) == len(target_ips), f'SNI_HOSTS ({len(sni_hosts)}) != TARGET_IPS ({len(target_ips)})'
targets = list(zip(target_ips, sni_hosts))
tls_versions = [v.strip() for v in os.environ.get('TLS_VERSIONS', '1.2,1.3').split(',')]
uas_browser = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/131.0.0.0 Safari/537.36',
@ -424,21 +494,21 @@ hits = int(os.environ.get('HITS', '100'))
with httpx.Client(http2=True, verify=ctx) as c:
for i in range(hits):
p = random.choice(paths)
target = random.choice(target_ips)
h = random.choice(sni_hosts)
target_ip, sni = random.choice(targets)
ua = random.choice(uas_browser if random.random() < 0.7 else uas_bot)
try:
c.get(f'https://{target}' + p, headers={'User-Agent': ua, 'Host': h})
c.get(f'https://{target_ip}' + p, headers={'User-Agent': ua, 'Host': sni})
except:
pass
PYEOF"
vagrant ssh "$src_vm" -- \
"source /tmp/e2e-traffic.env && TLS_VERSIONS='${TLS_VERSIONS}' python3 /tmp/e2e-h2-traffic.py" \
2>/dev/null || true
fi
done
pass "HTTP/2 généré depuis tous les endpoints"
vagrant ssh "$TRAFFIC_VM" -- \
"source /tmp/e2e-traffic.env && TLS_VERSIONS='${TLS_VERSIONS}' python3 /tmp/e2e-h2-traffic.py" \
2>/dev/null || true
pass "HTTP/2 généré depuis ${TRAFFIC_VM}"
else
warn "httpx non disponible sur ${TRAFFIC_VM} — HTTP/2 ignoré"
fi
pass "Trafic total : ${total_ok} requêtes réussies"
}
@ -489,7 +559,7 @@ phase4_wait() {
# Attendre les processus endpoint en arrière-plan
log "Attente fin des processus endpoint..."
for pid in "${PIDS[@]:-}"; do
for pid in "${ENDPOINT_PIDS[@]:-}"; do
wait "$pid" 2>/dev/null || true
done
}
@ -627,21 +697,25 @@ phase_summary() {
# Nettoyage
# ═════════════════════════════════════════════════════════════════════════════
cleanup() {
# Supprimer les IPs alias sur les VMs
# Supprimer les IPs alias sur la VM traffic (sur eth1, réseau ja4-e2e)
if [ "${SRC_IP_COUNT:-1}" -gt 1 ]; then
log "Suppression des IPs alias sur les VMs..."
for vm in $ENDPOINT_VMS; do
vagrant ssh "$vm" -- "
log "Suppression des IPs alias sur ${TRAFFIC_VM}..."
vagrant ssh "$TRAFFIC_VM" -- "
base_ip=\$(ip -4 addr show eth1 2>/dev/null | awk '/inet / {sub(/\/.*/, \"\", \\\$2); print \\\$2; exit}')
if [ -z \"\$base_ip\" ]; then
base_ip=\$(ip -4 addr show eth0 | awk '/inet / {sub(/\/.*/, \"\", \\\$2); print \\\$2; exit}')
net_prefix=\$(echo \$base_ip | awk -F. '{print \\\$1\".\"\\\$2\".\"\\\$3}')
base_last=\$(echo \$base_ip | awk -F. '{print \\\$4}')
for i in \$(seq 1 $((SRC_IP_COUNT - 1))); do
alias_last=\$((base_last + 100 + i))
[ \$alias_last -gt 254 ] && alias_last=\$((10 + i))
sudo ip addr del \${net_prefix}.\${alias_last}/24 dev eth0 2>/dev/null || true
done
" 2>/dev/null || true
done
iface=eth0
else
iface=eth1
fi
net_prefix=\$(echo \$base_ip | awk -F. '{print \\\$1\".\"\\\$2\".\"\\\$3}')
base_last=\$(echo \$base_ip | awk -F. '{print \\\$4}')
for i in \$(seq 1 $((SRC_IP_COUNT - 1))); do
alias_last=\$((base_last + 100 + i))
[ \$alias_last -gt 254 ] && alias_last=\$((10 + i))
sudo ip addr del \${net_prefix}.\${alias_last}/24 dev \$iface 2>/dev/null || true
done
" 2>/dev/null || true
fi
# Toujours arrêter les endpoints (sauf --keep global)
@ -649,7 +723,19 @@ cleanup() {
log "Nettoyage des endpoints..."
cd "$VM_DIR"
for vm in $ENDPOINT_VMS; do
vagrant ssh "$vm" -- "sudo pkill ja4ebpf 2>/dev/null; sudo nginx -s stop 2>/dev/null; sudo pkill httpd 2>/dev/null" 2>/dev/null || true
vagrant ssh "$vm" -- "sudo pkill ja4ebpf 2>/dev/null; sudo nginx -s stop 2>/dev/null; sudo pkill httpd 2>/dev/null; sudo pkill hitch 2>/dev/null; sudo pkill varnishd 2>/dev/null; sudo pkill -f 'TCPServer.*8080' 2>/dev/null; sudo pkill -f 'TCPServer.*:80' 2>/dev/null" 2>/dev/null || true
# Supprimer les IPs alias (IP2, IP3) sur eth1
local vm_base_ip
vm_base_ip=$(vagrant ssh "$vm" -- 'ip -4 addr show eth1' 2>/dev/null \
| awk '/inet / {sub(/\/.*/, "", $2); print $2; exit}')
if [ -n "$vm_base_ip" ]; then
local np bl ip2 ip3
np=$(echo "$vm_base_ip" | awk -F. '{print $1"."$2"."$3}')
bl=$(echo "$vm_base_ip" | awk -F. '{print $4}')
ip2="${np}.$((bl + 50))"
ip3="${np}.$((bl + 51))"
vagrant ssh "$vm" -- "sudo ip addr del ${ip2}/24 dev eth1 2>/dev/null || true; sudo ip addr del ${ip3}/24 dev eth1 2>/dev/null || true" 2>/dev/null || true
fi
done
fi
@ -668,9 +754,16 @@ cleanup() {
log "VMs endpoints conservées :"
for vm in $ENDPOINT_VMS; do
local vm_ip
vm_ip=$(vagrant ssh "$vm" -- 'ip -4 addr show eth0' 2>/dev/null \
vm_ip=$(vagrant ssh "$vm" -- 'ip -4 addr show eth1' 2>/dev/null \
| awk '/inet / {sub(/\/.*/, "", $2); print $2; exit}')
log " $vm : ${vm_ip}"
if [ -z "$vm_ip" ]; then
vm_ip=$(vagrant ssh "$vm" -- 'ip -4 addr show eth0' 2>/dev/null \
| awk '/inet / {sub(/\/.*/, "", $2); print $2; exit}')
fi
local np bl
np=$(echo "$vm_ip" | awk -F. '{print $1"."$2"."$3}')
bl=$(echo "$vm_ip" | awk -F. '{print $4}')
log " $vm : ${vm_ip} (nginx) ${np}.$((bl + 50)) (apache) ${np}.$((bl + 51)) (hitch+varnish)"
done
fi
}
@ -698,10 +791,20 @@ if [ "$UP_ONLY" = "true" ]; then
log "Bot-detector : http://${ANALYSIS_IP}:8080"
for vm in $ENDPOINT_VMS; do
local vm_ip
vm_ip=$(vagrant ssh "$vm" -- 'ip -4 addr show eth0' 2>/dev/null \
vm_ip=$(vagrant ssh "$vm" -- 'ip -4 addr show eth1' 2>/dev/null \
| awk '/inet / {sub(/\/.*/, "", $2); print $2; exit}')
log "$vm HTTP : http://${vm_ip}:80"
log "$vm HTTPS : https://${vm_ip}:443"
if [ -z "$vm_ip" ]; then
vm_ip=$(vagrant ssh "$vm" -- 'ip -4 addr show eth0' 2>/dev/null \
| awk '/inet / {sub(/\/.*/, "", $2); print $2; exit}')
fi
local np bl vm_ip2 vm_ip3
np=$(echo "$vm_ip" | awk -F. '{print $1"."$2"."$3}')
bl=$(echo "$vm_ip" | awk -F. '{print $4}')
vm_ip2="${np}.$((bl + 50))"
vm_ip3="${np}.$((bl + 51))"
log "$vm nginx : http://${vm_ip}:80 https://${vm_ip}:443"
log "$vm apache : http://${vm_ip2}:80 https://${vm_ip2}:443"
log "$vm hitch+varnish : http://${vm_ip3}:80 https://${vm_ip3}:443"
done
log ""
log "Pour générer du trafic :"