如何通过SSH使用Python脚本在HCL搭建的模拟环境中测试交换机配置?

摘要:介绍了如何搭建基础的HCL实验环境,并通过Python脚本实现SSH连接设备,执行了交换机简单的测试指令,为后续的学习做好准备。
通过交换机的提示信息,结合相关文档,解决了过程中因公钥认证,交换机认证策略原因,导致的para
一、创建路由器,交换机设备 创建适量的设备,不实现特定功能配置,仅实现基础的设备互通即可。 如下图所示,我创建了4台路由器和4台交换机,通过配置,实现设备互联互通及与本地电脑互通,能实现SSH登录即可。 二、设备配置 2.1 设备IP地址分配如下: 路由器IP分配 Router-R1 Router-R2 Router-R3 Router-R4 LO-ip 10.3.3.3/32 10.4.4.5/32 10.4.4.6/32 10.4.4.7/32 Router-R1 Local 10.10.1.1/30 10.10.1.5/30 10.10.1.9/30 交换机IP分配 Switch-1 Switch-2 Switch-3 Switch-4 LO-ip 10.5.5.5/32 10.6.6.6/32 10.7.7.7/32 10.8.8.8/32 Switch-1 Local 10.10.1.13/30 10.10.1.17/30 10.10.1.21/30 除了完成【网络自动化学习笔记-H3C模拟器(HCL)基础环境配置】中的SSH相关配置外,还需完成相关的IP配置及路由配置,确保各设备及本地电脑之间互通。 主要配置内容为: 设备loopback IP配置 端口互联IP配置 OSPF路由配置 2.2 路由器Router-R1的配置过程 sys # interface LoopBack0 ip address 10.3.3.3 255.255.255.255 quit # interface GigabitEthernet0/1 ip address 10.10.1.5 255.255.255.252 quit # interface GigabitEthernet0/2 ip address 10.10.1.13 255.255.255.252 quit # interface GigabitEthernet5/0 quit # interface GigabitEthernet5/1 ip address 10.10.1.9 255.255.255.252 quit # interface GigabitEthernet6/1 ip address 10.10.1.1 255.255.255.252 quit # ospf router-id 10.3.3.3 ar 0 network 10.2.1.0 0.0.0.255 network 10.3.3.3 0.0.0.0 network 10.10.1.1 0.0.0.3 network 10.10.1.5 0.0.0.3 network 10.10.1.9 0.0.0.3 network 10.10.1.13 0.0.0.3 quit quit 2.3 交换机Switch-1配置过程 交换机Switch-1配置与路由器基本相同。交换机默认端口为二层,不能配置IP,需要在端口模式下,使用命令 port link-mode route,将其配置为三层接口,然后配置IP。 sys # interface LoopBack0 ip address 10.5.5.5 255.255.255.255 quit # interface GigabitEthernet1/0/1 port link-mode route ip address 10.10.1.17 255.255.255.252 quit # interface GigabitEthernet1/0/2 port link-mode route ip address 10.10.1.21 255.255.255.252 quit # interface GigabitEthernet1/0/3 port link-mode route ip address 10.10.1.25 255.255.255.252 quit # interface GigabitEthernet1/0/10 port link-mode route ip address 10.10.1.14 255.255.255.252 quit # # ospf 1 router-id 10.5.5.5 area 0.0.0.0 network 10.5.5.5 0.0.0.0 network 10.10.1.12 0.0.0.3 network 10.10.1.16 0.0.0.3 network 10.10.1.20 0.0.0.3 network 10.10.1.24 0.0.0.3 quit quit 其他设备配置相似,即配置IP,OSPF宣告接口/IP即可。 2.4 本地电脑配置静态路由 因为模拟设备的IP没有使用与虚拟网卡同段IP,所以需要添加本地电脑到模拟设备的静态路由。打开本地电脑cmd命令终端(管理员),添加静态永久路由route add -p 10.0.0.0 mask 255.240.0.0 10.2.1.1,即所有去往【10.0.0.0---10.15.255.255】的IP段数据均送至10.2.1.1。 当然,你也可以使用mask 255.0.0.0,代表所有目标为10.x.x.x的IP均送至10.2.1.1。相关计算机网络基础知识不在此赘述。 #添加临时静态路由,电脑重启后失效 route add 10.0.0.0 mask 255.240.0.0 10.2.1.1 #添加永久静态路由,电脑重启后依然生效。可手动删除。 route add -p 10.0.0.0 mask 255.240.0.0 10.2.1.1 三、配置验证 3.1 互通ping测验证 终端电脑ping测所有设备。 你也可以在设备上互ping其他设备,验证设备间通信,虽然似乎没有这个必要。 如下是对部分设备的ping测结果。 3.2 SSH登录验证 使用本地电脑的CMD命令终端或其他第三方工具,如SecureCRT,MobaXterm等,进行SSH登录测试。 如下图,使用MobaX进行登录测试。SSH可正常登录。 四、使用Python进行简单的连接测试 Python工具我安装使用了VS Code,相关安装使用方法可自行搜索,网上教程很多。 你也可以安装使用其他优秀的Python工具,如Pycharm等。 或者你也可以直接使用windows的CMD命令行终端。 4.1 创建一个py文件 创建一个py文件,并准备如下代码。目前,我们可以不必太关心代码的具体意义。 import paramiko import time hostname = "10.8.8.8" username = "hao" password = "admin12345" ssh_client = paramiko.SSHClient () ssh_client.set_missing_host_key_policy (paramiko.AutoAddPolicy ()) ssh_client.connect (hostname,username,password) print ("你已成功连接至", hostname) command = ssh_client.invoke_shell () time.sleep (1) command.send ("sys\n") command.send ("dis version\n") time.sleep (2) output = command.recv (65535) print (output.decode ("ascii")) ssh_client.close 4.2 运行Python脚本 运行刚刚创建的脚本文件 在VS Code下方的终端窗口,发现报错 PS F:\Learning\p-a-net> & "D:/Program Files/python/python.exe" f:/Learning/p-a-net/person/test-1.py Traceback (most recent call last): File "f:\Learning\p-a-net\person\test-1.py", line 10, in <module> ssh_client.connect (hostname=ip,username=username,password=password) ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Program Files\python\Lib\site-packages\paramiko\client.py", line 483, in connect self._auth( ~~~~~~~~~~^ username, ^^^^^^^^^ ...<9 lines>... passphrase, ^^^^^^^^^^^ ) 同时在交换机的CLI命令终端上也看到相关的错误提示。 五、SSH错误故障处理 5.1 错误故障分析 首先看一下设备上的错误提示 #无效的用户名hao Invalid user hao. #因为错误的公钥算法,用户hao未通过公钥认证 "SSH user hao (IP: 10.2.1.254) didn't pass public key authentication for wrong public key algorithm." #无效用户hao认证失败,因为无效的用户名或错误密码 Authentication failed for invalid user hao from 10.2.1.254 port 9779 because of invalid username or wrong password. #用户关闭了连接 Connection closed by 10.2.1.254. #用户断开了连接 SSH user hao (IP: 10.2.1.254) disconnected from the server. 根据设备的提示,似乎是因为我们没有hao这个用户,所以导致登录失败。但是通过dis local-user查看设备是有用户hao的,而且前面使用MobaX是可以通用户hao正常登录的。 同时也看到有使用公钥算法错误的提示。 查看H3C官方文档【SSH故障处理手册-新华三集团-H3C】。 查看 【故障原因:设备上SSH2协议使用的算法与客户端不匹配】 章节,有如下相关说明: 检查是否配置了SSH用户并指定正确的服务类型和认证方式。 SSH支持Stelnet、SFTP、NETCONF和SCP四种用户服务类型。 首先,根据服务器采用的认证类型,根据如下规则,查看设备上是否创建正确的SSH用户。 如果服务器采用了publickey认证,则必须在设备上创建相应的SSH用户,以及同名的本地用户(用于下发授权属性:工作目录、用户角色)。 如果服务器采用了password认证,则必须在设备上创建相应的本地用户(适用于本地认证),或在远程服务器(如RADIUS服务器,适用于远程认证)上创建相应的SSH用户。这种情况下,并不需要通过本配置创建相应的SSH用户,如果创建了SSH用户,则必须保证指定了正确的服务类型以及认证方式。 如果服务器采用了keyboard-interactive、password-publickey或any认证,则必须在设备上创建相应的SSH用户,以及在设备上创建同名的本地用户(适用于本地认证)或者在远程认证服务器上创建同名的SSH用户(如RADIUS服务器,适用于远程认证)。 可以看到,如果设备使用了公钥(publickey)认证,除了创建一个local-user,还需要创建一个ssh user,且必需与本地用户同名。但是设备配置的是的密码(password)认证,这点从MobaX能正常登录可以看出来。 这样看来,似乎是Python的paramiko默认使用了公钥(publickey)认证,但设备上并没有ssh user用户,也没有配置公钥,导致认证失败,设备拒绝了连接,且没有给其使用密码的机会。 所以要做的便是,使两端登录相关参数一致: 【选择1】修改交换机配置使其与paramiko适配。 添加ssh user。 制作密钥对文件并保存。 使用FTP将公钥文件上传到交换机,指定ssh user使用publickey认证,并指定【公钥文件】。 在脚本中指定paramiko使用的【私钥文件】。 【选择2】修改paramiko参数,使其与交换机适配,能够像MobaXterm一样正常连接。 指定paramiko不优先使用publickey方式发起ssh连接 5.2 方法1:在设备添加ssh user 因为在交换机上Invalid user(无效用户)的错误提示,paramiko似乎不能使用在交换机上配置的local-user。 根据H3C官方文档说明,在使用公钥(publickey)认证时,需要同时配置local-user和ssh user。似乎paramiko默认使用公钥(publickey)认证方式登录且不会在失败时尝试密码(password)登录,导致找不到ssh user而登录失败。 尝试在交换机设备上添加ssh user。 在设备上输入命令ssh user hao service-type stelnet authentication-type password,即创建ssh用户hao(和local-user同名),允许服务为ssh,认证方式为密码。 [Switch-4]ssh user hao service-type stelnet authentication-type password [Switch-4]dis ssh user Total ssh users:1 Username Authentication-type User-public-key-name Service-type hao password Stelnet [Switch-4]dis local-user Total 1 local users matched. Device management user hao: State: Active Service type: SSH User group: system Bind attributes: Authorization attributes: Work directory: flash: User role list: network-admin, network-operator Password control configurations: Password complexity: username checking [Switch-4] 可以看到现在设备上同时存在了用户名为hao的Local-user和ssh user。 成功运行Python脚本,如下图所示。 至此,该故障我们通过修改交换机配置,增加和local-user同名的ssh user得以解决。 同时交换机的提示信息显示如下 依旧看到了之前的公钥认证失败提示 SSH user hao (IP: 10.2.1.254) didn't pass public key authentication for wrong public key algorithm.。 随后又提示密码认证成功。SSH user hao from 10.2.1.254 port 11971 passed password authentication. 由此可以推测出paramiko和交换机的交互行为: paramiko发起ssh连接,默认使用公钥认证。 没有配置ssh user时,用户名验证失败,交换机直接拒绝连接,导致paramiko没有机会使用密码认证的机会。 已经配置ssh user时,用户名验证成功,交换机没有拒绝连接,交换机发现自己没有公钥配置,使用local user密码验证方式成功登录设备。 5.3方法2:修改Python脚本中paramiko的SSH连接参数 先删除上一节中配置的ssh user用户,确保环境与先前一致,即Python脚本不能登录设备,而MobaXterm可以。 对脚本ssh_client.connect部分修改,指定ssh连接的相关配置,包括禁用ssh agent,禁用查找本地密钥文件。 ssh_client = paramiko.SSHClient () ssh_client.set_missing_host_key_policy (paramiko.AutoAddPolicy ()) ssh_client.connect ( hostname=ip,username=username,password=password, look_for_keys=False, # 禁用查找本地密钥文件 allow_agent=False # 禁用SSH agent ) print ("你已成功连接至", ip) 成功运行Python脚本,如下图所示。 在交换机的提示中,第一条就是用户hao通过了密码认证。SSH user hao from 10.2.1.254 port 1672 passed password authentication.可以确认paramiko没有使用公钥认证方式发起ssh连接,没有触发公钥认证失败。 参考文档 Client — Paramiko documentation SSH典型配置举例-新华三集团-H3C SSH故障处理手册-新华三集团-H3C