Aller au contenu
ZarexDocs

L'adresse IP du visiteur

Comment Zarex trouve la vraie adresse IP de vos visiteurs, comment la régler selon votre hébergement, et quand ne pas dépendre d'elle.

La limitation de débit, les filtres par IP ou par pays et la détection de bots utilisent l'adresse IP du visiteur. Cette page explique comment Zarex la trouve, et comment le régler.

Le principe

Votre serveur voit l'adresse de la machine qui se connecte directement à lui.

  • Rien entre le visiteur et votre serveur : cette adresse est celle du visiteur.
  • Un intermédiaire au milieu (nginx, Caddy, Cloudflare, Vercel…) : votre serveur voit l'adresse de l'intermédiaire. La vraie adresse du visiteur est écrite par l'intermédiaire dans un en-tête, par exemple X-Real-IP ou CF-Connecting-IP.

Or un visiteur peut lui aussi écrire ce qu'il veut dans un en-tête. L'option ipSource dit donc à Zarex où lire la vraie adresse, et à qui faire confiance. Elle ne bloque rien par elle-même.

Si l'adresse est mal déterminée

Soit tous vos visiteurs semblent venir de la même adresse (celle de votre proxy), et la limitation de débit les bloque ensemble ; soit un attaquant choisit son adresse, et contourne vos règles.

Les valeurs d'ipSource

ValeurQuand l'utiliser
"socket"Rien devant votre application : l'adresse de la connexion.
"framework"Laisser le framework calculer l'adresse (Express, Fastify, SvelteKit). Valeur par défaut de leurs SDK.
"vercel"Hébergé sur Vercel.
"fly"Hébergé sur Fly.io.
"cloudflare-workers"Votre code tourne dans un Cloudflare Worker (ou Pages).
"cloudflare"Derrière Cloudflare, devant votre serveur. L'en-tête n'est lu que si la connexion vient réellement de Cloudflare.
{ proxies: n }n proxys de confiance devant votre application.
{ trustedProxies: ["10.0.0.0/8"] }Les plages CIDR exactes de vos proxys.
{ header: "x-real-ip" }L'en-tête que votre proxy (nginx, Caddy…) écrit lui-même.
"auto"Détecter Vercel, Fly.io ou Cloudflare Workers.

Next.js : seulement les réglages par en-tête

Next.js ne donne jamais l'adresse de la connexion. "socket", "cloudflare", { proxies } et { trustedProxies } en ont besoin : avec Next.js, ils ne trouvent jamais l'adresse, et les requêtes passent sans être vérifiées. Avec Next.js, utilisez "vercel", "fly", "cloudflare-workers" ou { header }.

Si ipSource est omis

  • Express, Fastify, SvelteKit : l'adresse calculée par le framework est utilisée. Derrière un proxy, réglez le framework selon votre infrastructure (trust proxy pour Express, trustProxy pour Fastify, la configuration de l'adaptateur pour SvelteKit).
  • Next.js, Bun : Zarex détecte Vercel, Fly.io et Cloudflare Workers. Ailleurs, l'application refuse de démarrer, avec un message qui liste les options, plutôt que de deviner.

Par hébergement

HébergementNext.jsExpress, Fastify, SvelteKit, Bun
VercelRien à faireRien à faire (ou "vercel")
Fly.ioRien à faireRien à faire (ou "fly")
Cloudflare Workers / PagesRien à faire—
VPS sans proxyNon pris en charge : placez un proxy devant"socket" (ou le réglage par défaut du framework)
VPS avec nginx ou Caddy{ header: "x-real-ip" }{ proxies: 1 }, ou trust proxy / trustProxy réglé à 1 proxy
Cloudflare devant un VPS{ header: "cf-connecting-ip" }"cloudflare"

Avec votre propre proxy : { header }

Votre proxy écrit la vraie adresse dans un en-tête, et Zarex la lit.

/etc/nginx/sites-available/app
location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header X-Real-IP $remote_addr;
}
ipSource: { header: "x-real-ip" },

Si l'en-tête contient une liste (par exemple X-Forwarded-For), Zarex prend la dernière valeur : celle que votre proxy a ajoutée. Les valeurs précédentes peuvent venir du visiteur et sont ignorées.

Deux conditions de sécurité

  1. Le proxy doit écraser l'en-tête, pas le compléter : c'est ce que fait proxy_set_header X-Real-IP $remote_addr;.
  2. L'application ne doit être joignable que par le proxy : écoutez sur 127.0.0.1 ou fermez son port au public. Sinon, un visiteur qui contourne le proxy peut écrire l'en-tête lui-même et choisir son adresse.

Si l'en-tête est absent (requête qui n'est pas passée par le proxy), la requête passe sans être vérifiée, et le SDK l'écrit dans vos logs.

En local

En local, il n'y a pas de proxy : le visiteur, c'est vous, avec l'adresse 127.0.0.1 (ou ::1). Le pays apparaît comme inconnu (ZZ) : c'est normal.

  • Express, Fastify, SvelteKit, Bun : ça fonctionne sans réglage particulier ("socket" pour Bun).
  • Next.js : next dev ne fournit aucun en-tête d'adresse. Les requêtes passent donc sans être vérifiées, avec un avertissement dans les logs. Pour tester en local avec { header: "x-real-ip" }, ajoutez l'en-tête vous-même :
curl -H "X-Real-IP: 41.0.0.1" http://localhost:3000/api/produits

Ne dépendez pas que de l'adresse IP

Même bien réglée, une adresse IP ne désigne pas toujours une seule personne :

  • sur les réseaux mobiles, de nombreux abonnés partagent la même adresse publique ;
  • tous les appareils d'un même Wi-Fi (bureau, cybercafé, famille) sortent avec la même adresse.

Une limite par IP peut alors bloquer plusieurs personnes à cause d'une seule. Quand vous connaissez l'utilisateur, identifiez-le plutôt avec characteristics : la limite s'applique par compte, quelle que soit son adresse.

rules: [rateLimit({ max: 20, window: "1m", characteristics: ["userId"] })],
call: (req) => ({ characteristics: { userId: req.user?.id } }),

Vous pouvez utiliser n'importe quel identifiant stable : un identifiant de compte, une session, une clé d'API de votre propre service. Les valeurs sont hachées (SHA-256) avant d'être envoyées à Zarex. Voir Limitation de débit.

Sur cette page