一、实验环境

1.实验拓扑

20200514194836

讲解下细节部分:

  • net连接的是EVE-NG的第二个网卡,网卡模式为桥接
  • gateway的E0/1为DHCP自动获取,E0/0为192.168.154.130作为内网三台路由器的网关,三台内网路由器手动配置IP地址且都有一个静态默认路由指向getaway,即ip route 0.0.0.0 0.0.0.0 192.168.154.130
  • 内网地址段:192.168.154.0/24
  • 运行python的主机地址(即我的物理机地址):192.168.0.100

tips:需要注意的一点就是运行python的主机也就是我的windows,需要设置静态路由,否则无法访问R1-R3,配置就是route add 192.168.154.0 mask 255.255.255.0 192.168.0.121 metric 1,其中192.168.0.121是gateway的E0/1地址

2.实验设备

R1-R3三台内网路由器和gateway路由器使用的是IOL镜像

3.实验目的

  • 目的1:通过telnetlib、netmiko、paramiko模块,分别登录路由器R1、R2、R3
  • 目的2:给R1、R2、R3配置时区主机名

4.所需模块介绍

在Python中,支持Telnet/SSH远程登录访问网络设备的模块很多,常见的有Telnetlib,Paramiko,Netmiko,其中Telnetlib对应Telnet协议,后面两个对应SSH协议。本实验以telnetlib为例介绍该模块的使用。

二、实验运行

1.实验运行前准备

我们在实现我们的目的前,需要先让设备能够telnet访问。参考配置如下:

username epiol privilege 15 secret epiol
line vty 0 4
password epiol
login local
transport input telnet
exec-timeout 0 0

2.实验代码

以下是登录单个设备的python代码,参考配置:

#coding=utf-8
import telnetlib #导入telentlib模块
from getpass import getpass #导入getpass模块以便输入密码

#定义主机IP、用户名、密码
host = '192.168.154.131' 
user = input('请输入用户名:')
password = getpass('请输入密码:')

#调用telnetlib.Telnet函数,赋值给tn,尝试登录192.168.154.131
tn = telnetlib.Telnet(host)
#读取内容如果是Username:则输入用户名+回车
tn.read_until(b"Username: ") 
tn.write(user.encode('ascii') + b'\n')
#读取内容如果是Password:则输入密码+回车
tn.read_until(b'Password:')
tn.write(password.encode('ascii') + b'\n')
#成功登录后,开始输入正常的IOS命令,配置时区和主机名
tn.write(b'conf t\n')
tn.write(b'clock timezone GMT +8\n')
tn.write(b'hostname R1\n')
tn.write(b'end\n')
tn.write(b'wr\n')
#必须使用exit退出telnet,否则下面tn.read_all无法使用
tn.write(b'exit\n')
#将登录设备后执行的命令所有过程都记录下来,然后通过read_all打印出来
print(tn.read_all().decode('ascii'))

其中需要注意的是:

  • 部分代码之间增加空行的目的是增加代码可读性
  • 在网络编程中,服务器和浏览器只认bytes类型数据,所以需要对我们发送的str(即字符串)编码成bytes(即二进制数据),使用encode方法。当从服务器读取数据时需要用decode将bytes解码成为str,便于读取,如果不解码就是bytes类型不好读取。B表示后面的str是bytes类型
  • b'conf t\n'中的b表示bytes类型
  • \n表示回车换行的意思
  • 如果你的最后不加decode,会导致回显的内容不方便阅读,所以最后将从设备返回的bytes数据解码成为str
  • 最后一定需要执行exit,否则tn.read_all()无法执行

以下是代码运行回显图:
远程代码执行

如果需要循环登录三台连续IP地址的设备呢?使用for就行了,参考代码:

import telnetlib 
from getpass import getpass 

for router in range(131,134):
    host = '192.168.154.' + str(router)
    user = input('请输入用户名:')
    password = getpass('请输入密码:')
    tn = telnetlib.Telnet(host)
    tn.read_until(b"Username: ") 
    tn.write(user.encode('ascii') + b'\n')
    tn.read_until(b'Password:')
    tn.write(password.encode('ascii') + b'\n')
    print('successfully connect to',host)

    tn.write(b'conf t\n')
    tn.write(b'clock timezone GMT +8\n')
    tn.write(b'hostname R1\n')
    tn.write(b'end\n')
    tn.write(b'wr\n')
    tn.write(b'exit\n')

print(tn.read_all().decode('ascii'))

以上代码简单实现了我们的需求,可能有的人问了,你这点配置我十分钟搞定,还得花20分钟写代码?但是如果是1000台交换机或者路由器让你这么配置呢?你怎么办?同时如果是有关DMVPN和其他涉及BGP配置就会让你很崩溃。所以python实现网络自动化势在必行,我也是朝着devnet而前行,所以python学会使用,会让你的工作更加的方便,更加节省时间。那么又有人问了,如果是不连续IP地址呢?或者我从来不用telnet,我只用ssh,又该如何实现?代码中如果出现错误,又该如何处理?如何使用python快速匹配需要的信息?别急,该来的都会来。

tips:代码中如果出现问题或者疑问,请评论指出,谢谢!


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