API обнаружения VPN и прокси-серверов: помечайте о нарушениях, не блокируя пользователей
Обнаруживайте соединения VPN, прокси, Tor и центра обработки данных с помощью одного запроса POST. Включает промежуточное программное обеспечение Next.js, ограничение скорости Express и примеры оценки мошенничества.
Ваше SaaS-приложение предлагает бесплатную пробную версию для каждого пользователя. Пользователи регистрируются, активируют VPN и регистрируются снова. Злоупотребление промо-акцией приводит к потере дохода и искажает показатели конверсии. Вам необходимо отметить VPN и прокси соединения в момент регистрации.
В этом руководстве рассматриваются ботои POST /v1/vpn-detect конечная точка: что она возвращает, как
интегрировать его в приложения Next.js и Express, как объединить его с другими сигналами мошенничества и где
он терпит неудачу.
Конечная точка
Один POST-запрос с IP-адресом в теле. Никаких специальных заголовков и ключей API не требуется. анонимный доступ.
curl -X POST https://api.botoi.com/v1/vpn-detect \\
-H "Content-Type: application/json" \\
-d '{ "ip": "185.220.101.1" }'
Ответ для известного выходного узла Tor:
{
"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
}
}
}
Ответ на чистый жилой IP:
{
"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
}
}
}
Поля ответа
- is_vpn (логическое значение): true, если IP-адрес принадлежит известному диапазону центров обработки данных или имеет подозрительное имя хоста обратного DNS, содержащее ключевые слова, связанные с VPN.
- is_proxy (логическое значение): true, если имя хоста обратного DNS предполагает прокси-сервер.
- is_tor (логическое значение): true, если IP-адрес соответствует известному выходному узлу Tor.
- is_datacenter (логическое значение): true, если IP-адрес попадает в диапазоны AWS, Google Cloud, Azure, DigitalOcean или Linode CIDR.
- поставщик (строка или ноль): имя поставщика облачных услуг, когда
is_datacenterэто правда. Нуль для жилых IP-адресов и IP-адресов Tor. - Risk_score (число от 0 до 100): соединения Tor оцениваются в 90 баллов, IP-адреса центров обработки данных — в баллах 60, подозрительные имена хостов — в баллах 40. Чистые резидентные IP-адреса — в баллах 0.
- чеки (объект): информация о том, какие методы обнаружения сработали, для отладки.
Помечайте пользователей VPN при регистрации с помощью промежуточного программного обеспечения Next.js
Это промежуточное программное обеспечение перехватывает POST-запросы к вашему маршруту регистрации, сверяет IP-адрес вызывающего абонента с IP-адресом вызывающего абонента. API обнаружения VPN и прикрепляет заголовок к запросу при обнаружении VPN. Ваш обработчик регистрации читает заголовок и решает, что делать: потребовать подтверждения электронной почты, добавить пометку проверки вручную или сократить испытательный срок.
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'],
};
Промежуточное программное обеспечение не блокирует регистрацию. Он передает сигнал вашему обработчику. Это правильно подход, поскольку VPN-трафик не является доказательством мошенничества. Пользователь, использующий корпоративный VPN или путешествующий через ограничительную сеть является законным клиентом.
Более строгие ограничения скорости для IP-адресов VPN в Express
Если вы используете API, вы можете применить более жесткие ограничения скорости для VPN и прокси-соединений, не блокируя их откровенно. Это промежуточное программное обеспечение обеспечивает стандартным пользователям 100 запросов в час, а пользователям 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();
}
Отправной точкой является соотношение 5:1 между стандартными ограничениями и ограничениями VPN. Настройте его на основе вашего злоупотребления узоры. Если ваш API обрабатывает платежи или изменения учетной записи, имеет смысл ужесточить ограничения VPN. Для конечных точек, доступных только для чтения, дифференциальные ограничения могут вообще не потребоваться.
Оценка мошенничества: объедините обнаружение VPN с другими сигналами
Обнаружение VPN само по себе является слабым сигналом мошенничества. VPN + одноразовый адрес электронной почты + новая учетная запись + ошибка попытки оплаты — сильный сигнал. Эта функция объединяет несколько входных данных в одно мошенничество. оценка.
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,
},
};
}
Оба вызова API выполняются параллельно, поэтому общая задержка оказывается более медленной (обычно при
100 мс). action В этом поле есть три уровня: разрешить, просмотреть или заблокировать. Для баллов
между 40 и 70 направьте регистрацию в очередь на проверку вручную, а не автоматически отклоняйте ее.
Кэширование для сокращения вызовов API
IP-адрес не меняет свой статус VPN при каждом запросе. Кэшируйте результат на 10 минут, чтобы сократите использование API, не пропуская изменений статуса.
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 };
}
}
Для развертываний на нескольких серверах замените карту в памяти на Redis или Upstash. Тот же ключ кэша (IP-адрес) и шаблон TTL.
Что этот API не может обнаружить
Честность в отношении ограничений важнее, чем безупречная рекламная подача. Вот где обнаружение VPN терпит неудачу.
- Жилые VPN. Такие сервисы, как iCloud Private Relay и некоторые конфигурации. Mullvad маршрутизирует трафик через резидентные IP-адреса. Эти IP-адреса выглядят идентично регулярное домашнее подключение к Интернету. Никакой обратный DNS или обнаружение на основе CIDR их не улавливает.
-
Оператор мобильной связи НАТ. Операторы мобильной связи используют NAT операторского уровня, что означает
тысячи пользователей используют один IP-адрес. Пометка этих IP-адресов влияет на законных пользователей.
API может вернуться
is_datacenter: falseиrisk_score: 0для этих IP-адреса, даже если за ними стоит пользователь VPN. - Частные прокси SOCKS5. Прокси, размещенные на персональных серверах с жилыми Интернет-провайдеры не фигурируют в диапазонах CIDR центров обработки данных и не имеют подозрительных имен хостов. Они невидимый для автоматического обнаружения.
- Соединения только для IPv6. Текущая конечная точка поддерживает только адреса IPv4. Обнаружение IPv6 VPN недоступно.
-
Ложные срабатывания на виртуальном хостинге. Разработчик, выполняющий побочный проект на
Капля DigitalOcean сработает
is_datacenter: true. Это не значит, что они скрывающие свою личность.
Обнаружение хорошо работает для коммерческих провайдеров VPN (NordVPN, ExpressVPN, Surfshark, CyberGhost). и трафик Tor. Он ловит большинство прокси, размещенных в центрах обработки данных. Он не ловит домашние VPN или частные прокси. Ожидайте 80–90% обнаружения для распространенных случаев и около нуля для крайних случаев.
Пометить, не блокировать
Полная блокировка пользователей VPN является ошибкой для большинства приложений. Вот почему:
- Пользователи, заботящиеся о конфиденциальности и не намеревающиеся злоупотреблять вашим сервисом, по умолчанию используют VPN.
- Сотрудники корпоративных VPN маршрутизируют весь свой трафик через инфраструктуру компании.
- Пользователи в странах с ограничениями в Интернете полагаются на VPN для доступа к вашему продукту.
- Журналисты, активисты и исследователи безопасности используют Tor по законным причинам.
Правильный подход: добавить в аккаунт флаг риска, потребовать дополнительную верификацию (электронная почта подтверждение, номер телефона, способ оплаты) или направьте регистрацию в очередь на проверку. Пусть люди сделать окончательное решение в неоднозначных случаях.
Ключевые моменты
-
POST /v1/vpn-detectвозвращаетis_vpn,is_proxy,is_tor,is_datacenter,provider, иrisk_scoreдля любого адреса IPv4. - Для анонимного доступа не требуется ключ API (5 запросов в минуту). Бесплатные ключи разблокируют 500 запросов в день.
- Обнаружение охватывает коммерческих провайдеров VPN, известные выходные узлы Tor и крупных облачных провайдеров. IP-диапазоны. Резидентные VPN и частные прокси проскальзывают.
- Объедините обнаружение VPN с одноразовыми проверками электронной почты, возрастом учетной записи и историей платежей для значимый показатель мошенничества. Одного только статуса VPN недостаточно, чтобы действовать.
- Отметьте VPN-подключения для проверки. Не блокируйте их. Законные пользователи используют VPN для обеспечения конфиденциальности, корпоративная политика и доступ в регионах с ограниченным доступом.
FAQ
- Как обнаружить пользователей VPN в моем приложении?
- Отправьте IP-адрес пользователя в API обнаружения VPN (например, POST /v1/vpn-detect) и проверьте логическое значение is_vpn в ответе. API также возвращает флаги is_proxy, is_tor и is_datacenter, чтобы вы могли различать различные методы анонимизации. Вызовите эту конечную точку во время регистрации, входа в систему или оформления заказа, чтобы пометить подозрительные соединения для проверки.
- Может ли API обнаружения VPN перехватывать каждое VPN-соединение?
- Нет. Обнаружение VPN работает путем проверки известных диапазонов IP-адресов центров обработки данных, имен хостов обратного DNS и списков выходных узлов Tor. Домашние VPN-сервисы маршрутизируют трафик через адреса домашних интернет-провайдеров, которые выглядят идентично обычному домашнему трафику. Ожидайте 80-90% обнаружения коммерческих VPN (NordVPN, ExpressVPN, Surfshark), но более низкие показатели для частных VPN и частных прокси.
- Должен ли я заблокировать доступ всех пользователей VPN к моему приложению?
- Нет. Многие законные пользователи используют VPN из соображений конфиденциальности, корпоративной политики или потому, что они живут в регионах с ограниченным доступом в Интернет. Полная блокировка VPN-трафика приведет к блокировке платящих клиентов. Вместо этого пометьте VPN-соединения как более рискованные и объедините их с другими сигналами (домен электронной почты, способ оплаты, возраст учетной записи), чтобы принять решение.
- В чем разница между обнаружением VPN, прокси и Tor?
- VPN шифрует весь трафик через туннель к серверу, обычно принадлежащему коммерческому провайдеру. Прокси-сервер направляет трафик через промежуточный сервер без полного шифрования. Tor маршрутизирует трафик через несколько ретрансляторов, управляемых добровольцами, для максимальной анонимности. API botoi возвращает отдельные логические флаги для каждого типа, поэтому к каждому из них можно применять разные политики.
- Требуется ли API-интерфейс обнаружения botoi VPN ключ API?
- Нет. Анонимный доступ допускает 5 запросов в минуту без ключа API. Для производственных рабочих нагрузок бесплатный ключ API увеличивает лимит до 500 запросов в день. Платные планы начинаются с 9 долларов в месяц для более высоких лимитов.
Начните разработку с botoi
150+ API-эндпоинтов для поиска, обработки текста, генерации изображений и утилит для разработчиков. Бесплатный тариф, без банковской карты.