Netmiko 网络自动化详解
核心概念 Netmiko 是 Python 网络自动化库,简化 SSH 连接和多厂商设备配置管理。
1. 基础定义与底层架构
1.1. 什么是 Netmiko
Netmiko = net(网络设备) + miko(Paramiko),基于 Paramiko 开发的高层 SSH 网络设备专用库,专门解决路由器、交换机、防火墙、负载均衡等网络设备自动化运维问题。
核心定位:屏蔽各厂商 CLI 差异,提供统一API,自动处理网络设备独有的交互痛点,原生适配 80+ 设备系统。
1.2. 底层依赖与分层结构
- 底层:Paramiko(TCP 加密通道、SSH 协议、SFTP 文件传输)
- 中间层:Netmiko 设备驱动(每种厂商一套独立驱动,处理提示符、分页、模式切换)
- 应用层:统一对外方法
send_command()/send_config_set()/enable()等,一套代码兼容多厂商
1.3. 为什么不用原生 Paramiko 操作交换机?(核心痛点对比)
| | | |
|---|---|---|
|网络设备特有问题|原生 Paramiko 需要手动处理|Netmiko 自动内置处理|
|分页 --More--|自己循环发送空格/回车翻页|自动关闭分页 terminal length 0,一次性返回完整输出|
|模式切换(用户→特权→全局配置)|手动发送 enable、判断#提示符|内置 enable()、自动进出配置模式|
|多厂商提示符不同(#、>、[Huawei])|正则自定义匹配结束符,极易出错|驱动内置正则自动识别设备提示符|
|配置下发、保存配置命令不统一|Cisco write memory / 华为 save 手动区分|save_config() 自动适配厂商|
|命令执行阻塞、缓冲区卡死|自行写循环读取 stdout 释放缓冲区|底层封装流式读取,无阻塞风险|
|特权密码、会话超时、延迟适配|全部手动配置延时等待|global_delay_factor 统一延时控制|
简单总结:Paramiko 适合 Linux 服务器通用 SSH;Netmiko 专为网络交换机/路由器设计,开箱即用。
1.4. 安装
# Python3.7+
pip install netmiko
# 依赖 cryptography(Paramiko 加密库),自动附带
2. 核心核心概念:device_type 设备类型(最关键参数)
device_type 决定加载哪一套厂商驱动,写错直接登录失败、命令无返回。
2.1. 主流厂商常用类型
| | |
|---|---|
|device_type|适用设备|
|cisco_ios|Cisco 2960/3650/ISR 路由器交换机 IOS/IOS-XE|
|cisco_nxos|Cisco N9K、N5K 数据中心交换机|
|cisco_asa|Cisco ASA 防火墙|
|huawei / huawei_vrp|华为交换机、AR 路由器|
|hp_comware|华三 H3C、HP Comware|
|arista_eos|Arista 云交换机|
|juniper_junos|瞻博 Juniper 设备|
|fortinet|飞塔防火墙|
|linux|也可连接 Linux 服务器(兼容 Paramiko 能力)|
3. 连接参数完整详解(ConnectHandler 入参字典)
from netmiko import ConnectHandler
device = {
# 必选核心参数
"device_type": "cisco_ios", # 设备类型,驱动标识
"host": "192.168.1.1", # 设备IP
"username": "admin",
"password": "Admin@123",
# 特权模式密码(Cisco enable 密码,华为不需要)
"secret": "Enable@456",
# 可选超时控制(生产必须配置,防止脚本卡死)
"port": 22,
"timeout": 30, # TCP 连接超时
"banner_timeout": 15, # 等待设备SSH banner超时
"session_timeout": 120, # 整个会话空闲超时
"global_delay_factor": 1, # 全局延迟倍数,设备响应慢设2/3
# 性能优化
"fast_cli": True, # 快速CLI模式,大幅缩短命令等待时间
# 日志/审计
"session_log": "switch_192.168.1.1.log", # 完整会话交互日志
# 私钥免密登录(替代password)
"private_key": "/root/.ssh/id_rsa"
}
3.1. 连接两种写法
- 常规手动关闭
net_conn = ConnectHandler(**device)
# 业务操作
net_conn.disconnect()
- with 上下文管理器(推荐,自动释放连接,不会句柄泄露)
with ConnectHandler(**device) as net_conn:
out = net_conn.send_command("show version")
# 离开代码块自动 disconnect
4. 五大高频核心方法(生产90%场景只用这5个)
4.1. enable() 进入特权模式(Cisco 系列必备)
Cisco 设备默认 > 用户模式,无法查看完整配置、无法修改配置;执行 enable() 自动输入secret密码,进入 # 特权模式。
with ConnectHandler(**device) as net_conn:
net_conn.enable() # 自动切换特权
run_config = net_conn.send_command("show running-config")
4.2. send_command(command) 执行查看类查询命令(只读)
用于 show display 等不修改设备的查询命令,自动处理分页、等待提示符、返回完整字符串。
返回值是完整输出文本,搭配之前讲的 """.join().strip() 清洗输出:
output = net_conn.send_command("show ip interface brief")
clean_out = output.strip()
# 多行拆分列表
lines = output.splitlines()
关键可选参数:
delay_factor=2:单次命令额外延时,老旧设备响应慢使用expect_string:自定义结束匹配符,特殊设备适配
4.3. send_config_set(config_list / config_file) 批量下发配置(写操作)
自动进入全局配置模式、逐条下发命令、下发完成自动退出配置模式。
4.3.1. 方式1:列表传入多条配置
configs = [
"vlan 100",
"name TEST_VLAN",
"interface Gi0/1",
"switchport access vlan 100"
]
result = net_conn.send_config_set(configs)
4.3.2. 方式2:读取本地配置文件下发(生产标准流程,Git管理配置文件)
result = net_conn.send_config_from_file("./vlan_config.txt")
4.3.3. 关键参数
exit_config_mode=False:下发完不退出配置模式,适合连续多批次配置
4.4. save_config() 保存设备运行配置到启动配置
厂商自适应,无需区分命令:
- Cisco:自动执行
write memory - 华为/H3C:自动执行
save/save force
net_conn.send_config_set(["interface loopback 0", "ip address 1.1.1.1 255.255.255.255"])
net_conn.save_config() # 永久保存,重启不丢失
4.5. disconnect() 关闭SSH连接
with 语法自动执行;循环批量脚本必须手动关闭,防止 too many open files 句柄耗尽。
5. 配套高级能力(备份、文件传输、会话日志)
5.1. 文件传输 file_transfer(上传/下载设备固件、配置文件)
底层基于 SFTP,用于备份固件、下发升级包、导出日志文件。
from netmiko import file_transfer
# 本地文件上传到交换机flash
transfer_result = file_transfer(
net_conn,
source_file="new_firmware.bin",
dest_file="flash:/new_firmware.bin",
direction="put", # put上传 get下载
overwrite_file=True
)
print(transfer_result["file_transferred"]) # True=传输成功
5.2. 会话日志 session_log
连接参数传入 session_log="xxx.log",完整记录收发所有交互字符,用于故障排查、等保审计,完整复现人机操作。
5.3. 设备自动类型检测 SSHDetect
未知厂商设备自动识别 device_type,批量巡检未知机房设备使用:
from netmiko import SSHDetect, DetectNetmiko
detector = SSHDetect(**device)
best_match = detector.autodetect()
print("识别设备类型:", best_match)
6. 完整生产示例1:单台交换机备份配置(最常用场景)
from netmiko import ConnectHandler
from datetime import datetime
import os
device = {
"device_type": "cisco_ios",
"host": "192.168.1.1",
"username": "admin",
"password": "Admin@123",
"secret": "Enable@456",
"timeout": 20,
"global_delay_factor": 1
}
# 创建备份目录
backup_dir = "./network_backup"
os.makedirs(backup_dir, exist_ok=True)
today = datetime.now().strftime("%Y%m%d")
file_name = f"{device['host']}_{today}_running.cfg"
try:
with ConnectHandler(**device) as conn:
conn.enable()
config = conn.send_command("show running-config")
# 写入本地备份文件
with open(f"{backup_dir}/{file_name}", "w", encoding="utf-8") as f:
f.write(config.strip())
print(f"备份成功,文件:{file_name}")
except Exception as e:
print(f"备份失败:{str(e)}")
7. 并发批量处理(多线程批量备份全网设备)
使用 ThreadPoolExecutor,每个线程独立创建连接,禁止多线程共享同一个 ConnectHandler 实例:
from concurrent.futures import ThreadPoolExecutor
from netmiko import ConnectHandler, NetmikoTimeoutException, NetmikoAuthenticationException
# 设备清单列表
devices_list = [
{"device_type": "cisco_ios", "host": "192.168.1.1", "username": "admin", "password": "xxx", "secret": "xxx"},
{"device_type": "huawei", "host": "192.168.1.2", "username": "admin", "password": "xxx"},
]
def backup_single(dev):
try:
with ConnectHandler(**dev) as conn:
if dev["device_type"].startswith("cisco"):
conn.enable()
cfg = conn.send_command("show run")
else:
cfg = conn.send_command("dis cur")
return (dev["host"], True, cfg.strip())
except NetmikoTimeoutException:
return (dev["host"], False, "连接超时")
except NetmikoAuthenticationException:
return (dev["host"], False, "账号密码错误")
except Exception as e:
return (dev["host"], False, str(e))
# 最大并发10台,防止大量TCP连接打满设备SSH会话限制
with ThreadPoolExecutor(max_workers=10) as pool:
res = pool.map(backup_single, devices_list)
for ip, status, msg in res:
if status:
print(f"[{ip}] 备份成功")
else:
print(f"[{ip}] 失败:{msg}")
8. 完整异常体系(生产脚本必须捕获)
Netmiko 内置专属异常,区分网络、认证、命令错误,比通用 Exception 精准:
from netmiko.exceptions import (
NetmikoTimeoutException, # TCP连接超时/设备不可达
NetmikoAuthenticationException, # 用户名密码/特权密码错误
NetMikoException, # Netmiko通用基类异常
ConfigException # 下发配置语法错误、设备拒绝配置
)
8.1. 捕获模板
try:
conn = ConnectHandler(**device)
except NetmikoTimeoutException:
print("设备IP不通、防火墙拦截22端口")
except NetmikoAuthenticationException:
print("账号/密码/Enable密码错误")
except ConfigException as e:
print("配置命令语法错误:", e)
9. Netmiko vs Paramiko 完整区分(你之前学习过Paramiko)
| | | |
|---|---|---|
|维度|Netmiko|Paramiko|
|定位|网络交换机/路由器专用高层库|通用底层SSH协议库,不限设备|
|分页处理|自动关闭分页,无需手动处理 --More--|必须自己写循环翻页逻辑|
|模式切换|内置enable、自动进出配置模式|完全无概念,需手动发送命令识别提示符|
|多厂商兼容|一套API,device_type区分驱动|无厂商适配,全部交互逻辑手写|
|配置保存|save_config() 自动适配各厂商命令|需要判断设备类型拼接write/save|
|适用场景|网络自动化、批量备份、批量下发VLAN/ACL|Linux服务器运维、堡垒机、通用WebSSH|
|底层依赖|封装Paramiko|原生SSH协议实现,无依赖|
10. 生产最佳实践&避坑指南
- 优先使用 with 上下文管理器,自动断开连接,杜绝句柄泄露;
- 批量脚本必须加线程并发限制(max_workers≤15),防止设备SSH会话满;
- 所有连接配置
timeout/global_delay_factor,老旧设备设置global_delay_factor=2; - 下发配置前先备份 running-config,出错可回滚;
- 禁止硬编码账号密码,放入加密配置文件,权限600;
- 开启
session_log会话日志,用于故障审计、配置变更追溯; - 下发批量配置后必须调用
save_config(),否则重启配置丢失; - 多线程每个线程独立创建
ConnectHandler,连接实例不可共享; - 下发高危配置(删除VLAN、ACL)增加重试校验逻辑,先查询再修改;
- 搭配 TextFSM/Genie 解析
show文本输出,把纯文本转为结构化字典,便于监控告警、自动化判断。
11. 配套生态工具(网络自动化全家桶)
- TextFSM / Genie Parser:解析 Netmiko 获取的命令输出,文本→结构化数据字典;
- Nornir:上层调度框架,搭配 Netmiko 做大规模多设备任务编排;
- NAPALM:更高层统一抽象,底层可调用 Netmiko,标准化获取接口、ARP、路由表;
- Scrapli:Netmiko 现代异步替代,性能更高,适合超大集群并发。
关联文档