#!/usr/bin/env bash # ============================================================================= # generate-traffic.sh — Generate HTTPS/HTTP traffic from a VM endpoint # # Called by run-e2e-test.sh via: # vagrant ssh $vm -- "source /tmp/e2e-traffic.env && bash /ja4-platform/tests/vm/generate-traffic.sh" # # Environment variables (from /tmp/e2e-traffic.env): # HITS — Number of HTTPS requests (required) # HITS_HTTP — Number of HTTP requests (default: 0) # TARGET_IPS — Space-separated list of endpoint IPs (required) # SNI_HOSTS — Space-separated list of SNI hostnames (required) # TLS_FLAGS — curl TLS flags e.g. "--tlsv1.2 --tlsv1.3" (required) # SRC_IP_COUNT — Number of source IPs to rotate (default: 1) # ============================================================================= set -uo pipefail HITS="${HITS:-0}" HITS_HTTP="${HITS_HTTP:-0}" TARGET_IPS=(${TARGET_IPS:-}) SNI_HOSTS=(${SNI_HOSTS:-platform.test}) TLS_FLAGS="${TLS_FLAGS:---tlsv1.2 --tlsv1.3}" SRC_IP_COUNT="${SRC_IP_COUNT:-1}" if [ "$HITS" -eq 0 ] && [ "$HITS_HTTP" -eq 0 ]; then echo "0/0" exit 0 fi # ── Collect source IPs from eth0 ── SRC_IPS=($(ip -4 addr show eth0 2>/dev/null | awk '/inet / {sub(/\/.*/, "", $2); print $2}')) if [ ${#SRC_IPS[@]} -eq 0 ]; then echo "0/${HITS}" > /dev/stderr exit 1 fi # ── User-Agent pools ── UA_BROWSER=( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/131.0.0.0 Safari/537.36" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 Safari/605.1.15" "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0" ) UA_BOT=( "python-requests/2.32.3" "curl/8.9.1" "Go-http-client/2.0" "python-httpx/0.28.1" "Googlebot/2.1" ) PATHS=("/" "/health" "/data" "/api/users" "/api/v1/status" "/api/v1/metrics" \ "/login" "/logout" "/api/search" "/static/main.js" "/static/style.css" \ "/favicon.ico" "/robots.txt" "/sitemap.xml" "/api/v2/data" "/admin") ok=0 err=0 # ── HTTPS traffic ── if [ "$HITS" -gt 0 ]; then for i in $(seq 1 "$HITS"); do idx=$((i - 1)) target_ip="${TARGET_IPS[$((idx % ${#TARGET_IPS[@]}))]}" sni_host="${SNI_HOSTS[$((idx % ${#SNI_HOSTS[@]}))]}" path="${PATHS[$((idx % ${#PATHS[@]}))]}" # Rotate methods: GET(50%), POST(20%), PUT(10%), DELETE(10%), HEAD(10%) case $((i % 10)) in 0|1|2|3|4) method="GET" ;; 5|6) method="POST" ;; 7) method="PUT" ;; 8) method="DELETE" ;; 9) method="HEAD" ;; esac # 70% browser UA, 30% bot UA if [ $((i % 10)) -lt 7 ]; then ua="${UA_BROWSER[$((idx % ${#UA_BROWSER[@]}))]}" else ua="${UA_BOT[$((idx % ${#UA_BOT[@]}))]}" fi # Build curl flags resolve_flag="--resolve ${sni_host}:443:${target_ip}" extra_flags="${resolve_flag} ${TLS_FLAGS}" # Rotate source IPs if multiple are available if [ ${#SRC_IPS[@]} -gt 1 ] && [ "$SRC_IP_COUNT" -gt 1 ]; then src_ip="${SRC_IPS[$((idx % SRC_IP_COUNT))]}" if [ -n "$src_ip" ]; then extra_flags="${extra_flags} --interface ${src_ip}" fi fi case $method in POST) curl -sf -k ${extra_flags} -X POST "https://${sni_host}${path}" \ -H "User-Agent: ${ua}" -H "Content-Type: application/json" \ -d '{"test":1,"seq":'$i'}' \ --connect-timeout 5 --max-time 10 \ >/dev/null 2>&1 && ok=$((ok + 1)) || err=$((err + 1)) ;; PUT) curl -sf -k ${extra_flags} -X PUT "https://${sni_host}${path}" \ -H "User-Agent: ${ua}" \ --connect-timeout 5 --max-time 10 \ >/dev/null 2>&1 && ok=$((ok + 1)) || err=$((err + 1)) ;; DELETE) curl -sf -k ${extra_flags} -X DELETE "https://${sni_host}${path}" \ -H "User-Agent: ${ua}" \ --connect-timeout 5 --max-time 10 \ >/dev/null 2>&1 && ok=$((ok + 1)) || err=$((err + 1)) ;; HEAD) curl -sf -k ${extra_flags} -I "https://${sni_host}${path}" \ -H "User-Agent: ${ua}" \ --connect-timeout 5 --max-time 10 \ >/dev/null 2>&1 && ok=$((ok + 1)) || err=$((err + 1)) ;; *) curl -sf -k ${extra_flags} "https://${sni_host}${path}" \ -H "User-Agent: ${ua}" \ --connect-timeout 5 --max-time 10 \ >/dev/null 2>&1 && ok=$((ok + 1)) || err=$((err + 1)) ;; esac done fi # ── HTTP traffic (port 80) ── ok_http=0 if [ "$HITS_HTTP" -gt 0 ]; then for i in $(seq 1 "$HITS_HTTP"); do idx=$((i - 1)) # Round-robin across target IPs for HTTP too target_ip="${TARGET_IPS[$((idx % ${#TARGET_IPS[@]}))]}" path="${PATHS[$((idx % ${#PATHS[@]}))]}" # HTTP: use target_ip directly (no --resolve needed for HTTP) curl -sf "http://${target_ip}${path}" \ --connect-timeout 5 --max-time 10 \ >/dev/null 2>&1 && ok_http=$((ok_http + 1)) || true done fi # Output: HTTPS_ok/HTTPS_total HTTP_ok/HTTP_total echo "${ok}/${HITS} ${ok_http}/${HITS_HTTP}"