Noms des sites configurables (poc_fqdn_suffix) : www-bwpoc.vlab.bzh, un seul niveau sous le wildcard Traefik

Tests : 26 OK, 0 KO.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
cedricandClaude Opus 5.5 committed 2026-10-27 15:59:35 +01:00
1 parent 04c8081215
commit e395fae4c6
8 files changed
+33 -27

No files matched your search

+15 -14
View File
@@ -10,7 +10,7 @@
# --only ne lance que les tests dont le titre contient <motif>
#
# Variables (fichier bwpoc-tests.env à côté du script, ou environnement) :
# WAF_IP, DOMAIN, APPS_IP, PORT_WWW, PORT_SHOP, PORT_API
# WAF_IP, DOMAIN, SUFFIX, APPS_IP, PORT_WWW, PORT_SHOP, PORT_API
#
# ATTENTION : les derniers tests provoquent volontairement le
# bannissement de votre IP sur api.<domaine> (BAD_BEHAVIOR_BAN_TIME).
@@ -23,6 +23,7 @@ SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)"
WAF_IP="${WAF_IP:?WAF_IP non défini (bwpoc-tests.env ou environnement)}"
DOMAIN="${DOMAIN:-bwpoc.internal}"
SUFFIX="${SUFFIX:-.$DOMAIN}" # nom complet d'un site = <site>$SUFFIX
APPS_IP="${APPS_IP:-}"
PORT_SHOP="${PORT_SHOP:-8082}"
PORT_API="${PORT_API:-8083}"
@@ -48,8 +49,8 @@ UA="Mozilla/5.0 (X11; Linux x86_64) bwpoc-tests"
waf() {
local host="$1" path="$2"; shift 2
curl -sk -o /dev/null -w '%{http_code} %{redirect_url}' --max-time 10 \
--resolve "$host.$DOMAIN:443:$WAF_IP" --resolve "$host.$DOMAIN:80:$WAF_IP" \
-A "$UA" "$@" "https://$host.$DOMAIN$path"
--resolve "$host$SUFFIX:443:$WAF_IP" --resolve "$host$SUFFIX:80:$WAF_IP" \
-A "$UA" "$@" "https://$host$SUFFIX$path"
}
# Vérifie qu'un code fait partie de la liste attendue (séparateur |)
@@ -88,32 +89,32 @@ if [ "$DIRECT" -eq 1 ]; then
exit 0
fi
echo "${B}PoC BunkerWeb${N} : WAF $WAF_IP, domaine $DOMAIN"
echo "${B}PoC BunkerWeb${N} : WAF $WAF_IP, sites <site>$SUFFIX"
section "Transport et socle"
check "HTTP redirigé vers HTTPS (api)" "301|302|307|308" \
"$(curl -s -o /dev/null -w '%{http_code}' --max-time 10 --resolve "api.$DOMAIN:80:$WAF_IP" "http://api.$DOMAIN/get")"
"$(curl -s -o /dev/null -w '%{http_code}' --max-time 10 --resolve "api$SUFFIX:80:$WAF_IP" "http://api$SUFFIX/get")"
check "Host inconnu refusé (DISABLE_DEFAULT_SERVER)" "000|400|403|404|444" \
"$(curl -sk -o /dev/null -w '%{http_code}' --max-time 10 --resolve "inconnu.$DOMAIN:443:$WAF_IP" "https://inconnu.$DOMAIN/")"
"$(curl -sk -o /dev/null -w '%{http_code}' --max-time 10 --resolve "inconnu$SUFFIX:443:$WAF_IP" "https://inconnu$SUFFIX/")"
check "Requête légitime sur l'API" "200" "$(waf api /get)"
section "En-têtes et compression"
HDRS=$(curl -sk -D - -o /dev/null --max-time 10 --resolve "api.$DOMAIN:443:$WAF_IP" -A "$UA" "https://api.$DOMAIN/get" | tr -d '\r' | tr 'A-Z' 'a-z')
HDRS=$(curl -sk -D - -o /dev/null --max-time 10 --resolve "api$SUFFIX:443:$WAF_IP" -A "$UA" "https://api$SUFFIX/get" | tr -d '\r' | tr 'A-Z' 'a-z')
for h in strict-transport-security x-frame-options x-content-type-options content-security-policy referrer-policy; do
if grep -q "^$h:" <<<"$HDRS"; then check "En-tête $h ajouté" "yes" "yes"; else check "En-tête $h ajouté" "yes" "no"; fi
done
if grep -q "^server:" <<<"$HDRS"; then check "En-tête Server masqué" "masqué" "présent" info; else check "En-tête Server masqué" "masqué" "masqué"; fi
XFF=$(curl -sk --max-time 10 --resolve "api.$DOMAIN:443:$WAF_IP" -A "$UA" "https://api.$DOMAIN/headers" | jq -r '.headers["X-Forwarded-For"][0] // empty' 2>/dev/null)
XFF=$(curl -sk --max-time 10 --resolve "api$SUFFIX:443:$WAF_IP" -A "$UA" "https://api$SUFFIX/headers" | jq -r '.headers["X-Forwarded-For"][0] // empty' 2>/dev/null)
if [ -n "$XFF" ]; then check "Le backend reçoit X-Forwarded-For ($XFF)" "yes" "yes"; else check "Le backend reçoit X-Forwarded-For" "yes" "no"; fi
for enc in br gzip; do
CE=$(curl -sk -D - -o /dev/null --max-time 10 -H "Accept-Encoding: $enc" --resolve "api.$DOMAIN:443:$WAF_IP" -A "$UA" "https://api.$DOMAIN/html" \
CE=$(curl -sk -D - -o /dev/null --max-time 10 -H "Accept-Encoding: $enc" --resolve "api$SUFFIX:443:$WAF_IP" -A "$UA" "https://api$SUFFIX/html" \
| tr -d '\r' | awk -F': ' 'tolower($1)=="content-encoding"{print $2}')
check "Compression $enc" "$enc" "${CE:-aucune}"
done
section "Antibot (www)"
RES=$(waf www /)
if [[ "$RES" == *challenge* ]] || [[ "${RES%% *}" == 200 && $(curl -sk --max-time 10 --resolve "www.$DOMAIN:443:$WAF_IP" "https://www.$DOMAIN/" | grep -ci challenge) -gt 0 ]]; then
if [[ "$RES" == *challenge* ]] || [[ "${RES%% *}" == 200 && $(curl -sk --max-time 10 --resolve "www$SUFFIX:443:$WAF_IP" "https://www$SUFFIX/" | grep -ci challenge) -gt 0 ]]; then
check "Un client sans JavaScript reste bloqué sur /challenge" "yes" "yes"
else
check "Un client sans JavaScript reste bloqué sur /challenge" "yes" "no ($RES)"
@@ -135,12 +136,12 @@ section "Contraintes protocolaires (api)"
check "Méthode PUT interdite (ALLOWED_METHODS)" "405" "$(waf api /put -X PUT -d x=1)"
check "Corps de 2 Mo refusé (MAX_CLIENT_SIZE=1m)" "413" \
"$(head -c 2097152 /dev/zero | tr '\0' 'a' | curl -sk -o /dev/null -w '%{http_code}' --max-time 20 \
--resolve "api.$DOMAIN:443:$WAF_IP" -A "$UA" -H 'Content-Type: text/plain' --data-binary @- "https://api.$DOMAIN/post")"
--resolve "api$SUFFIX:443:$WAF_IP" -A "$UA" -H 'Content-Type: text/plain' --data-binary @- "https://api$SUFFIX/post")"
section "Limitation de débit puis bad behavior (api)"
echo " Envoi de 40 requêtes en parallèle (LIMIT_REQ_RATE=5r/s)..."
CODES=$(seq 1 40 | xargs -P 20 -I{} curl -sk -o /dev/null -w '%{http_code}\n' --max-time 10 \
--resolve "api.$DOMAIN:443:$WAF_IP" -A "$UA" "https://api.$DOMAIN/get?n={}" | sort | uniq -c | tr '\n' ' ')
--resolve "api$SUFFIX:443:$WAF_IP" -A "$UA" "https://api$SUFFIX/get?n={}" | sort | uniq -c | tr '\n' ' ')
echo " Répartition des codes : $CODES"
if grep -qE '\b429\b' <<<"$CODES"; then check "Des requêtes ont été limitées (429)" "yes" "yes"; else check "Des requêtes ont été limitées (429)" "yes" "no"; fi
echo " Envoi de 12 requêtes en erreur 404 (BAD_BEHAVIOR_THRESHOLD=10)..."
@@ -151,10 +152,10 @@ check "Bannissement limité au service api (shop répond)" "200" "$(waf shop /)"
# ---------------------------------------------------------------------
printf '\n%sBilan%s : %s%d OK%s, %s%d KO%s, %d info\n' "$B" "$N" "$G" "$PASS" "$N" "$R" "$FAIL" "$N" "$INFO"
MYIP=$(curl -sk --max-time 5 --resolve "shop.$DOMAIN:443:$WAF_IP" -A "$UA" -o /dev/null -w '%{local_ip}' "https://shop.$DOMAIN/")
MYIP=$(curl -sk --max-time 5 --resolve "shop$SUFFIX:443:$WAF_IP" -A "$UA" -o /dev/null -w '%{local_ip}' "https://shop$SUFFIX/")
cat <<EOF
Votre IP ($MYIP) est bannie de api.$DOMAIN pendant BAD_BEHAVIOR_BAN_TIME.
Votre IP ($MYIP) est bannie de api$SUFFIX pendant BAD_BEHAVIOR_BAN_TIME.
Pour lever le bannissement : UI BunkerWeb, menu Bans, ou sur la VM WAF :
docker exec bw-scheduler bwcli unban $MYIP
EOF