API de détection VPN et proxy : signaler les abus sans bloquer les utilisateurs
Détectez les connexions VPN, proxy, Tor et centre de données avec une seule requête POST. Comprend le middleware Next.js, la limitation du débit Express et des exemples de notation de fraude.
Votre application SaaS propose un essai gratuit par utilisateur. Les utilisateurs s'inscrivent, activent un VPN et se réinscrivent. Les abus promotionnels vous coûtent des revenus et faussent vos mesures de conversion. Vous devez signaler VPN et proxy connexions au moment de l’inscription.
Ce guide couvre le botoi POST /v1/vpn-detect point final : ce qu'il renvoie, comment
l'intégrer dans les applications Next.js et Express, comment le combiner avec d'autres signaux de fraude et où
cela ne suffit pas.
Le point final
Une requête POST avec une adresse IP dans le corps. Aucun en-tête spécial, aucune clé API requise pour accès anonyme.
curl -X POST https://api.botoi.com/v1/vpn-detect \\
-H "Content-Type: application/json" \\
-d '{ "ip": "185.220.101.1" }'
Réponse pour un nœud de sortie Tor connu :
{
"success": true,
"data": {
"ip": "185.220.101.1",
"is_vpn": true,
"is_proxy": false,
"is_tor": true,
"is_datacenter": false,
"provider": null,
"risk_score": 90,
"checks": {
"tor": true,
"datacenter": false,
"suspicious_hostname": false
}
}
}
Réponse pour une IP résidentielle propre :
{
"success": true,
"data": {
"ip": "73.162.45.118",
"is_vpn": false,
"is_proxy": false,
"is_tor": false,
"is_datacenter": false,
"provider": null,
"risk_score": 0,
"checks": {
"tor": false,
"datacenter": false,
"suspicious_hostname": false
}
}
}
Champs de réponse
- est_vpn (booléen) : vrai si l'adresse IP appartient à une plage de centres de données connue ou si elle possède un nom d'hôte DNS inversé suspect contenant des mots-clés liés au VPN.
- est_proxy (booléen) : vrai si le nom d'hôte DNS inversé suggère un serveur proxy.
- is_tor (booléen) : Vrai si l'adresse IP correspond à un nœud de sortie Tor connu.
- est_datacenter (booléen) : vrai si l'adresse IP se situe dans les plages CIDR AWS, Google Cloud, Azure, DigitalOcean ou Linode.
- fournisseuse (chaîne ou null) : le nom du fournisseur de cloud lorsque
is_datacenterest vrai. Null pour les IP résidentielles et Tor. - score_risque (nombre, 0-100) : les connexions Tor obtiennent un score de 90, les adresses IP des centres de données un score de 60, les noms d'hôtes suspects un score de 40. Les adresses IP résidentielles propres obtiennent un score de 0.
- chèques (objet) : Répartition des méthodes de détection déclenchées, pour le débogage.
Signaler les utilisateurs VPN lors de l'inscription avec le middleware Next.js
Ce middleware intercepte les requêtes POST sur votre itinéraire d'inscription, vérifie l'adresse IP de l'appelant par rapport à l'adresse IP de l'appelant. API de détection VPN et attache un en-tête à la demande lorsqu'un VPN est détecté. Votre gestionnaire d'inscription lit l'en-tête et décide quoi faire : exiger une vérification de l'e-mail, ajouter un indicateur de révision manuelle ou réduire la période d'essai.
import { NextRequest, NextResponse } from 'next/server';
const VPN_DETECT_URL = 'https://api.botoi.com/v1/vpn-detect';
export async function middleware(req: NextRequest) {
if (req.method !== 'POST') {
return NextResponse.next();
}
const ip = req.headers.get('x-forwarded-for')?.split(',')[0]?.trim()
|| req.ip
|| '127.0.0.1';
try {
const res = await fetch(VPN_DETECT_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ip }),
signal: AbortSignal.timeout(3000),
});
const { data } = await res.json();
if (data.is_vpn || data.is_tor || data.is_proxy) {
// Add a header so your signup handler can flag the account
const response = NextResponse.next();
response.headers.set('x-vpn-detected', 'true');
response.headers.set('x-vpn-risk-score', String(data.risk_score));
return response;
}
} catch {
// Fail open: if the API is unreachable, let the request through
console.warn('VPN detection check failed, allowing request');
}
return NextResponse.next();
}
export const config = {
matcher: ['/api/auth/signup', '/api/auth/register'],
};
Le middleware ne bloque pas l'inscription. Il transmet un signal à votre gestionnaire. C'est le droit approche car le trafic VPN ne constitue pas une preuve de fraude. Un utilisateur sur un VPN d'entreprise ou en voyage via un réseau restrictif est un client légitime.
Limites de débit plus strictes pour les IP VPN dans Express
Si vous exécutez une API, vous pouvez appliquer des limites de débit plus strictes aux connexions VPN et proxy sans bloquer eux carrément. Ce middleware donne aux utilisateurs standards 100 requêtes par heure et aux utilisateurs VPN 20.
import type { Request, Response, NextFunction } from 'express';
const VPN_DETECT_URL = 'https://api.botoi.com/v1/vpn-detect';
const BOTOI_API_KEY = process.env.BOTOI_API_KEY;
// Standard limits
const STANDARD_LIMIT = 100; // requests per hour
const VPN_LIMIT = 20; // requests per hour for VPN users
const requestCounts = new Map<string, { count: number; resetAt: number }>();
export async function vpnAwareRateLimit(
req: Request,
res: Response,
next: NextFunction
) {
const ip = req.headers['x-forwarded-for']?.toString().split(',')[0]?.trim()
|| req.socket.remoteAddress
|| 'unknown';
let isVpn = false;
try {
const vpnRes = await fetch(VPN_DETECT_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': \`Bearer \${BOTOI_API_KEY}\`,
},
body: JSON.stringify({ ip }),
signal: AbortSignal.timeout(2000),
});
const { data } = await vpnRes.json();
isVpn = data.is_vpn || data.is_tor || data.is_proxy;
} catch {
// Fail open: use standard limits if detection fails
}
const limit = isVpn ? VPN_LIMIT : STANDARD_LIMIT;
const now = Date.now();
const entry = requestCounts.get(ip);
if (!entry || entry.resetAt < now) {
requestCounts.set(ip, { count: 1, resetAt: now + 3600_000 });
res.setHeader('X-RateLimit-Limit', limit);
return next();
}
entry.count++;
if (entry.count > limit) {
return res.status(429).json({
error: 'Rate limit exceeded',
retryAfter: Math.ceil((entry.resetAt - now) / 1000),
});
}
res.setHeader('X-RateLimit-Limit', limit);
res.setHeader('X-RateLimit-Remaining', limit - entry.count);
next();
}
Le rapport de 5 : 1 entre les limites standard et VPN est un point de départ. Ajustez-le en fonction de votre abus modèles. Si votre API gère les paiements ou les modifications de compte, des limites VPN plus strictes sont logiques. Pour les points de terminaison en lecture seule, vous n’aurez peut-être pas du tout besoin de limites différentielles.
Scoring de fraude : combinez la détection VPN avec d’autres signaux
La détection VPN à elle seule constitue un faible signal de fraude. Un VPN + email jetable + nouveau compte + échec les tentatives de paiement sont un signal fort. Cette fonction combine plusieurs entrées en une seule fraude score.
interface FraudSignals {
vpnDetected: boolean;
riskScore: number;
disposableEmail: boolean;
accountAge: number; // days
failedPayments: number;
}
function calculateFraudScore(signals: FraudSignals): number {
let score = 0;
// VPN/proxy risk contributes up to 30 points
if (signals.vpnDetected) {
score += Math.round(signals.riskScore * 0.3);
}
// Disposable email: strong signal
if (signals.disposableEmail) {
score += 35;
}
// New account + VPN is a red flag
if (signals.accountAge < 1 && signals.vpnDetected) {
score += 20;
}
// Failed payment history
score += Math.min(signals.failedPayments * 10, 30);
return Math.min(score, 100);
}
async function assessSignupRisk(ip: string, email: string) {
const [vpnRes, emailRes] = await Promise.all([
fetch('https://api.botoi.com/v1/vpn-detect', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ip }),
}),
fetch('https://api.botoi.com/v1/disposable-email/check', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email }),
}),
]);
const vpnData = (await vpnRes.json()).data;
const emailData = (await emailRes.json()).data;
const fraudScore = calculateFraudScore({
vpnDetected: vpnData.is_vpn || vpnData.is_tor,
riskScore: vpnData.risk_score,
disposableEmail: emailData.is_disposable,
accountAge: 0, // new signup
failedPayments: 0,
});
return {
fraudScore,
action: fraudScore > 70 ? 'block' : fraudScore > 40 ? 'review' : 'allow',
details: {
vpn: vpnData.is_vpn,
tor: vpnData.is_tor,
proxy: vpnData.is_proxy,
disposableEmail: emailData.is_disposable,
},
};
}
Les deux appels d'API s'exécutent en parallèle, de sorte que la latence totale est la plus lente des deux (généralement sous
100 ms). Le action Le champ vous propose trois niveaux : autoriser, vérifier ou bloquer. Pour les partitions
entre 40 et 70, acheminez l'inscription vers une file d'attente de révision manuelle plutôt que de la rejeter automatiquement.
Mise en cache pour réduire les appels d'API
Une adresse IP ne change pas son statut VPN à chaque demande. Cachez le résultat pendant 10 minutes pour réduisez votre utilisation de l'API sans manquer de changements de statut.
const vpnCache = new Map<string, { result: VpnResult; expiresAt: number }>();
const CACHE_TTL = 10 * 60 * 1000; // 10 minutes
interface VpnResult {
isVpn: boolean;
isTor: boolean;
isProxy: boolean;
riskScore: number;
}
async function checkVpn(ip: string): Promise<VpnResult> {
const cached = vpnCache.get(ip);
if (cached && cached.expiresAt > Date.now()) {
return cached.result;
}
try {
const res = await fetch('https://api.botoi.com/v1/vpn-detect', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ip }),
signal: AbortSignal.timeout(3000),
});
const { data } = await res.json();
const result: VpnResult = {
isVpn: data.is_vpn,
isTor: data.is_tor,
isProxy: data.is_proxy,
riskScore: data.risk_score,
};
vpnCache.set(ip, { result, expiresAt: Date.now() + CACHE_TTL });
return result;
} catch {
return { isVpn: false, isTor: false, isProxy: false, riskScore: 0 };
}
}
Pour les déploiements multi-serveurs, remplacez la carte en mémoire par Redis ou Upstash. La même clé de cache (adresse IP) et le modèle TTL s'appliquent.
Ce que cette API ne peut pas détecter
L’honnêteté concernant les limites compte plus qu’un argumentaire de vente soigné. Voici où se trouve la détection VPN échoue.
- VPN résidentiels. Services comme iCloud Private Relay et certaines configurations de Mullvad achemine le trafic via des adresses IP résidentielles. Ces adresses IP semblent identiques à connexions Internet régulières à domicile. Aucune détection basée sur le DNS inversé ou le CIDR ne les détecte.
-
NAT de l'opérateur mobile. Les opérateurs de téléphonie mobile utilisent un NAT de niveau opérateur, ce qui signifie
des milliers d'utilisateurs partagent une seule adresse IP. Le signalement de ces adresses IP affecte les utilisateurs légitimes.
L'API peut renvoyer
is_datacenter: falseetrisk_score: 0pour ceux-là IP même lorsqu'un utilisateur VPN est derrière eux. - Proxy SOCKS5 privés. Proxies hébergés sur des serveurs personnels avec résidentiel Les FAI n'apparaissent pas dans les plages CIDR des centres de données et n'ont pas de noms d'hôtes suspects. Ils sont invisible à la détection automatisée.
- Connexions IPv6 uniquement. Le point de terminaison actuel prend uniquement en charge les adresses IPv4. La détection VPN IPv6 n'est pas disponible.
-
Faux positifs sur l'hébergement mutualisé. Un développeur exécutant un projet parallèle sur un
La gouttelette DigitalOcean se déclenchera
is_datacenter: true. Cela ne veut pas dire qu'ils sont cachant leur identité.
La détection fonctionne bien pour les fournisseurs VPN commerciaux (NordVPN, ExpressVPN, Surfshark, CyberGhost) et le trafic Tor. Il détecte la plupart des proxys hébergés dans les centres de données. Il ne capte pas les VPN résidentiels ou procurations privées. Attendez-vous à une détection de 80 à 90 % pour les cas courants et à près de zéro pour les cas extrêmes.
Signalez, ne bloquez pas
Bloquer purement et simplement les utilisateurs VPN est une erreur pour la plupart des applications. Voici pourquoi :
- Les utilisateurs soucieux de leur confidentialité et n’ayant pas l’intention d’abuser de votre service utilisent des VPN par défaut.
- Les employés utilisant des VPN d'entreprise acheminent tout leur trafic via l'infrastructure de l'entreprise.
- Les utilisateurs des pays soumis à des restrictions Internet s’appuient sur les VPN pour accéder à votre produit.
- Les journalistes, militants et chercheurs en sécurité utilisent Tor pour des raisons légitimes.
La bonne approche : ajouter un indicateur de risque au compte, exiger une vérification supplémentaire (e-mail confirmation, numéro de téléphone, mode de paiement) ou acheminer l'inscription vers une file d'attente de révision. Laissez les humains prendre la décision finale dans les cas ambigus.
Points clés
-
POST /v1/vpn-detectretoursis_vpn,is_proxy,is_tor,is_datacenter,provider, etrisk_scorepour toute adresse IPv4. - Aucune clé API requise pour l'accès anonyme (5 requêtes par minute). Les clés gratuites débloquent 500 demandes par jour.
- La détection couvre les fournisseurs VPN commerciaux, les nœuds de sortie Tor connus et les principaux fournisseurs de cloud. Plages IP. Les VPN résidentiels et les proxys privés passent inaperçus.
- Combinez la détection VPN avec des vérifications de courrier électronique jetables, l'âge du compte et l'historique des paiements pour un score de fraude significatif. Le statut VPN seul ne suffit pas pour agir.
- Marquez les connexions VPN pour examen. Ne les bloquez pas. Les utilisateurs légitimes utilisent des VPN pour des raisons de confidentialité, la politique d’entreprise et l’accès dans les régions restreintes.
FAQ
- Comment détecter les utilisateurs VPN dans mon application ?
- Envoyez l'adresse IP de l'utilisateur à une API de détection VPN (comme POST /v1/vpn-detect) et vérifiez le booléen is_vpn dans la réponse. L'API renvoie également les indicateurs is_proxy, is_tor et is_datacenter afin que vous puissiez distinguer les différentes méthodes d'anonymisation. Appelez ce point de terminaison lors de l’inscription, de la connexion ou du paiement pour signaler les connexions suspectes pour examen.
- Une API de détection VPN peut-elle détecter chaque connexion VPN ?
- La détection VPN fonctionne en vérifiant les plages IP connues du centre de données, les noms d'hôtes DNS inversés et les listes de nœuds de sortie Tor. Les services VPN résidentiels acheminent le trafic via les adresses des FAI domestiques, qui semblent identiques au trafic résidentiel classique. Attendez-vous à une détection de 80 à 90 % des VPN commerciaux (NordVPN, ExpressVPN, Surfshark) mais à des taux inférieurs pour les VPN résidentiels et les proxys privés.
- Dois-je bloquer tous les utilisateurs VPN de mon application ?
- Non. De nombreux utilisateurs légitimes utilisent des VPN pour des raisons de confidentialité, pour des raisons de politique d'entreprise ou parce qu'ils vivent dans des régions où l'accès à Internet est restreint. Le blocage pur et simple du trafic VPN exclura les clients payants. Signalez plutôt les connexions VPN comme présentant un risque plus élevé et combinez-les avec d’autres signaux (domaine de messagerie, mode de paiement, âge du compte) pour prendre une décision.
- Quelle est la différence entre la détection VPN, proxy et Tor ?
- Un VPN crypte tout le trafic via un tunnel vers un serveur, généralement géré par un fournisseur commercial. Un proxy achemine le trafic via un serveur intermédiaire sans cryptage complet. Tor achemine le trafic via plusieurs relais gérés par des bénévoles pour un anonymat maximal. L'API botoi renvoie des indicateurs booléens distincts pour chaque type afin que vous puissiez appliquer des politiques différentes à chacun.
- L'API de détection VPN botoi nécessite-t-elle une clé API ?
- Non. L’accès anonyme autorise 5 requêtes par minute sans clé API. Pour les charges de travail de production, une clé API gratuite augmente la limite à 500 requêtes par jour. Les forfaits payants commencent à 9 $/mois pour des limites tarifaires plus élevées.
Commencez a construire avec botoi
150+ endpoints API pour la recherche, le traitement de texte, la generation d'images et les utilitaires pour developpeurs. Offre gratuite, sans carte bancaire.