Determine whether an IP (or a socks5 proxy with credentials) is suitable for AI services (Grok/Claude/ChatGPT). The core is to see through leased IP ranges that are "physically in the US but on paper in another country"—such IPs are judged by commercial geolocation databases like ipinfo/MaxMind to be in the EU, causing Grok/Claude region locks, while risk control only looks at geolocation databases and not physical latency.
Operating Contract
Read-only detection, does not change any system configuration. The script only sends outbound HTTP/DNS queries and (when credentials are provided) probes through the proxy; it does not write files, change proxy settings, or touch network configuration.
Direct actions:
- Run against the IP or proxy credentials provided by the user
ipcheck.py, read the JSON, and produce a scorecard according to 4 hard criteria. - Distinguish facts (JSON fields) from inferences (e.g., "physically most likely on the US East Coast, based on latency ranking").
Escalate before:
- When the user requests implementation actions such as "change config/switch node/add to Clash"—that belongs to ops skills like clash-doctor; this skill is only responsible for judgment and does not switch on the user's behalf.
- When the DNSBL layer reports
unreliable(DNS hijacking), you must prompt the user to switch networks and rerun; do not treat an inaccurate test as "clean". - When the proxy exit cannot be confirmed, TLS verification fails, or the proxy parameters are invalid, the script returns non-zero and outputs
error; do not switch to the gateway or skip the proxy layer to continue the judgment.
Evidence-backed pushback:
- When the user insists that an IP is in the US, but rdap shows RIPE registration + country not US, rebut with the whois/geo fields; do not go along with subjective judgment.
- A single database judging US does not equal qualified; disagreement among three databases (split) is itself a signal of "paper relocation" and should be pointed out rather than trusting the most optimistic one.
Feedback loop:
- After switching nodes/proxies, rerun and compare item by item using the scorecard (e.g., Spain range = return, New York range = qualified) to confirm the problem items are indeed eliminated.
- When IPQS_KEY/ABUSEIPDB_KEY are available, additionally run the risk-control sources; when keys are missing, explicitly mark skipped, and do not treat "not tested" as "passed".
When to use
- The user gives an IP and asks "where is it/can it be used/why is it judged to be in a certain country"
- The user gives socks5 proxy credentials (
socks5://user:pass@host:port) and asks about attribution or whether a certain service is unlocked - Bought a residential/datacenter proxy and needs acceptance testing
- Troubleshoot region locks for AI services
Run
The script runs from the skill installation location. Prefer the installation path of the current runtime: Codex is usually ~/.agents/skills/ip-check/scripts/ipcheck.py, Claude Code is usually ~/.claude/skills/ip-check/scripts/ipcheck.py, and during repository development you can also use skills/ip-check/scripts/ipcheck.py。
python3 <script> <IP> # 只查 IP
python3 <script> socks5://user:pass@host:port # 带凭证多跑代理实测层
python3 <script> <IP> --proxy socks5://user:pass@host:port # IP 与代理分开给
The script outputs structured JSON (9 layers); your job is toread the JSON and make a judgment, not just relay fields. Optional environment variables IPQS_KEY(IPQualityScore free 5000/month),ABUSEIPDB_KEY(free 1000/day), when present, automatically run two additional risk-control sources; if absent, mark that item as skipped.
Detection layer description
| Layer | Data source | What to look at |
|---|---|---|
| rdap | rdap.org → RIR | Registration database (ARIN = North America good / RIPE = Europe needs caution), org, lease_flag, country |
| geo | ipinfo + ip-api + ipwho | Whether the country judged by the three databases is consistent (consensus) or split |
| asn | ipinfo org + rdap | Whether the ASN is a real ISP, whether the org matches the ASN entity |
| reputation | proxycheck + ipapi.is (+IPQS +AbuseIPDB) | proxy/vpn/datacenter flags, risk score, fraud score |
| dnsbl | Spamhaus/Barracuda/SORBS/SpamCop | Spam blacklist (with built-in DNS hijacking detection) |
| ptr | dig -x | Whether reverse DNS has a genuine residential domain format (hsd1/cable/dsl) |
| bgp | RIPEstat | Which ASN actually announces this prefix |
| services | Direct connection to each service via proxy | Whether Grok/ChatGPT/Anthropic are reachable, cf_loc, whether region-locked (proxy required) |
| exit | Check proxy exit 3 times | Single hop or rotating pool, whether exit IP equals server IP (proxy required) |
| latency | Proxy → AWS TLS connection to each continent ×3 | Physically nearest continent (proxy required) |
Decision protocol (read the JSON and rule accordingly)
Output onescorecard, with the 4 hard criteria checked item by item ✅/⚠️/❌, then give the overall verdict.
Hard criteria (4 items; must all pass to qualify):
- Registry = ARIN —
rdap.rir == "ARIN"andrdap.country == "US". RIPE/APNIC + non-US country = ❌ (this is the cause of death for the Spain block).lease_flag=true(mnt shows interlir/lease) = ❌ return immediately. - Three databases agree on US —
geo.consensus == trueand the country is US in all of them.geo.split == true(databases disagree) = ⚠️ strong warning; this is the "paper relocation" signal, and the disagreement itself matters more than any single database's conclusion. - ASN/org consistent and a real ISP — three cases:
asn.is_real_isp == trueandasn.org_matches_asn == true→ ✅。asn.is_real_isp == truebutasn.org_matches_asn == false(org is an unfamiliar third-party name, e.g. Treochoy9/AviationAI) → ⚠️ leased-block characteristic; usable but with drift risk, not an outright fail.asn.is_real_isp == false(ASN not in the real ISP whitelist) → do not reject on its own; the whitelist only covers mainstream North American ISPs, so legitimate European/Asian/small-to-mid ISPs will be missed. Judge together with reputation: if it also hits datacenter/hosting → return it; otherwise classify as ⚠️ use with caution and note "ASN is not a mainstream ISP; manually confirm whether it is truly residential".
- Risk score clean — proxycheck
risk==0、proxy/vpn=no、typenot hosting; all ipapi.is is_* fields false; when IPQS is available,fraud_scorelow. Any hit on datacenter or abuser = ❌.
Auxiliary signals (weighted, do not reject on their own):
dnsbl.status=="unreliable"→ must warn the user: the current network has DNS hijacking (most likely Clash TUN fake-ip); this blacklist item was not measured accurately and must be rerun on a non-TUN network to be valid. Do not treat unreliable as "clean".ptr.has_ptr==false→ common characteristic of annexed blocks; a weak negative signal (the New York block also had no PTR but still qualified, so do not reject on its own).bgp.announced_bydiffers from the rdap org entity → the IP block may have recently changed hands; record it but do not reject.
Proxy empirical layer (when credentials are available, the highest value — ask risk control directly):
services.results.grok.com.region_blocked==true(and it is an exact phrase hit) → Grok really does lock this exit;strongest negative evidence. Note thatregion_blockedis a weak heuristic signal (the homepage is an SPA shell),http_statusandcf_locare the hard signals —cf_loc != "US"indicates Cloudflare also judges it non-US.exit.stable==false→ you paid for static but got a rotating pool; another kind of trap, report it.exit.exit_ip != 服务器IP→ multi-hop, record it.latency.closestis Europe/Asia but the geolocation database says US, or vice versa → physical/paper split, clearly state "physically in X, on paper in Y, risk control believes the paper".
Overall verdict in three tiers:
- Qualified — all 4 hard criteria ✅; safe to use for AI services.
- Leased block, use with caution — Passes hard criteria but has ⚠️ (org mismatch / no PTR / BGP ownership change); usable but indicates risk, recommend periodic re-checks.
- Reject — Any ❌ (RIPE registration / non-US country / lease_flag / three databases judge non-US / datacenter / abuser / is_real_isp=false with hosting match / service region lock). Give the specific cause of failure and the script: "find an agent to switch to an ARIN-registered IP that ipinfo shows as US."
Output format
Give the user a Chinese scorecard: first a one-sentence overall verdict, then list key evidence layer by layer (marked ✅/⚠️/❌), and finally give action recommendations. Distinguish facts (from JSON fields) from inferences (e.g., "physically most likely on the US East Coast, based on latency ranking"). Do not list all raw fields; pick only the key evidence supporting the verdict.
Known boundaries
- scamalytics fully blocks automated access (measured 403); the protocol has been ruled out; use proxycheck + ipapi.is + IPQS instead.
- DNSBL is untrustworthy in a Clash TUN environment; the script will automatically detect this and mark it unreliable, and prompt the user accordingly.
- DNSBL resolver failures and Spamhaus
127.255.255.0/24query error codes are likewise markedunreliable, and are not counted as "not listed" or as a hit. - SOCKS HTTPS probing uses the system CA and hostname verification; a certificate failure counts as a probe failure, and TLS verification must not be disabled to retry.
serviceslayer homepages are mostly SPA shells,region_blockedis a weak signal; rely on http_status/cf_loc.- ip-api.com is limited to 45 requests/minute, and proxycheck is free for 100 requests/day; watch the quota when batch-querying multiple IPs.