43 lines
1.6 KiB
Bash
Executable File
43 lines
1.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Measure what the nginx -> Traefik chain actually delivers to the application.
|
|
#
|
|
# docs/reverse-proxy-headers.md documents a single-hop nginx contract. The lab
|
|
# runs two hops, so the forwarded headers are measured rather than assumed.
|
|
# Run from anywhere that can resolve the lab hostnames.
|
|
#
|
|
# ./deploy/lab/scripts/measure-proxy-headers.sh
|
|
set -euo pipefail
|
|
|
|
HOST="${HOST:-app1.hyeonworks.com}"
|
|
URL="https://${HOST}/api/echo"
|
|
|
|
jqf() {
|
|
if command -v jq >/dev/null 2>&1; then jq "$@"; else python3 -m json.tool; fi
|
|
}
|
|
|
|
echo "=== 1. baseline: what the app sees for a normal request ==="
|
|
curl -s "$URL" | jqf '{
|
|
scheme, secure, serverName, serverPort, requestUrl, remoteAddr,
|
|
forwarded: .headers | with_entries(select(.key | startswith("x-forwarded") or . == "x-real-ip" or . == "forwarded"))
|
|
}' 2>/dev/null || curl -s "$URL"
|
|
|
|
echo
|
|
echo "=== 2. spoof test: client sends its own X-Forwarded-* ==="
|
|
echo " a trusted boundary must overwrite these, not append to them"
|
|
curl -s "$URL" \
|
|
-H 'X-Forwarded-For: 1.2.3.4' \
|
|
-H 'X-Forwarded-Proto: http' \
|
|
-H 'X-Forwarded-Host: evil.example.com' \
|
|
-H 'X-Real-IP: 1.2.3.4' \
|
|
| jqf '.headers | with_entries(select(.key | startswith("x-forwarded") or . == "x-real-ip"))' 2>/dev/null
|
|
|
|
echo
|
|
echo "=== 3. which pod answered (host nginx upstream distribution) ==="
|
|
for _ in 1 2 3 4; do
|
|
curl -s "$URL" | jqf -r '.headers["x-forwarded-server"] // "n/a"' 2>/dev/null
|
|
done
|
|
|
|
echo
|
|
echo "=== 4. plain HTTP is redirected, not proxied ==="
|
|
curl -s -o /dev/null -w ' http -> %{http_code} %{redirect_url}\n' "http://${HOST}/api/echo"
|