Appearance
钓鱼网站怎么识别?先查它的服务器 IP 归属地(Python 实操)
「您的社保账户已停用,点击链接补录信息」——短信里跟了个短链。手快的人点进去,页面长得跟真的政务平台一模一样,输完身份证和银行卡,钱就没了。这类钓鱼页面的寿命通常只有两三天,域名随手注册、服务器随手租,打一枪换一个地方。
识别钓鱼网站,除了看域名长相,还有一个特别直接的抓手:查服务器的 IP 归属地。钓鱼是灰产生意,服务器选址有自己的一套规律——境外便宜机房、无备案、纯 IP 访问居多。把这些特征和域名信息摆在一起看,九成钓鱼网站藏不住。这篇给一条完整的判断流程,配一段 Python 脚本:输入一个可疑域名,自动解析出它所有 IP、逐个查归属地和运营商,输出一张「可疑度」清单。
一、钓鱼网站的 IP 特征为什么明显
正规网站和钓鱼网站在「服务器选址」上的规律是相反的:
- 正规站:域名备案、服务器在国内(或知名云厂商海外节点)、运营商是企业/IDC 线路、同一个 IP 上通常只跑一个主业务;
- 钓鱼站:域名刚注册、解析到海外廉价机房(香港小机房、美国低价 VPS、东南亚 VPS),很多时候还套着 CDN 或换 IP 频繁。
特别是仿冒国内机构的钓鱼站,一个非常扎眼的破绽:声称自己是「人社局/银行/运营商」,服务器却在美国或香港的某个 IDC 机房,国内没有任何备案。正常机构不可能把核心业务放在一个海外小机房裸奔。
IP 归属地接口能快速给出三个关键信息:国家/地区、省市、运营商类型。海外 IDC 特征 + 仿冒对象是国内机构,这两条叠一起,基本可以定性了。如果需要更细的判断,VIP 版的 ip_type 字段(ISP 家庭 / BUS 企业 / IDC 机房)和 ip_asn 能区分「家庭宽带挂的站」和「正规机房」,家庭宽带上挂政务仿冒站,可疑度直接拉满。
二、组合判断:域名 + IP + 备案三件套
单看 IP 不够,要交叉验证。完整决策树长这样:
- 看域名:主域名注册时间越短越可疑(whois 可查);域名和仿冒对象长得像(
renshe-bx.cn仿rsj.gov.cn这类)直接高危; - 解析 IP:域名解析到的 IP 归属地是境外或国内无备案机房 → 可疑;国内运营商宽带线路 → 更可疑(正常业务不用家庭宽带走官网);
- 查备案:ICP 备案信息(工信部备案系统可查)跟网站宣称的主体对不上 → 高危;
- 看证书和页面:证书颁发机构奇怪、页面只有表单没有真实业务功能(没有查询/办理入口,全是「输入框 + 提交」)→ 实锤概率极高。
取 IP 和查归属地这两步可以自动化,就是下面脚本干的事。
三、Python 实现:域名解析 + IP 归属地核查
思路:用一个域名做输入,socket.getaddrinfo 拿到全部 A 记录(钓鱼站经常解析到多个 IP),逐个调 IP9 免费接口查归属地和运营商,最后统一打印。加了超时和异常处理,遇到解析失败、接口限速不会整个崩掉。
python
import socket
import time
import requests
# IP9 免费版 60 次/分钟,查询间隔控制一下
QUERY_INTERVAL = 1.1
def resolve_ips(domain: str):
"""解析域名,返回全部 IPv4 地址(去重)"""
ips = []
try:
infos = socket.getaddrinfo(domain, None, socket.AF_INET)
for info in infos:
ip = info[4][0]
if ip not in ips:
ips.append(ip)
except socket.gaierror:
pass # 解析失败(域名不存在/未生效)由调用方处理
return ips
def query_geo(ip: str):
"""查询单个 IP 的归属地,返回国家/省/市/运营商"""
try:
resp = requests.get(
f"https://ip9.com.cn/get?ip={ip}",
timeout=6,
headers={"User-Agent": "Mozilla/5.0 (ip-check)"},
)
data = resp.json()
if data.get("ret") != 200:
return {"error": f"ret={data.get('ret')}"}
d = data["data"]
return {
"country": d.get("country", ""),
"prov": d.get("prov", ""),
"city": d.get("city", ""),
"isp": d.get("isp", ""),
}
except Exception as e:
return {"error": str(e)}
def assess(geo: dict) -> str:
"""粗判可疑度:境外或家庭宽带特征 -> 提示,其余 -> 需人工核验"""
if "error" in geo:
return "查询失败-需人工核验"
country = geo.get("country", "")
if country and country != "中国":
return "可疑-high(境外)"
isp = geo.get("isp", "")
if "IDC" in isp or "数据中心" in isp:
return "注意-核验备案(IDC机房)"
if "联通" in isp or "电信" in isp or "移动" in isp:
return "注意-家庭/企业宽带线路"
return "需人工核验"
def main():
domain = input("输入可疑域名(不带 https://): ").strip()
ips = resolve_ips(domain)
if not ips:
print("域名解析失败:可能不存在或 DNS 未生效。")
return
print(f"{domain} 解析到 {len(ips)} 个 IP,逐个核查归属地:")
for ip in ips:
geo = query_geo(ip)
verdict = assess(geo)
print(f" IP: {ip:16s} 归属地: {geo.get('country','')}{geo.get('prov','')}{geo.get('city','')} "
f"运营商: {geo.get('isp','')} 判定: {verdict}")
time.sleep(QUERY_INTERVAL) # 限速,别打满免费额度
print("\n下一步:用上面 IP 去查 ICP 备案 + whois 注册时间,和域名仿冒对象交叉核对。")
if __name__ == "__main__":
main()跑法很简单:python3 check.py,输入可疑域名。输出里「境外」「IDC 机房」字样的行要重点看。用真实案例验证一下:随便拿一个不知名短链域名套进去,大概率能看到「解析到 1-2 个 IP + 境外机房」的组合。
代码里三个点对应到实际风控逻辑:
- 解析全部 A 记录而不是只取第一个。钓鱼站常做多 IP 轮询,只查第一个可能漏掉真正在用的那个;
- 查询间隔放到 1 秒以上。免费接口限速 60 次/分钟,批量核查时这是保命用的;手上 IP 多的话,把
QUERY_INTERVAL换成可控的限速器(参考站内《高并发下怎么调 IP 接口才不被打爆》那篇的写法); - 判定规则放到独立函数。规则以后要调(比如加入 VIP 版
ip_type的 IDC 判断、ip_asn归属厂商白名单),改一个函数就行,不用动主流程。
四、落地注意事项
识别 ≠ 取证。 脚本输出的只是「可疑度提示」,不能直接当法律证据用。真要举报或起诉,需要固定原始数据:保留访问记录、whois 快照、查询结果截图,最好做公证或走平台电子取证流程。站内《IP 地址能作为证据吗》那篇讲过怎么固定才有效力,可以配合看。
钓鱼站会换 IP。 灰产常用「快闪域名 + 频繁换解析」,今天查到的 IP 明天可能就换了。所以识别流程要多跑几遍,或者对同一域名做周期核查(用 cron 每天跑一次,记录 IP 变化轨迹)。IP 归属地查询建议加缓存:同 IP 24 小时内不用重复查。
举报渠道别忘。 确认是钓鱼站后,把域名和 IP 提交到 12321 举报中心、运营商或云厂商的安全团队,顺手把仿冒对象(银行/政务平台)的客服渠道也通知一遍,多一层人肉传播的阻断。
国内正规站不一定都能查到备案。 境外注册、服务器在海外但内容合规的站点也存在,别一刀切把「境外 IP」直接当「钓鱼」——结合域名仿冒度和页面功能(有没有诱导填敏感信息)一起判断,宁可漏杀不可错杀。
总结
钓鱼网站的命门在「服务器选址」:仿冒国内机构却把站点放在海外小机房、无备案、家庭宽带,这些特征靠 IP 归属地查询几秒钟就能暴露。一段 Python 脚本做三件事——全量解析域名、逐个查归属地、按规则打可疑度标签,配合 whois 和备案信息交叉验证,识别率足够应对日常核查。查任意 IP(包括可疑域名解析出来的)直接用 https://ip9.com.cn/get?ip=xxx(官网 https://www.ip9.com.cn,免注册、支持 IPv4/IPv6),免费版 60 次/分钟,个人和中小企业做定期排查完全够用。