一、数据解读:境外攻击比例已超“警戒线”
2025年5月,工信部下属机构监测发现,由境外IP发起的网络攻击达144.09万次,占网络攻击总量的78.1%,攻击来源覆盖113个国家和地区,其中源自美国的攻击最多,达87.49万次,占境外攻击总数的60.7%。9月的数据显示,境外IP攻击虽回落至61.1%的占比(183.86万次),但整体规模仍在高位震荡,攻击来源扩展至124个国家。
更具代表性的事件是2025年哈尔滨亚冬会。赛事期间,信息系统共遭境外网络攻击270167次,封禁高危恶意IP地址12602个。其中美国攻击次数最高,达170864次,占比63.24%。
这些数据揭示了一个现实:溯源能力不再只是应急响应的“备选”,而是网络安全建设的“必选项”。
二、IP溯源的核心逻辑:从攻击日志到可操作情报
IP溯源的本质,是从攻击链的源头节点入手,将零散的攻击日志转化为可用于决策的威胁情报。技术路径可以归纳为以下步骤:
1. 日志提取:从WAF、防火墙、服务器访问日志中抓取恶意请求的源IP;
2. IP定位:调用IP定位API接口或离线IP库,获取攻击源的地理位置、运营商信息;
3. 风险关联:结合IP的历史行为数据和威胁情报库,评估该IP的风险等级。
IP溯源三步骤流程图
在实际操作中,一个攻击IP的价值不只在于定位它来自哪个城市,还在于识别它属于哪种网络类型——是住宅宽带,还是数据中心/VPS,抑或是代理/VPN节点。这直接决定了应对策略:住宅IP可能是被劫持的普通用户设备,而VPS上的攻击源则更可能存在持续、有组织的攻击行为。IP定位API接口在这一环节中承担了快速、自动化的地理与网络属性解析任务,是溯源流程的“第一道门”。
以IP数据云提供的定位服务为例,其接口返回字段涵盖国家、城市、运营商、ASN及代理类型,开发者可直接集成至溯源脚本中,实现分钟级的攻击源画像输出。
三、实战案例:一次暴力破解攻击背后的基础设施溯源
2025年,安全团队Huntress在处理一起RDP服务器的暴力破解警报时发现,攻击者成功破解了一个账户凭证,但与典型入侵不同,登录记录来自多个IP地址,这引起了分析师的警觉。团队随即对相关IP进行深入追溯,通过分析TLS证书发现了一个恶意域名specialsseason.com,顺藤摸瓜关联出大量采用“NL-<国家代码>”命名规则的子域名——一个遍布全球多国的初始访问代理基础设施网络逐步浮出水面。这一案例说明:单一IP的背后可能隐藏着庞大的攻击基础设施集群,而这种深度关联分析的起点,恰恰是对IP归属和网络属性的精准定位。在实际溯源工作中,安全团队常借助IP数据云这类专业IP地理位置库,快速区分攻击源是普通住宅带宽还是机房VPS,从而判断攻击行为的组织化程度。
暴力破解攻击溯源示意图
四、代码实操:从日志到溯源的工具链
以下是一个简化的IP溯源脚本示例。它批量读取攻击日志中的IP地址,调用IP定位API接口获取地理和网络信息,并输出汇总报告:
import requests
import json
from collections import Counter
def query_ip_location(ip, api_key, timeout=(3.05, 10)):
"""
查询单个IP的地理位置和代理信息
:param ip: 目标IP地址
:param api_key: API密钥
:param timeout: 连接超时(秒)和读取超时(秒)的元组
:return: 包含定位信息的字典,失败时返回error字段
"""
api_url = "https://api.ipdatacloud.com/v1/ip-location"
params = {
"key": api_key,
"ip": ip,
"fields": "country,city,region,isp,asn,proxy_type"
}
try:
response = requests.get(api_url, params=params, timeout=timeout)
response.raise_for_status() # 自动处理4xx/5xx状态码
data = response.json()
# 检查API返回的业务状态码
if data.get("code") == 200 and "data" in data:
return data["data"]
else:
error_msg = data.get("message", "Unknown API error")
return {"error": f"API error: {error_msg}"}
except requests.exceptions.Timeout:
return {"error": "Request timeout"}
except requests.exceptions.RequestException as e:
return {"error": f"Network error: {str(e)}"}
except (KeyError, ValueError, json.JSONDecodeError) as e:
return {"error": f"Response parsing error: {str(e)}"}
def batch_ip_trace(ip_list, api_key, delay=0.5):
"""
批量处理IP地址并生成溯源报告
:param ip_list: IP地址列表
:param api_key: API密钥
:param delay: 每次请求之间的延迟(秒),避免触发限流
:return: 统计报告字典
"""
import time
report = {
"total": len(ip_list),
"by_country": Counter(),
"bad_ips": [],
"details": {}
}
# 代理类型黑名单常量
PROXY_BLACKLIST = {"vpn", "proxy", "tor", "hosting"}
for idx, ip in enumerate(ip_list[:50]): # 限制批量查询数量
result = query_ip_location(ip, api_key)
if "error" not in result:
country = result.get("country", "Unknown")
isp = result.get("isp", "Unknown")
proxy_type = result.get("proxy_type", "").lower()
report["by_country"][country] += 1
report["details"][ip] = {
"country": country,
"isp": isp,
"proxy_type": proxy_type if proxy_type else "none"
}
if proxy_type in PROXY_BLACKLIST:
report["bad_ips"].append(ip)
else:
report["details"][ip] = {"error": result["error"]}
# 控制请求频率,避免API限流
if idx < len(ip_list) - 1:
time.sleep(delay)
return report
# 使用示例(请替换为真实API Key)
API_KEY = "YOUR_API_KEY_HERE"
sample_ips = [
"45.33.89.124", # 示例攻击IP
"185.130.5.225",
"103.139.44.15"
]
result = batch_ip_trace(sample_ips, API_KEY, delay=0.5)
print(json.dumps(result, indent=2, ensure_ascii=False))
运行上述脚本后,输出示例为:
{
"total": 3,
"by_country": {"US": 1, "DE": 1, "Unknown": 1},
"bad_ips": ["185.130.5.225"],
"details": {
"45.33.89.124": {"country": "US", "isp": "Linode", "proxy_type": "hosting"},
"185.130.5.225": {"country": "DE", "isp": "Hetzner", "proxy_type": "proxy"},
"103.139.44.15": {"error": "API error: rate limit exceeded"}
}
}
在生产环境中,可进一步集成威胁情报服务、自动化封禁模块和SIEM/SOAR平台,实现“定位-判定-处置”的全链路闭环。
五、数据来源说明
- 工信部贵州省通信管理局:《工业互联网网络安全情况通报(2025年第5期)》,发布境外IP攻击占比78.1%、源自美国攻击占比60.7%等核心数据。
- 国家计算机病毒应急处理中心:《2025年哈尔滨第九届亚冬会赛事信息系统遭境外网络攻击情况报告》,发布27万次攻击总次数、170864次来自美国、封禁12602个恶意IP等数据。
扩展思考:本脚本基于同步请求,适合小批量实时查询。当处理百万级访问日志时,建议改用离线IP库预加载 + 内存二分查找(O(logN)),可将单IP判定延迟降至微秒级。您也可以将代理类型检测集成到WAF或网关中间件,实现实时阻断。