mirror of
https://github.com/uk0/camostream.git
synced 2026-08-29 08:49:44 +00:00
- E2E test suite: TCP/UDP data integrity, AES-GCM, decoy injection, metrics - PCAP deep analysis: 7-dimension DPI resistance scoring (protocol, size, timing, entropy, RTP consistency, decoy coverage) - Docker Compose multi-container test environment - Traffic stealth analysis with tshark - Verified: 12/12 E2E tests pass, DPI score 81.9/100 with AES-GCM
373 lines
11 KiB
YAML
373 lines
11 KiB
YAML
version: "3.9"
|
|
|
|
volumes:
|
|
pcap-data:
|
|
test-results:
|
|
|
|
networks:
|
|
camotest:
|
|
driver: bridge
|
|
|
|
services:
|
|
# ── HTTP echo backend (TCP tunnel target) ──────────────────────
|
|
backend:
|
|
build:
|
|
context: ..
|
|
dockerfile: tests/Dockerfile
|
|
command: ["python3", "/opt/tests/backend/server.py"]
|
|
networks:
|
|
- camotest
|
|
expose:
|
|
- "8080"
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-sf", "http://127.0.0.1:8080/health"]
|
|
interval: 3s
|
|
timeout: 2s
|
|
retries: 10
|
|
start_period: 2s
|
|
|
|
# ── UDP echo backend (UDP tunnel target) ───────────────────────
|
|
backend-udp:
|
|
build:
|
|
context: ..
|
|
dockerfile: tests/Dockerfile
|
|
command: ["udp_server"]
|
|
networks:
|
|
- camotest
|
|
expose:
|
|
- "18081/udp"
|
|
healthcheck:
|
|
test: ["CMD", "true"]
|
|
interval: 5s
|
|
timeout: 2s
|
|
retries: 3
|
|
|
|
# ── CamoStream TCP Server ─────────────────────────────────────
|
|
camostream-server-tcp:
|
|
build:
|
|
context: ..
|
|
dockerfile: tests/Dockerfile
|
|
command:
|
|
- camostream
|
|
- -role=server
|
|
- -mode=tcp
|
|
- -listen=:39001
|
|
- -forward=backend:8080
|
|
- -bitrate-mbps=20
|
|
- -fps=60
|
|
- -decoy-rps=10
|
|
- -aes=0123456789abcdef0123456789abcdef
|
|
- -pcap=/data/pcap/tcp_server.pcap
|
|
- -pcap-max-mb=50
|
|
- -metrics=:9100
|
|
- -log=debug
|
|
- -showdrop
|
|
networks:
|
|
- camotest
|
|
expose:
|
|
- "39001"
|
|
- "9100"
|
|
volumes:
|
|
- pcap-data:/data/pcap
|
|
depends_on:
|
|
backend:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-sf", "http://127.0.0.1:9100/debug/vars"]
|
|
interval: 3s
|
|
timeout: 2s
|
|
retries: 10
|
|
start_period: 3s
|
|
|
|
# ── CamoStream TCP Client ─────────────────────────────────────
|
|
camostream-client-tcp:
|
|
build:
|
|
context: ..
|
|
dockerfile: tests/Dockerfile
|
|
command:
|
|
- camostream
|
|
- -role=client
|
|
- -mode=tcp
|
|
- -listen=:37001
|
|
- -server=camostream-server-tcp:39001
|
|
- -bitrate-mbps=20
|
|
- -fps=60
|
|
- -decoy-rps=10
|
|
- -aes=0123456789abcdef0123456789abcdef
|
|
- -pcap=/data/pcap/tcp_client.pcap
|
|
- -pcap-max-mb=50
|
|
- -metrics=:9101
|
|
- -log=debug
|
|
- -showdrop
|
|
networks:
|
|
- camotest
|
|
expose:
|
|
- "37001"
|
|
- "9101"
|
|
ports:
|
|
- "37001:37001"
|
|
volumes:
|
|
- pcap-data:/data/pcap
|
|
depends_on:
|
|
camostream-server-tcp:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-sf", "http://127.0.0.1:9101/debug/vars"]
|
|
interval: 3s
|
|
timeout: 2s
|
|
retries: 10
|
|
start_period: 3s
|
|
|
|
# ── CamoStream UDP Server ─────────────────────────────────────
|
|
camostream-server-udp:
|
|
build:
|
|
context: ..
|
|
dockerfile: tests/Dockerfile
|
|
command:
|
|
- camostream
|
|
- -role=server
|
|
- -mode=udp
|
|
- -wire=rtpish
|
|
- -listen=:39002
|
|
- -forward=backend-udp:18081
|
|
- -bitrate-mbps=20
|
|
- -fps=60
|
|
- -decoy-rps=10
|
|
- -rtcp-sr-rps=2
|
|
- -rtcp-rr-rps=3
|
|
- -rtpkeep-rps=4
|
|
- -stun-rps=1
|
|
- -aes=0123456789abcdef0123456789abcdef
|
|
- -pcap=/data/pcap/udp_server.pcap
|
|
- -pcap-max-mb=50
|
|
- -metrics=:9200
|
|
- -log=debug
|
|
- -showdrop
|
|
networks:
|
|
- camotest
|
|
expose:
|
|
- "39002/udp"
|
|
- "9200"
|
|
volumes:
|
|
- pcap-data:/data/pcap
|
|
depends_on:
|
|
backend-udp:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-sf", "http://127.0.0.1:9200/debug/vars"]
|
|
interval: 3s
|
|
timeout: 2s
|
|
retries: 10
|
|
start_period: 3s
|
|
|
|
# ── CamoStream UDP Client ─────────────────────────────────────
|
|
camostream-client-udp:
|
|
build:
|
|
context: ..
|
|
dockerfile: tests/Dockerfile
|
|
command:
|
|
- camostream
|
|
- -role=client
|
|
- -mode=udp
|
|
- -wire=rtpish
|
|
- -listen=:37002
|
|
- -server=camostream-server-udp:39002
|
|
- -bitrate-mbps=20
|
|
- -fps=60
|
|
- -decoy-rps=10
|
|
- -rtcp-sr-rps=2
|
|
- -rtcp-rr-rps=3
|
|
- -rtpkeep-rps=4
|
|
- -stun-rps=1
|
|
- -aes=0123456789abcdef0123456789abcdef
|
|
- -pcap=/data/pcap/udp_client.pcap
|
|
- -pcap-max-mb=50
|
|
- -metrics=:9201
|
|
- -log=debug
|
|
- -showdrop
|
|
networks:
|
|
- camotest
|
|
expose:
|
|
- "37002/udp"
|
|
- "9201"
|
|
ports:
|
|
- "37002:37002/udp"
|
|
volumes:
|
|
- pcap-data:/data/pcap
|
|
depends_on:
|
|
camostream-server-udp:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-sf", "http://127.0.0.1:9201/debug/vars"]
|
|
interval: 3s
|
|
timeout: 2s
|
|
retries: 10
|
|
start_period: 3s
|
|
|
|
# ── Network capture (sniff all traffic on camotest) ────────────
|
|
capture:
|
|
image: alpine:3.20
|
|
command:
|
|
- sh
|
|
- -c
|
|
- |
|
|
apk add --no-cache tcpdump >/dev/null 2>&1
|
|
echo "[capture] starting tcpdump on all interfaces..."
|
|
tcpdump -i any -w /data/pcap/camotest_full.pcap -s 0 -U
|
|
networks:
|
|
- camotest
|
|
cap_add:
|
|
- NET_RAW
|
|
- NET_ADMIN
|
|
volumes:
|
|
- pcap-data:/data/pcap
|
|
restart: unless-stopped
|
|
|
|
# ── Test runner ────────────────────────────────────────────────
|
|
test-runner:
|
|
build:
|
|
context: ..
|
|
dockerfile: tests/Dockerfile
|
|
command:
|
|
- bash
|
|
- -c
|
|
- |
|
|
echo "=== CamoStream Test Suite ==="
|
|
echo "Waiting for services to stabilize..."
|
|
sleep 3
|
|
|
|
PASS=0
|
|
FAIL=0
|
|
RESULTS=/data/results/report.txt
|
|
mkdir -p /data/results
|
|
|
|
echo "Test run started at $$(date -u)" | tee $$RESULTS
|
|
|
|
# ── Test 1: TCP tunnel end-to-end ──
|
|
echo -n "[TEST 1] TCP tunnel HTTP echo... " | tee -a $$RESULTS
|
|
RESP=$$(curl -sf --max-time 10 -X POST \
|
|
-H "Content-Type: text/plain" \
|
|
-d "hello-camostream-tcp" \
|
|
http://camostream-client-tcp:37001/test-tcp 2>&1)
|
|
if echo "$$RESP" | grep -q "hello-camostream-tcp"; then
|
|
echo "PASS" | tee -a $$RESULTS
|
|
PASS=$$((PASS+1))
|
|
else
|
|
echo "FAIL (response: $$RESP)" | tee -a $$RESULTS
|
|
FAIL=$$((FAIL+1))
|
|
fi
|
|
|
|
# ── Test 2: TCP tunnel multiple requests ──
|
|
echo -n "[TEST 2] TCP tunnel 10 sequential requests... " | tee -a $$RESULTS
|
|
TCP_OK=0
|
|
for i in $$(seq 1 10); do
|
|
R=$$(curl -sf --max-time 5 http://camostream-client-tcp:37001/seq-$$i 2>&1)
|
|
if echo "$$R" | grep -q "seq-$$i"; then
|
|
TCP_OK=$$((TCP_OK+1))
|
|
fi
|
|
done
|
|
if [ "$$TCP_OK" -eq 10 ]; then
|
|
echo "PASS ($$TCP_OK/10)" | tee -a $$RESULTS
|
|
PASS=$$((PASS+1))
|
|
else
|
|
echo "FAIL ($$TCP_OK/10)" | tee -a $$RESULTS
|
|
FAIL=$$((FAIL+1))
|
|
fi
|
|
|
|
# ── Test 3: TCP metrics endpoint ──
|
|
echo -n "[TEST 3] TCP server metrics available... " | tee -a $$RESULTS
|
|
METRICS=$$(curl -sf --max-time 5 http://camostream-server-tcp:9100/debug/vars 2>&1)
|
|
if echo "$$METRICS" | grep -q "bytes_up"; then
|
|
echo "PASS" | tee -a $$RESULTS
|
|
PASS=$$((PASS+1))
|
|
else
|
|
echo "FAIL" | tee -a $$RESULTS
|
|
FAIL=$$((FAIL+1))
|
|
fi
|
|
|
|
# ── Test 4: TCP client metrics endpoint ──
|
|
echo -n "[TEST 4] TCP client metrics available... " | tee -a $$RESULTS
|
|
METRICS=$$(curl -sf --max-time 5 http://camostream-client-tcp:9101/debug/vars 2>&1)
|
|
if echo "$$METRICS" | grep -q "bytes_up"; then
|
|
echo "PASS" | tee -a $$RESULTS
|
|
PASS=$$((PASS+1))
|
|
else
|
|
echo "FAIL" | tee -a $$RESULTS
|
|
FAIL=$$((FAIL+1))
|
|
fi
|
|
|
|
# ── Test 5: UDP server metrics endpoint ──
|
|
echo -n "[TEST 5] UDP server metrics available... " | tee -a $$RESULTS
|
|
METRICS=$$(curl -sf --max-time 5 http://camostream-server-udp:9200/debug/vars 2>&1)
|
|
if echo "$$METRICS" | grep -q "bytes_up"; then
|
|
echo "PASS" | tee -a $$RESULTS
|
|
PASS=$$((PASS+1))
|
|
else
|
|
echo "FAIL" | tee -a $$RESULTS
|
|
FAIL=$$((FAIL+1))
|
|
fi
|
|
|
|
# ── Test 6: UDP client metrics endpoint ──
|
|
echo -n "[TEST 6] UDP client metrics available... " | tee -a $$RESULTS
|
|
METRICS=$$(curl -sf --max-time 5 http://camostream-client-udp:9201/debug/vars 2>&1)
|
|
if echo "$$METRICS" | grep -q "bytes_up"; then
|
|
echo "PASS" | tee -a $$RESULTS
|
|
PASS=$$((PASS+1))
|
|
else
|
|
echo "FAIL" | tee -a $$RESULTS
|
|
FAIL=$$((FAIL+1))
|
|
fi
|
|
|
|
# ── Test 7: Decoy metrics are non-zero (TCP server) ──
|
|
echo -n "[TEST 7] Decoy injection active (TCP server)... " | tee -a $$RESULTS
|
|
sleep 5
|
|
METRICS=$$(curl -sf --max-time 5 http://camostream-server-tcp:9100/debug/vars 2>&1)
|
|
DECOY=$$(echo "$$METRICS" | grep -o '"shim_decoy_sent": [0-9]*' | grep -o '[0-9]*')
|
|
if [ -n "$$DECOY" ] && [ "$$DECOY" -gt 0 ]; then
|
|
echo "PASS (decoys sent: $$DECOY)" | tee -a $$RESULTS
|
|
PASS=$$((PASS+1))
|
|
else
|
|
echo "FAIL (decoy count: $$DECOY)" | tee -a $$RESULTS
|
|
FAIL=$$((FAIL+1))
|
|
fi
|
|
|
|
# ── Test 8: PCAP files created ──
|
|
echo -n "[TEST 8] PCAP files generated... " | tee -a $$RESULTS
|
|
PCAP_COUNT=$$(ls /data/pcap/*.pcap 2>/dev/null | wc -l)
|
|
if [ "$$PCAP_COUNT" -ge 4 ]; then
|
|
echo "PASS ($$PCAP_COUNT pcap files)" | tee -a $$RESULTS
|
|
PASS=$$((PASS+1))
|
|
else
|
|
echo "FAIL (only $$PCAP_COUNT pcap files)" | tee -a $$RESULTS
|
|
FAIL=$$((FAIL+1))
|
|
fi
|
|
|
|
# ── Summary ──
|
|
echo "" | tee -a $$RESULTS
|
|
echo "=== Results: $$PASS passed, $$FAIL failed ===" | tee -a $$RESULTS
|
|
echo "Test run finished at $$(date -u)" | tee -a $$RESULTS
|
|
|
|
# Copy pcap listing to results
|
|
ls -lh /data/pcap/*.pcap >> $$RESULTS 2>/dev/null
|
|
|
|
if [ "$$FAIL" -gt 0 ]; then
|
|
exit 1
|
|
fi
|
|
exit 0
|
|
networks:
|
|
- camotest
|
|
volumes:
|
|
- pcap-data:/data/pcap
|
|
- test-results:/data/results
|
|
depends_on:
|
|
camostream-client-tcp:
|
|
condition: service_healthy
|
|
camostream-client-udp:
|
|
condition: service_healthy
|
|
camostream-server-tcp:
|
|
condition: service_healthy
|
|
camostream-server-udp:
|
|
condition: service_healthy
|
|
capture:
|
|
condition: service_started
|