Python提取Bot-IoT数据集CSV内IP地址信息的问题求解
问题背景
我正在用Python构建分析模型,使用UNSW公开的Bot-IoT数据集,目标是提取数据集CSV文件中存储的IP地址相关信息。数据集中saddr、daddr特征分别对应模拟IoT场景下的源IP地址、目的IP地址。
我已经安装了maxminddb-geolite2、ip2geotools两个依赖库尝试实现IP信息提取,但返回结果存在异常,相关实现代码、运行结果如下:
基于geolite2的实现方案
实现代码
import time from geolite2 import geolite2 geo = geolite2.reader() df_1 = dt.loc[:50,['saddr']] def IP_info_1(ip): try: x = geo.get(ip) except ValueError: # 非法IP值 return np.nan try: return x['country']['names']['en'] if x is not None else np.nan except KeyError: # 键不存在 return np.nan s_time = time.time() # 映射IP到所属国家 # apply(fn)会将函数应用到所有pandas Series元素上 df_1['country'] = df_1.loc[:,'saddr'].apply(IP_info_1) print(df_1.head(), '\n') print('耗时:',str(time.time()-s_time)+'s \n') print(type(geo.get('48.151.136.76')))
运行结果
saddr country 0 192.168.100.147 NaN 1 192.168.100.147 NaN 2 192.168.100.147 NaN 3 192.168.100.147 NaN 4 192.168.100.147 NaN 耗时: 0.00870203971862793s <class 'dict'>
基于ip2geotools的实现方案
实现代码
import time s_time = time.time() from ip2geotools.databases.noncommercial import DbIpCity df_2 = dt.loc[:50,['saddr']] def IP_info_2(ip): try: return DbIpCity.get(ip, api_key = 'free').country except: return np.nan df_2['country'] = df_2.loc[:, 'saddr'].apply(IP_info_2) print(df_2.head()) print('耗时:',str(time.time()-s_time)+'s') print(type(DbIpCity.get('48.151.136.76',api_key = 'free')))
运行结果
saddr country 0 192.168.100.147 ZZ 1 192.168.100.147 ZZ 2 192.168.100.147 ZZ 3 192.168.100.147 ZZ 4 192.168.100.147 ZZ 耗时: 25.913161039352417s <class 'ip2geotools.models.IpLocation'>
待解决问题
- 上述两种IP地理位置解析方案返回结果异常(geolite2返回NaN、DbIpCity返回ZZ且耗时过长)的问题应如何修复?
- 数据集中存在两类IP地址格式:第一类格式为
fe80::250:56ff:febe:254、fe80::250:56ff:febe:26db,第二类格式为192.168.100.46,二者的核心区别是什么? - 除IP对应的地理位置信息外,IP地址特征还有哪些可挖掘的方向,可用于提升模型效果?
解答
问题1:IP解析结果异常修复方案
两种方案返回异常的核心原因是测试使用的192.168.100.147属于私有内网IP,本身就没有公网归属地信息:
- geolite2返回NaN是正常表现:GeoLite2数据库本身不收录私有IP、保留IP的地理位置信息,查询这类IP时返回
None,现有代码逻辑就会输出NaN。 - DbIpCity返回ZZ是标准占位符:
ZZ是IP地理位置库通用的「未知/无对应归属地」编码,专门用来标记内网IP、环回地址这类没有公网归属的IP;耗时过长是因为免费接口采用逐次调用第三方在线服务的模式,每查一个IP都要发一次HTTP请求,50条数据跑25秒属于正常表现。
修复操作如下:
- 解析归属地前先做IP类型过滤,用Python标准库
ipaddress判断IP属性,私有IP、环回地址、链路本地地址直接标记为「内网」,不需要调用解析接口,判断逻辑参考:
import ipaddress def is_public_ip(ip_str): try: ip = ipaddress.ip_address(ip_str) return not ip.is_private and not ip.is_link_local and not ip.is_loopback except ValueError: return False
- 弃用DbIpCity的在线查询模式,换成本地GeoIP库查询,速度可以提升3个数量级以上,注意同步更新到最新版的GeoLite2数据库,避免公网IP查询遗漏。
- 公网IP查询不到归属时统一标记为「未知」,不要留空值影响后续模型训练。
问题2:两类IP格式的核心区别
两类IP属于不同版本的互联网协议地址:
- 格式类似
fe80::xxxx的是IPv6地址,地址长度128位,采用十六进制冒分表示,fe80开头的地址属于IPv6链路本地地址,和IPv4下的169.254.0.0/16段作用一致,仅在本地链路生效,跨路由器无法路由。 - 格式类似
192.168.100.46的是IPv4地址,地址长度32位,采用十进制点分表示,192.168开头的地址属于IPv4私有内网地址段,仅在局域网内生效,公网无法路由。
问题3:IP特征可挖掘方向
针对Bot-IoT这类流量检测场景,除了归属地,还可以从IP本身挖掘以下高价值特征:
- IP类型属性:是否为公网IP、是否为内网IP、是否为环回/组播/保留地址、属于IPv4还是IPv6,这类特征可以快速区分本地局域网流量和跨网流量。
- 网络段属性:提取IP对应的/24(IPv4)、/64(IPv6)网段,统计时间窗口内同网段出现的不同IP数量、同网段发起连接的频次,这类特征对扫描类攻击的识别度很高。
- 通信行为属性:统计单个IP作为源/目的的连接数、发送/接收的字节数占比、连接的不同端口数量、连接失败的比例,这类特征对识别C&C通信、DDoS攻击源效果明显。
- 威胁情报匹配:匹配公开恶意IP威胁情报库,打标IP是否在恶意IP清单内、是否为已知C&C服务器IP、是否属于Tor出口节点,这类特征对恶意流量检测的增益非常显著。
- 拓扑属性:计算IP在流量通信图里的度中心性、接近中心性,僵尸网络节点的通信拓扑特征和正常IoT设备存在明显差异。
内容的提问来源于stack exchange,提问作者LAT
相关产品推荐
相关产品推荐

