Netmiko 简介
Netmiko 通过提供统一的界面来管理来自不同厂商的设备,从而简化了对网络设备的 SSH 管理。
主要用途
- 建立与设备的 SSH 连接
- 执行、检索和格式化 show 命令
- 发送配置命令
安装 Netmiko
Netmiko 不是 Python 标准库的一部分,需要使用 pip 进行安装:
pip install netmiko
Netmiko 会自动安装以下依赖项:Paramiko、scp、pyserial 和 textfsm。
验证安装:在 Python shell 中导入测试
import netmiko
基础连接
连接单个设备
from netmiko import ConnectHandler
connection = ConnectHandler(
host="172.16.10.12",
username="admin",
password="cisco",
device_type="cisco_ios"
)
output = connection.send_command("show ip interface brief")
print(output)
connection.disconnect()
输出示例:
Interface IP-Address OK? Method Status Protocol
FastEthernet0/0 172.16.10.12 YES NVRAM up up
FastEthernet0/1 unassigned YES NVRAM administratively down down
Loopback0 1.1.1.0 YES manual up up
Loopback2 1.1.1.2 YES manual up up
重要提示:
- 确保 Cisco 设备已正确配置 SSH 访问
- Python 工作站可以成功通过 SSH 连接到该设备
- 务必使用
disconnect()方法断开 SSH 会话
使用字典管理设备信息
为什么使用字典?
使用 Python 字典可以让设备信息更有序、更易于管理和重复使用。
基本用法
from netmiko import ConnectHandler
# 定义设备信息
SW_01 = {
"device_type": "cisco_ios",
"host": "172.16.10.12",
"username": "admin",
"password": "cisco"
}
# 使用字典解包连接设备
connection = ConnectHandler(**SW_01)
# 执行命令
output = connection.send_command('show interface desc')
print(output)
# 断开连接
connection.disconnect()
输出示例:
Interface Status Protocol Description
Fa0/0 up up
Fa0/1 admin down down
启用特权 EXEC 模式
为什么需要特权模式?
某些命令(如 show run)需要更高的权限才能执行。
实现方法
from netmiko import ConnectHandler
SW_01 = {
"device_type": "cisco_ios",
"host": "172.16.10.12",
"username": "admin",
"password": "cisco",
"secret": "cisco123" # Enable 密码
}
connection = ConnectHandler(**SW_01)
# 进入特权模式
connection.enable()
# 验证当前模式
device_prompt = connection.find_prompt()
print(device_prompt) # 应显示 '#' 提示符
# 执行需要特权的命令
output = connection.send_command('show run')
print(output)
connection.disconnect()
设备配置
进入全局配置模式
from netmiko import ConnectHandler
SW_01 = {
"device_type": "cisco_ios",
"host": "172.16.10.11",
"username": "admin",
"password": "cisco",
"secret": "cisco123"
}
connection = ConnectHandler(**SW_01)
connection.enable()
# 进入全局配置模式
connection.config_mode()
# 执行配置命令
connection.send_command('access-list 1 permit any')
# 退出全局配置模式
connection.exit_config_mode()
# 验证配置
show_output = connection.send_command('show interface desc')
print(show_output)
connection.disconnect()
安全处理密码
使用 getpass 保护密码
为什么要用 getpass?
- 避免在代码中以明文形式存储密码
- 提高脚本安全性
- 密码输入时不会在终端显示
from netmiko import ConnectHandler
import getpass
# 安全地提示用户输入密码
passwd = getpass.getpass('Please enter the password: ')
SW_01 = {
"device_type": "cisco_ios",
"host": "172.16.10.11",
"username": "admin",
"password": passwd,
"secret": passwd
}
connection = ConnectHandler(**SW_01)
connection.enable()
output = connection.send_command('show interface desc')
print(output)
connection.disconnect()
发送多个命令
使用 send_config_set 方法
这个方法可以一次性发送多个配置命令,自动处理进入和退出配置模式。
from netmiko import ConnectHandler
import getpass
passwd = getpass.getpass('Please enter the password: ')
SW_01 = {
"device_type": "cisco_ios",
"host": "172.16.10.11",
"username": "admin",
"password": passwd,
"secret": passwd
}
connection = ConnectHandler(**SW_01)
connection.enable()
# 定义配置命令列表
config_commands = [
'interface gi0/0',
'description WAN',
'exit',
'access-list 1 permit any'
]
# 批量发送配置命令
connection.send_config_set(config_commands)
# 验证配置
print(connection.send_command('show interfaces description'))
print(connection.send_command('show access-lists'))
connection.disconnect()
连接多个设备
批量管理设备
from netmiko import ConnectHandler
import getpass
import json
passwd = getpass.getpass('Please enter the password: ')
# 设备 IP 列表
ip_list = ["172.16.10.11", "172.16.10.12"]
# 创建设备列表
device_list = []
for ip in ip_list:
device = {
"device_type": "cisco_ios",
"host": ip,
"username": "admin",
"password": passwd,
"secret": passwd
}
device_list.append(device)
# 打印设备列表(格式化输出)
json_formatted = json.dumps(device_list, indent=4)
print(json_formatted)
# 遍历并连接每个设备
for each_device in device_list:
connection = ConnectHandler(**each_device)
connection.enable()
print(f'Connecting to {each_device["host"]}')
output = connection.send_command('show run | incl hostname')
print(output)
print(f'Closing Connection on {each_device["host"]}')
connection.disconnect()
高级配置管理
向多个设备发送配置
from netmiko import ConnectHandler
# 定义多个设备
devices = [
{
'device_type': 'cisco_ios',
'ip': '172.16.10.11',
'username': 'admin',
'password': 'cisco',
'secret': 'cisco123',
},
{
'device_type': 'cisco_ios',
'ip': '172.16.10.12',
'username': 'admin',
'password': 'cisco',
'secret': 'cisco123',
},
]
# 遍历设备并配置
for device in devices:
print(f"Connecting to {device['ip']}...")
net_connect = ConnectHandler(**device)
net_connect.enable()
# 配置设备
config_commands = ['username admin pri 15 password cisco']
net_connect.send_config_set(config_commands)
net_connect.save_config()
# 显示更新后的配置
output = net_connect.send_command('show running-config | section username')
print(output)
print(f'Closing Connection on {device["ip"]}')
net_connect.disconnect()
从文件应用配置
from netmiko import ConnectHandler
device = {
'device_type': 'cisco_ios',
'ip': '172.16.10.11',
'username': 'admin',
'password': 'cisco',
'secret': 'cisco123',
}
file = "config_file.cfg"
# 使用上下文管理器
with ConnectHandler(**device) as net_connect:
output = net_connect.send_config_from_file(file)
output += net_connect.save_config()
print(output)
异常处理
处理常见错误
在网络自动化中,异常处理至关重要,可以优雅地处理超时和认证失败等问题。
from netmiko import ConnectHandler
from netmiko.ssh_exception import NetmikoTimeoutException, NetmikoAuthenticationException
devices = [
{
'device_type': 'cisco_ios',
'ip': '172.16.10.11',
'username': 'admin',
'password': 'cisco123', # 错误的密码
},
{
'device_type': 'cisco_ios',
'ip': '172.16.10.12', # 错误的 IP
'username': 'admin',
'password': 'cisco',
}
]
# 尝试连接并处理异常
for device in devices:
try:
net_connect = ConnectHandler(**device)
output = net_connect.send_command("show ip int brief")
print(output)
except NetmikoTimeoutException:
print(f"Device {device['ip']} not reachable")
except NetmikoAuthenticationException:
print(f"Authentication failed for {device['ip']}")
备份设备配置
自动化配置备份
from netmiko import ConnectHandler
from datetime import datetime
devices = [
{
"host": "172.16.10.11",
"username": "admin",
"password": "cisco",
"device_type": "cisco_ios",
},
{
"host": "172.16.10.12",
"username": "admin",
"password": "cisco",
"device_type": "cisco_ios",
}
]
# 获取当前时间戳
time_stamp = datetime.now().strftime("%d-%b-%Y")
# 备份每个设备的配置
for device in devices:
net_connect = ConnectHandler(**device)
print(f"Initiating running config backup for {device['host']}...")
sh_run = net_connect.send_command('show run')
# 保存到文件
with open(f"{device['host']}_{time_stamp}.cfg", 'w') as f:
f.write(sh_run)
print("Backup saved")
print("Finished backup process.")
总结
Netmiko 的主要优势:
- 简化 SSH 管理:统一的接口处理不同厂商设备
- 批量操作:轻松管理多个网络设备
- 安全性:支持安全的密码处理
- 灵活性:支持单个命令或批量配置
- 可靠性:内置异常处理机制
通过掌握 Netmiko,网络工程师可以显著提高网络管理效率,实现配置自动化和标准化。
参考资源
原文转载:https://python-automation-book.readthedocs.io/en/1.0/12_netmiko/01_netmiko.html#sending-multiple-commands