VPN & proxy detection
Arcjet provides IP reputation information in two places:
- Decisions after calling
protect()
include IP address analysis fields depending on your pricing plan. You can use this to customize responses. See the SDK reference for details e.g. Next.js. - Filter rules have access to IP address analysis. You can use this to block traffic.
Available data
Section titled “Available data”- IP AS type. This is the Autonomous
System
associated with the IP, which can be used to identify VPNs and proxies. This
can be one of
isp
,hosting
,business
oreducation
. - IP type. Arcjet adds one or more categories to the IP address to help you
identify VPNs and proxies. The categories are
vpn
,proxy
,tor
,hosting
,relay
.
Available fields
Section titled “Available fields”Filters | Decision | Free | Starter | Business |
---|---|---|---|---|
ip.src.asnum.country | ip.asnCountry | 🚫 | ✅ | ✅ |
ip.src.asnum.domain | ip.asnDomain | 🚫 | ✅ | ✅ |
ip.src.asnum.name | ip.asnName | 🚫 | ✅ | ✅ |
ip.src.asnum.type | ip.asnType | 🚫 | ✅ | ✅ |
ip.src.asnum | ip.asn | 🚫 | ✅ | ✅ |
ip.src.service | ip.service | ✅ | ✅ | ✅ |
ip.src.hosting | ip.isHosting() | ✅ | ✅ | ✅ |
ip.src.proxy | ip.isProxy() | ✅ | ✅ | ✅ |
ip.src.relay | ip.isRelay() | ✅ | ✅ | ✅ |
ip.src.tor | ip.isTor() | ✅ | ✅ | ✅ |
ip.src.vpn | ip.isVpn() | ✅ | ✅ | ✅ |
Checking for data
Section titled “Checking for data”The IP analysis fields may be undefined
, but you can use various methods to
check their availability. See the SDK reference for details.
// ... imports, client configuration, etc// See https://docs.arcjet.com/get-startedconst decision = await aj.protect(req);
if (decision.ip.hasASN() && decision.ip.asnType === "hosting") { // The network this IP belongs to is a hosting provider, which makes it more // likely to be a VPN, proxy, or other suspicious network.}
if ( decision.ip.isHosting() || decision.ip.isProxy() || decision.ip.isRelay() || decision.ip.isTor() || decision.ip.isVpn()) { // The IP is from a hosting provider, proxy, relay, Tor, or VPN. We can check the name // of the service and customize the response if (decision.ip.hasService()) { if (decision.ip.service === "Apple Private Relay") { // We trust Apple Private Relay because it requires an active iCloud // subscription, so we can allow it } else { // Do something else } } else { // The service name is not available, but we can still do something here }}
Examples
Section titled “Examples”Block VPN traffic
Section titled “Block VPN traffic”Filter rules can be used to block traffic based on IP reputation:
// …rules: [ filter({ deny: ['ip.src.vpn'], mode: "LIVE", })],
// …
const decision = await aj.protect(req);
if (decision.isDenied()) { // Return 403 Forbidden}
Customize response for Apple Private Relay
Section titled “Customize response for Apple Private Relay”The ip
field on a decision
can be used to customize the response based on IP
reputation:
// …const decision = await aj.protect(req);
if (decision.isDenied()) { // Handle your other configured rules here.}
// Otherwise, customize for Apple Private Relay:if (decision.ip.service === "Apple Private Relay") { return new Response("Hello, Apple Private Relay user!");}