如何用MaxMind GeoLite2数据库分析fail2ban拦截的恶意IP?附Python代码示例
如何用MaxMind GeoLite2数据库分析fail2ban拦截的恶意IP附Python代码示例在服务器运维工作中fail2ban作为一款经典的入侵防御工具能够有效拦截暴力破解、恶意扫描等攻击行为。但单纯的拦截记录往往缺乏全局视角——攻击者究竟来自哪些地区是否存在明显的聚集特征这些问题的答案对于优化安全策略至关重要。本文将手把手教你如何通过MaxMind的GeoLite2数据库将枯燥的IP列表转化为直观的地理分布报告。1. 环境准备与数据源获取1.1 fail2ban数据库解析默认情况下fail2ban使用SQLite数据库存储拦截记录路径通常为/var/lib/fail2ban/fail2ban.sqlite3。通过以下命令可以快速查看数据库结构sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 SELECT name FROM sqlite_master WHERE typetable;关键表结构说明表名存储内容关键字段bips被禁止的IP及触发次数ip, failures, timebans当前生效的封禁记录ip, jail, timeofbanlogs历史日志记录ip, time, action提示实际操作前建议备份数据库文件避免误操作影响fail2ban正常运行。1.2 GeoLite2数据库获取MaxMind提供免费的GeoLite2数据库需注册账号后下载访问MaxMind官网注册账户进入下载页面选择GeoLite2 City版本下载.mmdb格式数据库文件约50-60MB推荐下载的数据库版本GeoLite2-City包含城市级地理位置信息GeoLite2-ASN包含IP所属AS网络信息2. Python地理信息查询实战2.1 基础环境配置安装必要的Python库pip install geoip2 sqlite3 pandas matplotlib初始化GeoIP2读取器import geoip2.database reader geoip2.database.Reader(GeoLite2-City.mmdb)2.2 IP地理信息查询函数def get_geo_info(ip_address): try: response reader.city(ip_address) return { country: response.country.name, region: response.subdivisions.most_specific.name, city: response.city.name, latitude: response.location.latitude, longitude: response.location.longitude } except Exception as e: return {error: str(e)}典型返回数据结构示例{ country: United States, region: California, city: Mountain View, latitude: 37.386, longitude: -122.0838 }3. 完整数据分析流程3.1 从fail2ban提取IP数据import sqlite3 def extract_banned_ips(db_path): conn sqlite3.connect(db_path) cursor conn.cursor() # 获取最近30天的封禁IP cursor.execute( SELECT ip, COUNT(*) as count FROM bips WHERE time datetime(now, -30 days) GROUP BY ip ORDER BY count DESC ) results cursor.fetchall() conn.close() return [{ip: row[0], count: row[1]} for row in results]3.2 生成地理分布报告结合Pandas进行数据分析import pandas as pd def generate_report(ip_data): df pd.DataFrame(ip_data) # 添加地理信息列 df[geo] df[ip].apply(get_geo_info) # 展开地理信息 geo_df pd.json_normalize(df[geo]) final_df pd.concat([df, geo_df], axis1) # 按国家统计 country_stats final_df.groupby(country).agg({ count: sum, ip: count }).rename(columns{ip: unique_ips}) return final_df, country_stats.sort_values(count, ascendingFalse)4. 可视化与进阶分析4.1 使用Matplotlib绘制攻击热力图import matplotlib.pyplot as plt def plot_attack_map(geo_df): plt.figure(figsize(12, 8)) plt.scatter( xgeo_df[longitude], ygeo_df[latitude], sgeo_df[count]*10, # 点大小代表攻击次数 alpha0.5, cred ) plt.title(Global Attack Distribution) plt.xlabel(Longitude) plt.ylabel(Latitude) plt.grid() plt.show()4.2 自动化分析脚本架构推荐的项目目录结构/geo_analysis/ │── config.py # 配置文件 │── main.py # 主程序 │── utils/ # 工具函数 │ ├── geo.py # 地理查询功能 │ └── db.py # 数据库操作 │── data/ # 数据存储 │ ├── fail2ban.db # 数据库备份 │ └── GeoLite2/ # GeoIP数据库 └── reports/ # 生成报告定时任务设置crontab示例0 3 * * * /usr/bin/python3 /path/to/geo_analysis/main.py --daily-report在实际运维中我们发现约65%的暴力破解攻击集中在10个特定国家/地区。通过将fail2ban的自动封禁与地理分析结合可以针对高频攻击来源实施更严格的访问控制策略如直接屏蔽特定国家IP段。