Python+SSH网络自动化实战:批量巡检、备份与配置下发

📅 发布时间:2026/9/6 4:58:05
Python+SSH网络自动化实战:批量巡检、备份与配置下发 简介一份基于Python设计网络自动化运维程序的完整技术文档面向具备Python基础、从事网络运维、系统管理或IT自动化工作的技术人员及相关专业学生。内容以毕业设计论文形式呈现覆盖系统需求分析、SSH安全通信、华为eNSP模拟器环境搭建、FreeSSHd传输通道建立等核心环节重点梳理paramiko、re、time模块在设备远程连接、命令执行、信息采集与配置管理中的应用。包体为1个docx文档约1.89MB适合在中小型网络环境中学习路由器、交换机等设备的批量自动化管理。文档详细讲解了设备版本、接口状态、IP地址、内存使用等系统查询功能以及用户配置、访问控制、配置文件备份等自动化操作实现思路并结合完整代码与拓扑图进行验证已有107人学习下载。 晚上九点半值班手机突然响了。机房那边反馈核心交换机CPU飙升要我远程上去看一眼配置。我打开终端SSH登上去一条一条敲命令排查旁边还摆着十几个同样需要检查配置的分支机构设备清单。那一瞬间我就在想如果这些操作能写成一个脚本批量完成现在应该已经处理完两轮了。这就是我后来把所有网络设备的日常巡检、配置备份、批量下发全部迁到PythonSSH自动化方案上的直接原因。到今天这套东西已经在我手里稳定跑了两年多从最初几十行的小脚本慢慢长成了一个包括并发执行、日志记录、异常处理在内的完整工具集。这篇就把整个设计思路和实操过程写出来想做网络自动化的朋友可以直接照着抄。1. 为什么是PythonSSH网络自动化的最佳入门组合1.1 命令行依然是运维的基本盘先说个很多人爱问的问题现在SDN、NETCONF、RESTCONF炒得这么热为什么还要回头用SSH做自动化答案很简单你不可能一夜之间把所有设备全部升级成支持新协议的新款。我手头管理的设备里有最新的框式交换机也有服役快十年的老接入层设备它们唯一的共同点就是都支持SSH登录。尤其异构网络环境不同厂商、不同型号并存NETCONF在华为、H3C上支持程度不一思科老设备更是别指望。SSH命令行的方式就像普通话一样不管哪个厂商的设备都能听懂。还有一个现实问题运维团队的能力曲线。大多数人最熟悉的设备操作方式就是CLI对着命令行敲了十年命令突然让你学YANG模型、学RESTCONF数据结构学习成本实在太高。而PythonSSH的思路本质上没有任何新概念——你还是在对设备发命令只不过把“手敲”换成了“脚本发”。设备该怎么配还怎么配唯一变化的只是执行效率。1.2 Paramiko与Netmiko从“能用”到“好用”Python操作SSH的库主要有两个Paramiko和基于它封装的Netmiko。简单理解Paramiko是底层的SSH协议实现它负责建立连接、发送命令、拿回结果但它不关心你连的是交换机还是路由器。Netmiko是在Paramiko上面做了一层网络设备适配层内置了几十个厂商设备的命令交互逻辑自动处理分页、提示符匹配、异常回显这些问题。我的建议是如果只是临时连一台设备执行个命令直接用Paramiko就够了灵活且少一层依赖。但如果要写正经的运维工具直接上Netmiko。原因后面代码对比的时候你会看得很清楚——Netmiko帮你省掉的那部分代码恰恰是SSH自动化里最容易踩坑的地方比如命令回显截断、等待时间不足、登录横幅干扰等等。2. 动手前的基础准备2.1 Python环境与依赖安装环境准备这块没什么高深的Python 3.8以上版本就可以。Windows、Linux、macOS都行因为脚本跑在运维跳板机上与被管理的网络设备没有系统绑定关系。我自己的主力环境是CentOS跳板机Windows笔记本上也跑过都挺稳定。依赖安装只需要两条命令pip install paramiko pip install netmiko如果你所在环境访问外网源慢用国内镜像源速度能快一个量级pip install -i https://pypi.tuna.tsinghua.edu.cn/simple paramiko netmiko安装完验证一下python -c import paramiko, netmiko; print(ok)这里有个容易被忽略的点跳板机上如果同时装了Python 2和Python 3注意pip和python的版本对应关系。我遇到过同事在服务器上敲pip install结果装进了Python 2环境脚本一跑直接ImportError排查了半天。2.2 SSH密钥配置先解决免密登录写自动化脚本的第一原则尽量不要用密码登录。密码一是容易过期二是可能会被安全策略要求定期更换一旦密码变了你所有脚本全部失效。改成SSH密钥认证之后只要把公钥分发到设备上就不再担心密码变动的问题。生成密钥对ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa_network然后把公钥内容复制到网络设备上。不同厂商的配置方式不同华为设备大概长这样rsa peer-public-key admin-key public-key-code begin 粘贴公钥内容 public-key-code end peer-public-key end ssh user admin authentication-type rsa这段配置在不同版本上命令略有差异我遇到过VRP5和VRP8版本之间命令写法不一致的情况实操时以你设备的版本为准。核心思想就是把跳板机的公钥注册到设备上并将SSH用户的认证方式设置为RSA。2.3 网络设备端开启SSH服务如果设备还没开SSH脚本写得再好也白搭。华为交换机开启SSH的一套基础命令大致涉及system-view stelnet server enable rsa local-key-pair create ssh user admin authentication-type password ssh user admin service-type stelnet user-interface vty 0 4 protocol inbound ssh思科IOS设备类似但命令体系完全不同ip domain-name example.com crypto key generate rsa ip ssh version 2 username admin privilege 15 secret yourpassword line vty 0 4 transport input ssh这里务必注意开启SSH的时候不要把原有的Telnet直接关掉万一SSH配置有问题你还有条后路。我吃过这个亏有台核心设备改SSH时把Telnet关了结果SSH协商一直失败最后只能跑机房用console线救回来。正确做法是先开SSH、验证能连上再逐步收紧VTY的入站协议。3. 核心代码实现从单台到批量3.1 第一版用Paramiko连接一台设备先看最朴素的写法。用Paramiko连一台华为交换机执行display version然后退出import paramiko ssh paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect( hostname192.168.1.1, port22, usernameadmin, passwordadmin123, timeout10 ) stdin, stdout, stderr ssh.exec_command(display version) output stdout.read().decode() print(output) ssh.close()这个脚本功能上没问题但有个隐藏缺点exec_command是“发一条命令收一条结果”的模式每次执行相当于开一个独立的shell会话设备上的配置模式、当前视图不会被保留。比如你想进入系统视图连续配置好几条命令这种写法就不行了。想要连续交互得用invoke_shell类似手动SSH登录后那个交互式命令行import paramiko ssh paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname192.168.1.1, port22, usernameadmin, passwordadmin123, timeout10) shell ssh.invoke_shell() shell.send(system-view\n) shell.send(sysname TEST-SW\n) import time time.sleep(1) output shell.recv(65535).decode() print(output) ssh.close()这套代码里sleep用得非常难受时间短了命令还没执行完时间长了浪费时间。真实场景中一台设备几十条命令每条都sleep的话效率惨不忍睹。这个痛点直到我换成Netmiko才算彻底解决。3.2 用Netmiko重写代码量直接减半Netmiko对上面的问题做了封装send_command自动等待命令执行完成send_config_set自动进入配置模式并逐条下发你不需要手动sleep。批量连接两台设备执行巡检命令的示例from netmiko import ConnectHandler devices [ { device_type: huawei, host: 192.168.1.1, username: admin, password: admin123, timeout: 20, }, { device_type: huawei, host: 192.168.1.2, username: admin, password: admin123, timeout: 20, }, ] for dev in devices: print(f正在连接 {dev[host]} ...) conn ConnectHandler(**dev) version conn.send_command(display version) cpu conn.send_command(display cpu-usage) print(f {dev[host]} 版本信息 ) print(version) print(f {dev[host]} CPU使用率 ) print(cpu) conn.disconnect()注意device_type这个参数Netmiko靠它判断设备和厂商的命令交互细节。华为是huawei思科IOS是cisco_iosH3C是hp_comware锐捷是ruijie_os。这样一台台连接还是串行设备多了效率不够后面会讲并发。3.3 批量备份设备配置一个可以立刻用起来的脚本配置备份是网络运维里需求最刚性、也是最容易第一时间跑起来的自动化场景。不需要变更设备配置、只读不写风险极低。下面这个脚本读取devices.txt逐台执行display current-configuration结果按IP和日期命名保存到本地import time from netmiko import ConnectHandler def backup_device(dev): host dev[host] print(f开始备份 {host}) conn ConnectHandler(**dev) output conn.send_command(display current-configuration) filename fconfig_{host}_{time.strftime(%Y%m%d_%H%M%S)}.txt with open(filename, w, encodingutf-8) as f: f.write(output) conn.disconnect() print(f{host} 备份完成文件: {filename}) devices [ { device_type: huawei, host: 192.168.1.1, username: admin, password: admin123, }, ] if __name__ __main__: for dev in devices: backup_device(dev)设备清单建议放在外部文件里脚本用循环读取。我用的是最简方案一个存设备IP的txt、一个存账号密码的配置模块。等设备量大了再考虑上数据库、上Web界面。初期别过度设计够用就行。提醒备份出来的配置文件里包含明文密码和密钥属于敏感信息存放目录记得做权限控制别扔在/web目录下被人直接访问。4. 批量配置下发与运维场景实战4.1 批量修改设备配置的完整流程配置变更是运维自动化里价值最高、同时风险也最高的场景。和备份不同下发配置会对现网产生实际影响千万不能脚本一写就冲着生产设备直接跑。我总结了一套相对安全的流程先备份再下发最后验证。这三个步骤缺一不可。批量下发脚本至少应该包含连接前检查设备是否可达、下发前完整备份当前配置、下发后自动执行验证命令核对结果。一个批量下发端口配置的示例from netmiko import ConnectHandler devices [ {device_type: huawei, host: 192.168.1.1, username: admin, password: admin123}, {device_type: huawei, host: 192.168.1.2, username: admin, password: admin123}, ] config_commands [ interface GigabitEthernet0/0/1, port link-type access, port default vlan 100, description auto-configured-by-python, ] for dev in devices: conn ConnectHandler(**dev) output conn.send_config_set(config_commands) print(f {dev[host]} 下发结果 ) print(output) verify conn.send_command(display current-configuration interface GigabitEthernet0/0/1) print(f {dev[host]} 验证结果 ) print(verify) conn.disconnect()这里send_config_set是关键它自动从用户视图进入系统视图、逐条下发命令、最后返回到用户视图。整个过程不用你操心模式切换。4.2 并发执行几十台设备等不起串行串行脚本在设备数量少的时候问题不大但量级上来之后就很痛苦。假设每台设备交互耗时10秒50台设备就是500秒将近十分钟。用并发可以把总时间压缩到十分之一以下。Python的concurrent.futures处理这种场景很方便from concurrent.futures import ThreadPoolExecutor, as_completed from netmiko import ConnectHandler devices [ {device_type: huawei, host: 192.168.1.1, username: admin, password: admin123}, # ... 更多设备 ] def backup_one(dev): conn ConnectHandler(**dev) output conn.send_command(display current-configuration) conn.disconnect() return dev[host], output with ThreadPoolExecutor(max_workers10) as executor: futures {executor.submit(backup_one, dev): dev for dev in devices} for future in as_completed(futures): dev futures[future] try: host, output future.result() print(f{host} 执行成功配置长度 {len(output)}) except Exception as e: print(f{dev[host]} 执行失败: {e})max_workers建议从5到10开始调不要上来就开50个线程。网络设备CPU和SSH连接数都有上限并发太大容易把设备搞出问题尤其是那些老旧的接入设备SSH并发连接数超过一定值就会出现认证超时。4.3 日志记录与异常处理设计自动化脚本大规模跑起来之后日志就变得至关重要。几十台设备跑完你要能快速回答三个问题哪些成功了哪些失败了失败原因是什么我在脚本里习惯用logging模块同时输出到控制台和文件import logging logging.basicConfig( levellogging.INFO, format%(asctime)s - %(name)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(network_auto.log, encodingutf-8), logging.StreamHandler() ] ) logger logging.getLogger(__name__)在关键操作点插入logger.info和logger.error跑完之后直接看日志文件比盯着屏幕输出靠谱得多。尤其并发场景下多线程输出会交错在一起落盘到文件之后按设备IP或者线程号一过滤问题定位就很容易。5. 常见问题与排查技巧实录5.1 高频问题速查表问题现象可能原因解决办法连接超时 timeout设备侧SSH服务未开启或端口不通先手动SSH测试确认端口可达检查VTY配置Authentication failed用户名密码错误或密钥未注册手动登录设备验证凭据检查SSH用户认证方式命令回显不完整设备输出分页未关闭用Netmiko会自动处理Paramiko需先执行screen-length 0 temporary某些命令提示未授权账号权限不足改用privilege级别高的账号或提前在设备上配好命令授权中文注释乱码终端编码不匹配统一使用utf-8编码设备端注意language-mode切换并发过高导致设备无响应SSH连接数超限降低max_workers或对设备分批执行5.2 实操中踩过的一些坑第一个坑是华为设备的分页问题。如果直接用Paramiko执行display current-configuration大概率只能拿到部分输出因为设备输出分页后停在---- More ----等待你按键。Netmiko内部自动发送空格翻页Paramiko就得自己处理shell.send(screen-length 0 temporary\n)这条命令临时取消分页当前会话内生效非常实用。第二个坑是命令回显等待时间。老设备执行display current-configuration可能耗时十几秒如果超时时间设置太短会拿不到完整结果。Netmiko的send_command有个delay_factor参数专门应对慢设备output conn.send_command(display current-configuration, delay_factor2)第三个坑是设备型号差异。前面说过各家设备命令不一样其实同一厂商不同系列、不同软件版本的命令也可能有差异。我在华为S5700和S12700上就遇到过display命令输出格式不一样的情况。所以脚本里的解析逻辑务必用真实设备输出验证过再上批量。5.3 从脚本到工具的三个进阶方向如果基础批量执行已经跑顺了可以往这几个方向扩展一是资产清单管理。把设备IP、型号、厂商、登录方式、密码等信息从代码里拆出来放到数据库或配置中心里脚本和资产数据解耦加一台设备只需要录一条数据。二是定时任务调度。用crontab或者更好的方案是直接上个简单的调度平台Jenkins也能干这个活每天凌晨自动执行巡检和备份脚本早上到公司直接看报告。三是Web可视化。给运维团队做个简单的操作界面让不会写Python的同事也能点点按钮完成批量下发。Flask前端表格就能搞定数据量不大不需要上太重的框架。6. 写在最后的几点真实体会这套自动化方案从第一个Paramiko脚本到现在已经迭代了差不多两年。最大的感受不是“脚本帮我省了多少时间”而是它把运维工作的确定性提高了。手工敲命令总有疏漏脚本虽然也会出错但出错是稳定的出、一致的出能被发现、能被修复这种可预期性在运维里太难得了。如果你正在犹豫要不要投入精力搞这个方向我的建议是别一上来就研究那些高大上的自动化框架。先把SSH登录、批量执行、配置备份这三件事做扎实你的运维效率就已经比大多数人高出一个档次了。再往后不管是学Ansible还是学Nornir有了这个基础上手都会快很多。最后再分享一个小经验自动化脚本上线之前先在测试设备上完整跑三遍以上确认输出结果稳定后再碰生产。第一遍跑可能成功不代表第二遍还能成功网络设备的状态是在不断变化的。运维这个行当稳永远比快重要。本文还有配套的精品资源点击获取