paramiko实现相同配置集

1.实验拓扑

20200514194836

2.paramiko介绍

  paramiko是SSHv2协议的python实现,简化了主机和远程设备之间的SSHv2交互。有了paramiko,我们可以在python代码中直接使用SSHv2协议对远程服务器或网络设备进行操作。paramiko是高级自动化框架ansible背后低级SSH客户端。paramiko包含了三个核心组件包括SSHclient、SSHserver、SFTPclient

  仍然是上个实验的拓扑,在此基础上使用了更加安全的SSH。在python中,支持SSH远程登录的模块也有很多,常见的比如paramiko和netmiko,这里使用的是paramiko。

  paramiko在执行完命令集后,不会自动保存或者返回这些命令集所能显示的内容,需要我们手动去让它返回必要的回显信息。同时,如果不对python进行必要的短暂控制,那么python会在很短的时间内一次性将命令集中所有的命令全部输入,这会导致SSH终端跟不上速度,导致某些命令缺失没有输入完整。同时我们也需要间隔时间让回显内容显示的更加完整,所以我们需要用time模块下的sleep方法来设置间隔时间。

3.基于paramiko的配置脚本

  paramiko是第三方模块,所以需要使用pip进行安装,安装命令如下

pip3 install paramiko
#coding=utf-8
#本代码属于单线程同步,本代码未增加单线程异步/多线程、差异化配置
import paramiko
from getpass import getpass
import time
import sys
import socket

ipfile = sys.argv[1]
cmdfile = sys.argv[2]

"""
因为可能会出现两种问题:用户名密码认证错误、网络设备不可达
所以创建两个列表,用于记录出这两种问题的网络设备的IP地址
"""
authentication_issue = []
unreachable_issue = []

username = input("请输入用户名:")
passwd = getpass("请输入密码:")

#paramiko远程登录
with open(ipfile,'r') as ipobj:
    for allip in ipobj.readlines():
        try:
            ip = allip.strip()
            """
            如果每台网络设备的用户名和密码不同,则设置在此处
            username = input("请输入用户名:")
            passwd = getpass("请输入密码:")
            """
            client = paramiko.SSHClient() #创建SSH对象
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())#允许连接不在know_hosts文件中的主机
            client.connect(hostname=ip,username=username,password=passwd) #连接网络设备
            print('成功登录',ip)
            time.sleep(2) #每条命令间隔时间

            cmd = client.invoke_shell() #获取网络设备shell
            print("正在自动配置命令.....")
            with open(cmdfile,'r') as fileobj:
                fileobj.seek(0)#指针归位
                for allcmd in fileobj.readlines():
                    cmd.send(allcmd)
                    time.sleep(1)
                    output = cmd.recv(65535) #设置缓冲区65535
                    print(output) #输出回显内容,如果输出不好看,则加上output.decode('ascii')
            client.close() #关闭SSH
        except paramiko.ssh_exception.AuthenticationException:
            print(f"网络设备{ip}用户名密码认证失败!")
            authentication_issue.append(ip)
        except socket.error:
            print(f"网络设备{ip}不可达")
            unreachable_issue.append(ip)
print("\n 用户名密码认证失败的网络设备:")
for sw_ai in authentication_issue:
    print(sw_ai)
print("\n 不可达网络设备:")
for sw_ui in unreachable_issue:
    print(sw_ui)

解释下部分重要代码:

from getpass import getpass :导入getpass方法,该方法接收用户输入的SSH用户名和密码,且不显示

import sys :导入sys模块,sys是内建模块,接收输入的脚本名,这里指的是命令集,一般是将python脚本和命令集放在同一个目录下。所以后面接收了两个命令集ipfile和cmdfile。

with open(ipfile,'r') as ipobj:打开文件路径为ipfile,只读模式,赋值给文件对象ipobj。也就是打开ipfile这个存放网络设备ip地址的文件

client.set_missing_host_key_policy(paramiko.AutoAddPolicy()):其中改方法autoaddpolicy策略是自动添加主机名和主机密钥到本地hostkeys对象,即建立新的SSH连接时不需要再输入yes或no进行确认

output值得注意,因为如果不加output.decode(),那么返回的回显结果就是字节流,不容易查看,所以建议加上decode

4.ipfile和cmdfile

脚本中提到的ipfile和cmdfile内容很简单。ipfile用于存放网络设备的IP地址,cmdfile用于存放配置网络设备的命令集

192.168.154.131
192.168.154.132
192.168.154.133
conf t 
banner motd #
python test
#
end
wr

20200615120211

有关paramiko的更多描述,请自行googlebing学习

5.总结

  我们使用paramiko结合python文件操作、异常处理等等来实现对网络设备无差异配置,所谓的无差异是配置网络设备命令都一样。同时这是一个单线程同步的脚本,执行时间上较长,后面会介绍到单线程异步和差异化配置。


保持一个积极向上的良好心态,分享网络技术!