Proxys de confiance

Lorsqu'OxPHP s'exécute derrière un reverse proxy (Ingress Kubernetes, Cloudflare, AWS ALB, nginx), chaque requête arrive depuis l'adresse IP du proxy. Sans configuration des proxys de confiance, la limitation de débit, la journalisation des accès et $_SERVER['REMOTE_ADDR'] voient tous l'IP du proxy au lieu de la véritable IP client.

Configuration

bash
# Comma-separated CIDR list TRUSTED_PROXIES="10.0.0.0/8,172.16.0.0/12,192.168.0.0/16" # Shorthand: all RFC-1918 + loopback + link-local (IPv4 and IPv6) TRUSTED_PROXIES="private"
Note

Lorsqu'elle n'est pas définie, OxPHP ignore tous les en-têtes de transfert. C'est la valeur par défaut sûre.

Fonctionnement

Lorsqu'une requête arrive depuis une IP de confiance, OxPHP inspecte les en-têtes de transfert par ordre de priorité :

  1. Forwarded (RFC 7239) — l'en-tête standardisé
  2. X-Forwarded-For / X-Forwarded-Proto / X-Forwarded-Host / X-Forwarded-Port — le repli de fait

Si l'en-tête Forwarded est présent, les en-têtes X-Forwarded-* sont ignorés.

Extraction de l'IP client

OxPHP utilise l'algorithme rightmost-non-trusted (le premier non fiable en partant de la droite) — la même approche que celle employée par nginx (real_ip_recursive on), Caddy, Traefik et Apache :

text
X-Forwarded-For: 203.0.113.50, 172.16.1.1, 10.0.0.5 TCP peer: 10.0.0.1 (trusted) Walk right-to-left: 10.0.0.5 → trusted → skip 172.16.1.1 → trusted → skip 203.0.113.50 → NOT trusted → client IP

Cela empêche l'usurpation via des valeurs ajoutées en tête de liste. Un attaquant peut ajouter de fausses IP à gauche, mais l'IP non fiable la plus à droite a été définie par le dernier proxy de confiance de la chaîne.

Ce qui change

Lorsque TRUSTED_PROXIES est configuré et que l'IP de connexion est de confiance :

Composant Sans proxys de confiance Avec proxys de confiance
$_SERVER['REMOTE_ADDR'] IP du proxy Véritable IP client
$_SERVER['REMOTE_PORT'] Port source du proxy Port client issu de Forwarded: for=ip:port, sinon 0
$_SERVER['HTTPS'] Selon la configuration TLS d'OxPHP Issu de Forwarded: proto= ou X-Forwarded-Proto
$_SERVER['REQUEST_SCHEME'] http ou https issu du TLS Issu du protocole transféré
$_SERVER['SERVER_NAME'] Issu de l'en-tête Host Issu de Forwarded: host= ou X-Forwarded-Host
$_SERVER['SERVER_PORT'] Issu de l'en-tête Host Issu de X-Forwarded-Port, sinon le port de X-Forwarded-Host / Forwarded: host=, sinon 443/80
Limitation de débit Par IP de proxy Par IP client
Journal d'accès IP du proxy Véritable IP client

REMOTE_PORT vaut 0 derrière un proxy, sauf si un nœud RFC 7239 Forwarded: for=ip:port transporte le port source du client. X-Forwarded-For n'a pas de champ port, la valeur réécrite ne peut donc pas être reconstituée et elle est mise à zéro plutôt que devinée.

Réseaux private

Le raccourci private inclut :

Réseau Description
10.0.0.0/8 Privé de classe A
172.16.0.0/12 Privé de classe B
192.168.0.0/16 Privé de classe C
127.0.0.0/8 Loopback
169.254.0.0/16 Link-local
::1/128 Loopback IPv6
fc00::/7 Unique local IPv6
fe80::/10 Link-local IPv6

Sécurité

  • Valeur par défaut sûre — sans TRUSTED_PROXIES, aucun en-tête de transfert n'est traité
  • Validation CIDR — des valeurs invalides dans TRUSTED_PROXIES provoquent une erreur au démarrage
  • Résistance à l'usurpation — l'algorithme rightmost-non-trusted ignore les valeurs ajoutées en tête par un attaquant
  • Les requêtes provenant d'IP non fiables voient leurs en-têtes de transfert entièrement ignorés

Voir aussi