Python网络运维实验(网络模拟器)

目录

前言

1.环境要求

2.拓扑图

3.实验目的

4.实验过程

4.1 Python中的Telnet和SSH模块

4.1.1  Telnetlib

4.1.2 Netmiko

4.1.3 Paramiko实验举例

4.2 input()函数和getpass模块

4.2.1 实验目的

4.3.2 实验准备

4.3.3 验证


前言

python作为网工进阶必学的技能,利用各种网络自动化库自动完成各种网络配置任务,不仅可以在配置的时候节约大量时间,还可以直观的了解到Python是如何把繁杂、单调、耗时的传统网络运维实现自动化(所有实验均基于华为的ENSP)

本章主要讲解

  • 如何使用Python里的telnetlib模块连接到网络设备
  • 初识Paramiko和Netmiko模块
  • 通过Paramiko和Netmiko连接到网络设备
  • 使用input()函数和getpass模块

1.环境要求

检查一下是否正确安装了下列工具并且保证版本能够正常使用

  • python 3.10.x(笔者这里的python是3.10.6)
  • Pycharm社区版或者专业版(社区版足矣)
  • 华为的ENSP模拟三层交换设备
  • 操作系统Windows 10

2.拓扑图

保证交换机可以和宿主机互通

然后配置aaa登录以及和外界互通的IP地址


stelnet server enable
ssh user python
ssh user python authentication-type password
ssh user python service-type all
ssh client first-time enable
#

aaa
local-user python password cipher python
local-user python privilege level 15
local-user python service-type telnet ssh
#
interface Vlanif1
ip address 192.168.56.2 255.255.255.0
#
user-interface vty 0 4
authentication-mode aaa
protocol inbound all

3.实验目的

通过Telnetlib,Netmiko,Paramiko模块登录交换机SW1,SW2,SW3,SW4,然后给每台交换机的环回口配地址

4.实验过程

4.1 Python中的Telnet和SSH模块

4.1.1  Telnetlib

telnet作为一种不安全的登录方法,在python中,我们不经常用它远程登陆网络设备,Telnetlib作为python的内置模块,不需要pip下载就能直接使用,鉴于Telnet的不安全性,通常不用在生产网络当中,本小节只举一例来讲解Telnetlib模块的使用方法

import telnetlib
import time

host = "192.168.56.2" //管理地址的IP地址
user = "python" //创建的AAA用户的用户名
password = "python" //创建AAA用户的登录密码

telnet = telnetlib.Telnet(host)
telnet.read_until(b"Username: ")
telnet.write(user.encode('ascii') + b"\n")
telnet.write(user + '\n')
telnet.read_until(b"Password: ")
telnet.write(user.encode('ascii') + b"\n") 
telnet.write(password + "\n")
telnet.write(b"sys\n")
telnet.write(b"int loo0\n")
telnet.write(b"ip add 2.2.2.2 255.255.255.255\n")
time.sleep(0.5)
telnet.write(b"quit\n")
print(telnet.read_very_earger().decode('ascii'))
telnet.close()

在python3中,telnetlib模块下所有函数的返回值都变成了字节型字符串(Byte strings),因此,在python3中使用telnetlib需要注意以下几点

  • 在字符串面前需要加一个b
  • 在变量和telnetlib函数后面需要加上.encode('ascii')函数
  • 在read_all()函数后面需要加上decode('ascii')函数

注意:1.encode是解码的意思,将用户输入用ascii解码

           2.b表示将用户的输入解码成字符串

           3.telnet.read_very_earger方法表示打印,这样就可以在运行结果中清楚的看到我们对设备做了什么配置,并且这这个方法只有在退出telnet才会生效,因此我们必须在之前通过telnet.write(b"quit\n")退出telnet

代码分段讲解如下:

首先通过import语句导入telnetlib模块


import telnetlib
import time

然后创建三个变量,分别是host,user,password,分别对应交换设备的管理地址,Telnte用户名和密码,且三个变量的类型是字符串类型


host = "192.168.56.2"
user = "python"
password = "123"

调用telnetlib模块里面的Telnet()函数,将它赋值给变量telnet,然后以Telnet方式登录

192.168.56.2


telnet = telnetlib.Telnet(host)

通过Telnet登录交换机的时候,终端输出最下面的提示信息为“Username:”,我们通过telnet.read_until("Username: ")和telnet.read_until("Password: ")告诉Python,如果在终端信息里读到“Username:”和“Password:”字样,就使用telnet.write()函数来输入用户名和密码,记得加换行符'\n',这里我们用CRT模拟一下Telnet连接


telnet.read_until(b"Username: ")
telnet.write(user.encode('ascii') + b"\n")
telnet.write(user + '\n')
telnet.read_until(b"Password: ")

至此,已经成功通过Telnet登录到SW1上了,接下来就用Telnetlib的write()函数在交换机上输入各种配置命令,给环回口配置IP地址,划分VLAN等操作


telnet.write(b"sys\n")
telnet.write(b"int loo0\n")
telnet.write(b"ip add 2.2.2.2 255.255.255.255\n")
time.sleep(0.5)
telnet.write(b"quit\n")
print(telnet.read_very_earger().decode('ascii'))
telnet.close()

最后结果就和我们正常配置一样,但是笔者这里的python版本过高,导致telnetlib已经在这个版本被移除了,这里就不过多演示了,有兴趣的可以试试,代码如果写对了就会只出现这一个报错,如果有其他地方报错,比如和宿主机不能连通,会继续出现报错,显示连接失败,如下图,

4.1.2 Netmiko

Python中支持SSH协议实现远程连接设备的模块主要有Paramiko和Netmiko两种,Paramiko是Python中一个非常著名的开源SSHv2项目,基于Python 2.7和Python3.4+开发

Netmiko是Python的第三方模块,需要通过pip安装,但是笔者在这里不推荐用pip安装,笔者通过这种方法安装之后在Python里检测不到这个模块,这里推荐用PyCharm安装,如下图

点击“+”

然后搜索模块

笔者这里已经安装过了,同时paramiko模块也装好了,这里就不演示,直接点击Install Package安装就行了

然后开始做实验,与上面的Telnet实验一样,首先我们要登录SW1,然后查看一下环回口有没有地址,防止我们在试验中混淆,接下来创建一个名为ssh_netmiko.py的脚本

代码如下

from netmiko import ConnectHandler

SW1 = {
    'device_type': 'huawei',
    'ip': '192.168.56.2',
    'username': 'python',
    'password': 'python'
}

connect = ConnectHandler(**SW1)
print("成功登录到" + SW1['ip'])
config_command = ['int loo 1 ','ip add 1.1.1.1 32']
output = connect.send_config_set(config_command)
print(output)
result = connect.send_command('disp cur int loo 1')
print(result)

代码分段讲解如下

 首先通过import语句从Netmiko模块导入他的链接库函数ConnectHandler()。该函数用来实现SSH登录网络设备,是Netmiko最重要的函数


from netmiko import ConnectHandler

然后创建一个名为SW1的字典,字典包含 device_type、 ip 、 username、password必选的键,device_type键表示支持的厂家的设备,Netmiko支持多数厂家设备,比如Cisco,huawei,Arista,HP等主流厂商设备,由于不通厂商设备登录SSH后命令行界面和特性各不相同,因此我们必须通过device_type来指定需要登陆设备的类型,如果要是Cisco,device_type的键值为csico_ios,后面三个就很好理解了,笔者在这里就不一一赘述了


SW1 = {
    'device_type': 'huawei',
    'ip': '192.168.56.2',
    'username': 'python',
    'password': 'python'
}

 然后调用ConnectHandler()函数,用已经创建的字典SW1进行SSH连接,将它赋值给connect变量,注意SW1前面的**为关键字参数kwargs,在函数里,关键字参数表示传入函数的参数为字典格式


connect = ConnectHandler(**SW1)

 创建一个登陆提示,如果登录成功就告诉我们


print("成功登录到" + SW1['ip'])

 然后创建一个config_commands的列表,其元素为需要在交换机依次执行的命令


config_command = ['int loo 1 ','ip add 1.1.1.1 32']

 调用ConnectHandler()的send_config_set()函数来使用上述命令对SW1做配置,参数就是我们上面创建出来的列表,并把配置过程打印出来


output = connect.send_config_set(config_command)
print(output)
result = connect.send_command('disp cur int loo 1')
print(result)

最后调用ConnectHandler()的Send_command函数,对交换机输入命令show run int loo 1,并将回显内容打印出来,需要注意的是connect.send_command一次只能向设备输入一条命令,connect.send_config_set则可以向设备一次输入多个命令

运行代码,结果如图所示

4.1.3 Paramiko实验举例

Paramiko和Netmiko不同,Netmiko是基于Paramiko开发的,自然比Paramiko要更好用,比如,Paramiko不会在做配置的时候给我们做配置的时候自动加上system-view,return等命令,相信大家在上面已经看出来了,Telnetlib实验需要我们敲sys进入全局下进行配置,配置完需要敲quit退出,Netmiko就完全不需要,大家可以仔细看Netmiko运行结果,如下图

是不是自动给我们加上了system-view和return命令,Python是一次性执行脚本里所有的命令的,中间没有间隔时间,当我们一次性执行过多的命令,通常出现SSH终端跟不上速度,导致某些命令缺失没有被输入的问题,同样,在用print函数显示回显内容或者open.write()将回显写入文档进行保存,也会因为缺失时间间隔导致命令不完整,Netmiko自动帮我们解决了这个难题,这也是Netmiko比Paramiko的好用的原因之一,而且在Paramiko这个模块中,我们必须导入time模块,然后使用time模块下的sleep()方法来解决这个问题,关于time模块我们会在下面的实验中讲解,这里安装Paramiko就不再赘述,和Netmiko安装方法一样

首先创建一个名为ssh_paramiko.py的脚本,内容如下

import paramiko
import time

ip = '192.168.56.2'
username = 'python'
password = 'python'

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=ip, username=username, password=password)
print("成功登录到{}".format(ip))
command = client.invoke_shell()
command.send('sys\n')
command.send('int loo 2\n')
command.send('ip add 2.2.2.2 32\n')
command.send('return\n')
command.send('save\n')
command.send('Y\n')
time.sleep(2)
output = command.recv(65535)
print(output.decode("ascii"))
client.close()

 代码分段讲解如下

通过import语句导入paramiko和time两个模块


import paramiko
import time

 然后创建三个变量:ip,username,password,分别对应我们要登陆的交换机SW1的管理地址,SSH用户名和密码


ip = '192.168.56.2'
username = 'python'
password = 'python’

默认情况下,Paramiko会拒绝任何位置SSH公钥,这我们需要用client.set_missing_host_key_policy(paramiko.AutoAddPolicy())来让Paramiko来接受SSH的服务端,这是在任何时候使用Paramiko连接SSH的标准配置


client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

 然后调用paramiko.SSHClient()和client.connect()进行SSH登录,里面包含的三个变量就是我们创建的ip,username,password,如果登陆成功,就提示用户登录成功的交换机的管理IP


client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=ip, username=username, password=password)
print("成功登录到{}".format(ip))

SSH连接成功过后,需要调用command = client.invoke_shell()来唤醒Shell来向SW1输入你想要的配置,注意这里需要输入system-view,不然进不了全局配置模式下,就会导致配失败


command = client.invoke_shell()
command.send('sys\n')
command.send('int loo 2\n')
command.send('ip add 2.2.2.2 32\n')
command.send('return\n')
command.send('save\n')
command.send('Y\n')

 最后,就是我们的前面所说的,因为python是一次性执行所有脚本的命令的,中间没有间隔时间,这样会导致命令遗漏和回显内容不完整的问题,在Paramiko的recv()将回显结果保存之前,我们需要调用time模块下的time方法让python休眠2s,这样回显才能被完整保存下来,这里的command.recv(65535)中的65535代表截取65535的字符的回显内容,这也是Paramiko一次能截取的最大回显内容数,另外,与Telnetlib类似,在Python3中,Paramiko街区的弧线内容格式为字节型字符串,需要用decode("ascii")将其解析为ASCII编码,否则打印出来的output的内容格式会很难看,有兴趣的同学可以试试不用decode解析,这里笔者就不做演示了


time.sleep(2)
output = command.recv(65535)
print(output.decode("ascii"))

配置完毕之后,使用close方法退出SSH

配置完毕之后,使用close方法退出SSH


client.close()

运行代码后看结果,验证,如下图所示

4.2 input()函数和getpass模块

在针对Telnetlib、Netmiko和Paramiko模块的基础知识讲解中,我们都将SSH登录的用户名和密码明文写在了脚本中,这种做法一般用在实验里,但是在生产环境中是不够安全的,在生产环境中,正确的做法是使用input()函数和getpass模块来分别提示用户手动输入SSH用户名和密码,这也是本实验重点讲解的部分

4.2.1 实验目的
  • 使用input()函数和getpass模块实现交互式的SSH用户名和密码输入
  • 通过for循环同时为三台交换机配置VLAN10-VLAN20
4.3.2 实验准备

在运行代码之前,首先检查交换机配置,看看VLAN是否存在

然后创建Python脚本文件

代码如下

import paramiko
import time
import getpass

username = input('Username: ')
password = getpass.getpass('Password: ')

for i in range(2,5):
    ip  = "192.168.56." + str(i)
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(hostname=ip, username=username, password=password,look_for_keys=False)
    print("成功登录到{}".format(ip))
    command = client.invoke_shell()
    command.send('screen-length 0 temporary\n')
    command.send('sys\n')
    for n in range(10,21):
        command.send('vlan ' + str(n) + '\n')
        command.send('description python_vlan' + str(n) + '\n')
        time.sleep(1)
    command.send('return\n')
    command.send('save\n')
    command.send('Y\n')
    time.sleep(2)
    output = command.recv(65535)
    print(output.decode("ascii"))
client.close()

 代码分段讲解如下

首先导入paramiko、time和getpass3种模块


import paramiko
import time
import getpass

username = input('Username: ')
password = getpass.getpass('Password: ')

因为三台交换机的IP地址是连续的,都是192.168.65.X,我们直接做一个简单的for循环来遍历三台交换机,然后配合下一行代码ip = "192.168.56." + str(i)来实现循环批量登录交换机,注意这里的i是整数,我们输入的属于字符,所以要用str(i)来转化成字符串


for i in range(2,5):
    ip  = "192.168.56." + str(i)
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(hostname=ip, username=username, password=password,look_for_keys=False)
    print("成功登录到{}".format(ip))
    command = client.invoke_shell()
    command.send('screen-length 0 temporary\n')
    command.send('sys\n')

同样的道理,我们要创建VLAN10-VLAN20,这些VLANID都是连续的,所以又可以配合一个简单的for循环来达到循环配置VLAN10-VLAN20的目的,这里使用的是嵌套for循环,需要注意缩进,这里创建VLAN的时候可以创建一个打印内容来提醒我们正在创建那个VLAN,每创建一个VLAN都需要1s的间隔


for n in range(10,21):
    command.send('vlan ' + str(n) + '\n')
    command.send('description python_vlan' + str(n) + '\n')
    time.sleep(1)

 最后保存配置


command.send('return\n')
command.send('save\n')
command.send('Y\n')
time.sleep(2)
output = command.recv(65535)
print(output.decode("ascii"))
4.3.3 验证

注意:这里用的是IDLE shell验证的,用pycharm会卡在输入密码那里,具体原因不知道为啥

 

检查交换机配置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值