Skip to content

VPN & proxy detection

Arcjet provides IP reputation information in two places:

  • Decisions after calling protect() include IP address analysis fields. You can use this to customize responses. See the SDK reference for details e.g. Next.js.
  • Arcjet Filters have access to IP address analysis. You can use this to block traffic.
  • 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 or education.
  • 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.
FiltersDecision
ip.src.asnum.countryip.asnCountry
ip.src.asnum.domainip.asnDomain
ip.src.asnum.nameip.asnName
ip.src.asnum.typeip.asnType
ip.src.asnumip.asn
ip.src.serviceip.service
ip.src.hostingip.isHosting()
ip.src.proxyip.isProxy()
ip.src.relayip.isRelay()
ip.src.torip.isTor()
ip.src.vpnip.isVpn()

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-started
const 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
}
}

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!");
}