← Back to Engineering Blog
v2.3-GOLD P3 Landlord ID Reference Reading

Internet Landlords
How To Detect VPN Wholesalers Like Clouvider, M247, and Tesonet

Published Apr 28, 2026 Engineering Team ~10 min read

Run any commercial VPN ASN through your favorite GeoIP database and you will get the same answer the rest of us got: asnType: "unknown". NordVPN is not on the list. Surfshark is not on the list. ExpressVPN routes through a half dozen wholesale providers that nobody has bothered to keyword. So when a fresh exit IP from one of those vendors lands on your signup page, the only thing your fraud stack sees is an IP, a country, and a shrug.

The fix is not a bigger blocklist or a paid VPN-subscription database. The fix is one layer deeper. Modern commercial VPNs do not own their IP space. They lease it from a small set of wholesale infrastructure providers. We call them Internet Landlords. Once you can identify the landlord, you stop chasing tenants.

What "Internet Landlord" actually means

BGP routing is a public ledger. Every IP on the internet announces a route, and every route resolves to an ASN. That ASN is owned by someone. For consumer broadband and mobile carriers, the owner is also the brand: Comcast operates AS7922, Verizon Wireless operates AS6167, Deutsche Telekom operates AS3320. Easy.

For commercial VPN providers, the situation is upside down. NordVPN does not run AS49981 because NordVPN does not own ASNs. NordVPN buys capacity from Tesonet (its sister Lithuanian holding) which in turn rents IP blocks from a rotating cast of European hosting wholesalers: M247 Ltd, Clouvider, Hivelocity, Performive, Datacamp, Misaka, Serverius. Surfshark uses the same playbook. ExpressVPN uses the same playbook with slightly different vendors. The end-user installer talks to a hostname like nordvpn-uk-1234. The route announcement says M247.

These wholesalers are the landlords. They do not advertise themselves as VPN providers, because their business is renting CIDR blocks to anyone with a credit card. A subscription database that lists "NordVPN" will miss every IP NordVPN does not formally announce. A landlord database catches NordVPN, plus every other VPN, plus the sneaker-bot farm next door, plus the residential-proxy reseller renting the same /22.

The MaxMind blindspot in one screenshot

Take the IP 216.183.115.43. It is a Clouvider host inside AS62240 in London. We caught it during a v2.3 audit when our scoring engine returned a 0 on a fresh first-contact lookup. Here is what each major data provider returns, side by side, on the same IP.

Landlord Detection: Provider Comparison
Signal MaxMind IPinfo AbuseIPDB CandycornDB v2.3
Resolves AS62240 owner Yes Yes No Yes
Tags as VPN provider No Partial (paid tier) No Yes (isProxy: true)
Identifies wholesale landlord No No No Yes (asnType: hosting)
/24 CIDR neighbor density No No No Yes (networkCluster +25)
First-contact prefix resolution No Bulk only No Yes, single call
Returns audit receipt No No No scoreReasons[]
p99 cached lookup ~80ms ~70ms ~150ms < 50ms

The legacy providers all see "AS62240 Clouvider," then stop. They do not know what Clouvider is. CandycornDB matches "clouvider" against the wholesale keyword bag, fires asnType: "hosting", layers on isProxy: true, and returns the audit receipt that justifies it. Same data feed, different conclusion.

The detection logic, step by step

Landlord identification is not magic. It is a four-step pipeline that runs on every first-contact IP. Total cost: one DNS resolution and three Mongo lookups, all parallelized. Below is the actual flow your request takes when you hit /api/public/lookup.

Step 1
IP arrives
No prior record in cleanedDatas. JIT path opens. Redis dedup window prevents duplicate work.
Step 2
Prefix resolution
Multi-key index on asns.prefixes. Returns the longest-match CIDR landlord without an upstream API call.
Step 3
Keyword scan
ISP, ASN org name, and reverse-DNS hostname all run against HOSTING_KEYWORDS and VPN_KEYWORDS bags.
Step 4
Score and persist
Base-Zero math runs. scoreReasons[] is built. Write-behind saves the row so the next call hits the cache in < 50ms.

The keyword bags are the part most teams underestimate. They are not glamorous. They are short text files. But they hold the entire detection wedge. Every time a customer reports a missed VPN, the fix is one new line in HOSTING_KEYWORDS or VPN_KEYWORDS, deployed in under five minutes, and every existing dirty row in the database self-heals on its next read.

The wholesale landlord shortlist

Below is the curated set we maintain in production right now. It is not exhaustive (it never will be), but it covers the long tail that GeoIP databases skip. Match these strings against ISP, ASN org name, and reverse-DNS hostname.

Wholesale infrastructure landlords (always hosting)

  • clouvider: London-based wholesale, used by NordVPN, Surfshark, residential proxy resellers.
  • m247: Manchester-based, the largest single VPN landlord in Europe by IP volume.
  • performive: US-based, popular with sneaker bots and scraping farms.
  • datacamp, datacenters: alias-heavy IP brokers.
  • packethub, serverius, misaka: small-cap wholesalers, disproportionate VPN footprint.
  • colocation: generic wholesale tag. Fires on facilities that resell rack space and routes.

VPN-branded keywords (always isProxy: true)

  • nordvpn, nordsec, tesonet: the Lithuanian Nord stack. All three resolve to the same legal owner.
  • surfshark: matches both ISP strings and reverse-DNS hostnames.
  • expressvpn: rare in ASN names, common in PTR records.

When a hostname or ISP contains nordvpn or clouvider, our v2.3 scorer applies an additional +20 proxy penalty on top of the standard +15 hosting delta. This is the "infrastructure penalty" we shipped after the AS62240 audit. NordVPN exits now reliably land in the 35 to 50 risk band, which is the medium-to-high range. They are no longer scoring 0.

The real receipt: scoring 216.183.115.43

Here is the actual response from GET /api/public/lookup?ip=216.183.115.43 after the v2.3-GOLD rollout. Pay attention to scoreReasons. That array is the audit receipt. Every delta is signed by a component name and a numeric weight. You can paste this into a Jira ticket and defend the block to a customer support rep with no further context.

{
  "ip": "216.183.115.43",
  "score": 35,
  "scoreVersion": "v2.3-base-zero",
  "country": "GB",
  "asn": "AS62240",
  "asnName": "Clouvider Limited",
  "asnType": "hosting",
  "isProxy": true,
  "isp": "Clouvider Limited",
  "scoreReasons": [
    { "component": "asnHosting",     "delta": 15, "detail": "clouvider matched in HOSTING_KEYWORDS" },
    { "component": "proxyInferred",  "delta": 20, "detail": "clouvider matched in VPN_KEYWORDS, +20 infra penalty" }
  ],
  "firstSeen": "2026-04-28T13:11:08.412Z",
  "lastSeen":  "2026-04-28T13:11:08.412Z"
}
// Math: 0 (base) + 15 (hosting) + 20 (infra penalty) = 35
// Risk band: Medium

Thirty-five is not a "block on sight" score. It is a "ratchet your friction up by one notch" score. CAPTCHA the signup. Email-verify the checkout. Push the API request through stricter rate limits. The point of Base-Zero math with explicit deltas is that you no longer need a one-size threshold. You react proportionally to the signal you have, and you can show your work.

The /24 cluster amplifier

Landlord identification gets sharper when you pair it with subnet density. A clean residential IP on Comcast scores 0. The same IP on a wholesale ASN scores 35. But a wholesale IP whose /24 CIDR block contains 12 already-flagged neighbors scores 60. That is the P1 layer doing its job.

Our P1 scanner runs on the ipLong integer index, which means a /24 neighbor count is one indexed range query, O(log N) on the IP table. Cost is essentially free. When 60 percent or more of a /24 is dirty, the scorer adds networkCluster: +25 to the receipt. Stack that on top of a wholesale hosting hit, and the score climbs into the high band where automatic blocking starts to make sense.

When wholesale + cluster fire together

A real example from production logs, redacted:

  • IP first-contact, no prior record.
  • Prefix resolution: AS9009, M247.
  • Keyword bag: m247 matches HOSTING. asnType: hosting, +15.
  • Reverse DNS: vpn.m247.com. Hostname pattern fires isProxy: true, +20.
  • /24 scanner: 18 of 256 neighbors flagged. networkCluster: +25.
  • Final score: 60. Risk band: High. Action: hard block on signup, soft block on read-only API endpoints.

Plug it into your auth flow

The whole detection loop is one API call. Below is a Node example for a signup endpoint. Same shape works in Python, Go, or whatever your stack happens to be. There is no SDK to vendor, no model to retrain, no blocklist to refresh.

const { data } = await axios.get(
  'https://candycorndb.com/api/public/lookup',
  { params: { ip }, headers: { 'x-api-key': KEY } }
);

// Hard block: known infrastructure with proxy signals.
if (data.asnType === 'hosting' && data.isProxy) {
  return res.status(403).json({
    code: 'WHOLESALE_VPN',
    score: data.score,
    receipt: data.scoreReasons
  });
}

// Soft friction: medium risk band, add a CAPTCHA.
if (data.score >= 35 && data.score < 60) {
  return res.json({ requireCaptcha: true });
}

// Clean IP. Continue normal flow.
return next();

Notice we are returning data.scoreReasons in the 403. That is intentional. When a customer emails support saying "your site blocked me," your support rep can paste the receipt into a ticket and show exactly which deltas fired. No black box. No "our model says you are risky." Just asnHosting +15, proxyInferred +20.

What this catches that subscription databases do not

1. Fresh exit IPs on existing landlords

NordVPN rotates exit IPs constantly. New IP, same M247 /22. A subscription database that lists "NordVPN" by IP will miss every fresh exit until the vendor catches up. Landlord identification fires the moment the prefix resolves to M247, even if the specific IP has never been seen before.

2. Smaller VPNs that nobody catalogs

There are hundreds of mid-sized VPN brands you have never heard of. Mullvad, IPVanish, ProtonVPN, PIA, CyberGhost, Hide.me, plus the long tail of regional vendors. Most of them rent from the same wholesale pool. Match the landlord, you catch them all.

3. Residential proxy resellers using hosting

Some vendors sell "residential" proxies that are actually datacenter IPs with a residential PTR. The wholesale ASN exposes the lie. If the IP routes through Clouvider, it is not a real Comcast subscriber, no matter what the reverse DNS says.

4. Sneaker bots, scraper farms, ATO operations

Anyone who buys IP space at scale rents from the same wholesalers. The user-agent will lie. The behavior will be careful. The ASN will give them up.

When the landlord layer maps to a billing problem

A pattern we keep seeing in support tickets: a SaaS launches a metered API or per-seat plan. They offer a generous free trial. Within a week their usage credits are being burned by accounts that all look like real users. Different emails, different names, different timezones. But trace the source IPs and 80 percent of them route through three or four wholesale ASNs.

That is usage billing fraud, executed at the BGP layer. The accounts are sock puppets created from disposable wholesale IPs. The signal is not in the email pattern or the click behavior. It is in the network. Block at signup with a asnType: hosting rule and the problem disappears overnight, because the attacker would now need to source residential IPs at scale, which is an order of magnitude more expensive.

See also: ATO blindspots in unmonitored auth flows for the parallel pattern on login. Same primitive, different surface.

The bottom line

GeoIP databases were built to answer "where is this IP?" The internet changed. The question that matters now is "what kind of network is this IP on, and who owns the building?" Once you can identify the landlord, the tenants stop mattering. NordVPN this week, Surfshark next week, an unnamed sneaker bot the week after: same landlord, same flag, same defense.

Wholesale ASN identification is one HTTP call, three lookups, and a keyword bag you can extend in five minutes. It runs in p99 under 50ms cached, returns the audit receipt by default, and ships on the free Developer tier with no credit card. If your fraud stack is still doing IP-list lookups in 2026, you are already losing the network-edge fight. Start at the landlord layer. The tenants will follow.