Batfish 网络配置分析工具教程
Batfish 是一款由 Intentionet 开发的开源网络配置分析工具,它可以在不影响生产网络的情况下,对网络设备配置进行离线建模和分析。Batfish 能够解析来自 Cisco、Juniper、Arista、Palo Alto 等多种厂商的配置文件,构建网络模型并回答关于路由、可达性、安全策略等方面的问题。它是网络变更前进行配置验证的理想工具。
一、安装 Batfish
1.1 使用 Docker 部署 Batfish 服务
# 拉取并运行 Batfish 容器
docker pull batfish/batfish
docker run -d --name batfish -v /opt/batfish/data:/data -p 9997:9997 -p 9996:9996 --restart unless-stopped batfish/batfish
1.2 安装 Python 客户端
pip3 install pybatfish
二、准备网络快照
Batfish 需要网络设备的配置文件作为输入。创建以下目录结构:
mkdir -p /opt/batfish/networks/mynetwork/configs
# 将设备配置文件放入 configs 目录
# 文件名建议使用设备主机名
cp router1.cfg /opt/batfish/networks/mynetwork/configs/
cp router2.cfg /opt/batfish/networks/mynetwork/configs/
cp switch1.cfg /opt/batfish/networks/mynetwork/configs/
cp firewall1.cfg /opt/batfish/networks/mynetwork/configs/
三、基本分析
#!/usr/bin/env python3
from pybatfish.client.commands import *
from pybatfish.question.bfq import *
from pybatfish.question import load_questions
# 连接到 Batfish 服务
bf_session.host = "localhost"
load_questions()
# 初始化网络快照
bf_set_network("mynetwork")
bf_init_snapshot("/opt/batfish/networks/mynetwork", name="snapshot1")
# 查看解析状态
parse_status = bfq.fileParseStatus().answer()
print(parse_status.frame())
# 获取节点(设备)列表
nodes = bfq.nodeProperties().answer()
print(nodes.frame())
四、路由分析
# 查看所有路由条目
routes = bfq.routes().answer()
print(routes.frame())
# 查询到特定前缀的路由
routes_to_dest = bfq.routes(
network="10.0.0.0/24"
).answer()
print(routes_to_dest.frame())
# 分析 BGP 会话状态
bgp_sessions = bfq.bgpSessionStatus().answer()
print(bgp_sessions.frame())
# 查看 BGP 路由通告
bgp_ribs = bfq.bgpRib().answer()
print(bgp_ribs.frame())
五、可达性分析
# 测试两个节点之间的可达性
traceroute = bfq.traceroute(
startLocation="router1",
headers=HeaderConstraints(
srcIps="10.0.1.1",
dstIps="10.0.2.1",
applications=["SSH"]
)
).answer()
print(traceroute.frame())
# 查找所有可以到达特定目标的路径
reachability = bfq.reachability(
pathConstraints=PathConstraints(startLocation="router1"),
headers=HeaderConstraints(dstIps="10.0.2.0/24"),
actions="SUCCESS"
).answer()
print(reachability.frame())
六、安全策略分析
# 分析 ACL/防火墙规则
acl_analysis = bfq.searchFilters(
headers=HeaderConstraints(
srcIps="0.0.0.0/0",
dstIps="10.0.1.100",
dstPorts="22",
ipProtocols=["TCP"]
),
action="PERMIT"
).answer()
print(acl_analysis.frame())
# 查找未使用的 ACL 规则
unused_rules = bfq.filterLineReachability().answer()
print(unused_rules.frame())
# 检查 ACL 中的冗余和冲突规则
acl_references = bfq.referencedStructures().answer()
七、配置变更验证
# 比较两个快照(变更前后)
bf_init_snapshot("/opt/batfish/networks/mynetwork_before", name="before")
bf_init_snapshot("/opt/batfish/networks/mynetwork_after", name="after")
# 比较路由表差异
diff_routes = bfq.routes(
snapshot="before",
reference_snapshot="after"
).answer()
# 比较可达性差异
diff_reach = bfq.differentialReachability(
pathConstraints=PathConstraints(startLocation="router1"),
headers=HeaderConstraints(dstIps="10.0.0.0/8")
).answer()
print(diff_reach.frame())
八、自动化集成
# 结合 CI/CD 流水线进行配置验证
# 在推送配置前使用 Batfish 检查
# 示例:检查变更是否会导致路由黑洞
def validate_network_change(before_dir, after_dir):
bf_init_snapshot(before_dir, name="before")
bf_init_snapshot(after_dir, name="after")
# 检查是否有路由丢失
diff = bfq.differentialReachability(
headers=HeaderConstraints(dstIps="0.0.0.0/0")
).answer()
if len(diff.frame()) > 0:
print("WARNING: 配置变更可能导致可达性变化!")
print(diff.frame())
return False
return True
总结
Batfish 为网络工程师提供了强大的配置分析能力,可以在变更推送前发现潜在问题。配合 Ansible 和 NAPALM 构建完整的自动化流水线:使用 Batfish 验证、NAPALM 推送、Ansible 编排。选购搬瓦工 VPS 请参考 全部方案,购买时使用优惠码 NODESEEK2026 可享受 6.77% 的优惠,通过 bwh81.net 进入官网购买。