网络自动化实验(SSH,SFTP,NETCONF)
- 拓扑
- 要求,通过python编程 实现自动SSH 登陆,并获取配置。
- 配置步骤:
- 与CE设备互通
配置G1/0/0口
interface GE1/0/0
undo portswitch
undo shutdown
ip address 192.168.1.1 255.255.255.0
-
- 配置CE ssh service
aaa
local-user devuser password irreversible-cipher Huawei@123 (用户名devuser,密码Huawei@123)
local-user devuser service-type ssh
local-user devuser level 3
stelnet server enable
ssh user devuser
ssh user devuser authentication-type password
ssh user devuser service-type stelnet
ssh authorization-type default aaa
user-interface vty 0 4
authentication-mode aaa
protocol inbound ssh
验证能否ssh登陆
-
- 配置代码
- 代码详细配置:
1.安装paramiko
如果是上面的问题,需要升级python。(不要用anaconda安装python。版本太低!可以用paramiko建环境或单独下载python安装包。)
把python 升级到3.x版本。
然后回提示升级PIP,按提示输入:python.exe -m pip install --upgrade pip
在CMD里测试一下能否引入 paramiko
没报错。表示可以引用
2.引入time,测试没问题
3.Jupyter 里 写代码
import paramiko #使用Paramiko 模块可以登陆SSH
import time #使用Time 进行延时等待,否则不能瞬间接收返回值。
ssh_proc = paramiko.SSHClient()
ssh_proc.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_proc.connect(hostname="192.168.1.1",
port="22",
username="devuser",
password="Huawei@123",)
shell = ssh_proc.invoke_shell()
time.sleep(0.5)
使用AAA本地用户登录设备时,如果密码设置不符合系统的复杂度要求,会有如下的显示:
Warning: The initial password poses security risks.
The password needs to be changed. Change now? [Y/N]:
可以输入Undo password alert original关闭。
或通过Paramiko直接修改密码:
shell.send("Y\n")
time.sleep(0.5)
shell.send("Huawei@123" + "\n")
time.sleep(0.5)
shell.send("Admin@123" + "\n")
time.sleep(0.5)
shell.send("Admin@123" + "\n")
time.sleep(0.5)
这些代码只能使用一次。因为下次密码不对导致登陆失败。
shell.send("screen-length 0 " + "\n") #使配置一次性全部输出。
time.sleep(0.5)
shell.send("display cu\n") #发送查看所有配置命令
time.sleep(0.5)
resp = shell.recv(99999).decode() #接收所有字符
现在resp已经可以获得配置。
现在收到了配置信息,进行写入文档:
在python文件同目录新建一个config文件夹。用于存储配置文件。
with open("./config/ce12800_conf.txt","a") as file:
file.write(resp)
运行后检查文件正常。
现在的问题是收到一些无用信息,需要去除,[HUAWEI]display cu\r\n 和前面的信息都无用。[HUAWEI]在最后也无用。
使用split分割取值。
#括号内以”[HUAWEI]display cu\r\n“进行分割。
分割后是列表的形式。0是代表第1个值。[1]是取分割后的第2个值,这里我们需要取第2个值。后面用[HUAWEI]进行分割取第1个值,为[0]。
config = resp.split("[HUAWEI]display cu\r\n")[1].split("[HUAWEI]")[0]
检查结果:
结果正常。
把写入配置文件从resp改成优化后的config
with open("./config/ce12800_conf.txt","a") as file:
file.write(config)
检查TXT文件:
信息正确。
现在需要定义IPlist 和Device List,自动读取IP列表和用户名密码列表。并自动登陆自动配置读取和存储配置。
下面是完整代码:
import paramiko
import time
# 设置参数
DEVICEs = {"192.168.1.1": ("devuser", "Admin@123")}
IPs = list(DEVICEs.keys())
USERNAMEs = [one[0] for one in DEVICEs.values()]
PASSWORDs = [one[1] for one in DEVICEs.values()]
# 配置保存功能
def save_config(ip, config):
with open("./config/ce12800_conf.txt", "a") as file:
file.write(config)
# 单独设备备份配置功能
def run_backup(ip, username, password):
ssh_proc = paramiko.SSHClient()
ssh_proc.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_proc.connect(hostname=ip, port=22, username=username, password=password)
shell = ssh_proc.invoke_shell()
time.sleep(1)
shell.send("sys im\n")
time.sleep(0.5)
shell.send("screen-length 0\n")
time.sleep(0.5)
shell.send("display cu\n")
time.sleep(0.5)
# 接收数据
resp = ""
while True:
part = shell.recv(9999).decode()
resp += part
if not part or '[HUAWEI]' in part:
break
config = resp.split("display cu\r\n")[1].split("[HUAWEI]")[0]
save_config(ip, config)
print("正在备份 {} 的配置".format(ip))
ssh_proc.close()
# 主进程
if __name__ == "__main__":
for index in range(len(IPs)):
ip = IPs[index]
username = USERNAMEs[index]
password = PASSWORDs[index]
run_backup(ip, username, password)
备份成功。
如果有不知道如何处理的问题,用chatgpt检查 优化一下:
SFTP实验
基于python可以SSH连接设备的情况下。
CE12800开启SFTP
[HUAWEI]ssh user devuser service-type sftp
[HUAWEI]ssh user devuser sftp-directory cfcard:
[HUAWEI]sftp server enable
Info: Succeeded in starting the SFTP server.
配置代码:
#查看paramiko transport 功能,help(paramiko.Transport)
如果transport 函数没有放参数,会提示丢失sock参数。
写sock参数,元组的方式
sock 中有两个元素,IP,port
ip = "1.1.1.1"
port = 22
sock = (ip,port)
sftp_proc = paramiko.Transport(sock)
#创建文件名+时间#
def creat_filename(time_struct):
str_year = str(time_struct.tm_year) + "_"
str_mon = str(time_struct.tm_mon) + "_"
str_mday = str(time_struct.tm_mday) + "_"
str_hour = str(time_struct.tm_hour) + "_"
str_min = str(time_struct.tm_min) + "_"
str_sec = str(time_struct.tm_sec) + ".cfg"
filname = str_year + str_mon + str_mday + str_hour + str_min + str_sec
return filname
试运行,查看名称
下面是完整代码:
##这是一个PYTHON实现 SFTP客户端功能,拷贝配置文件到本地的脚本#
#首先CE12800设备开启sftp功能,具体方法略 #
###引入sftp连接模块##
###查看paramiko transport 功能,可以使用:“help(paramiko.Transport”##
import paramiko
#引入时间模块,获取时间#
import time
#新建文件夹模块#
import os
#如果不存在某个IP的文件夹,则新建IP地址的文件夹#
def check_folder(ip,path):
path += ip
if not os.path.isdir(path):
os.mkdir(path)
print("{}目录已建立".format(path))
return path
#以时间的方式创建文件名#
def creat_filename(time_struct):
str_year = str(time_struct.tm_year) + "_"
str_mon = str(time_struct.tm_mon) + "_"
str_mday = str(time_struct.tm_mday) + "_"
str_hour = str(time_struct.tm_hour) + "_"
str_min = str(time_struct.tm_min) + "_"
str_sec = str(time_struct.tm_sec) + ".cfg"
filname = str_year + str_mon + str_mday + str_hour + str_min + str_sec
return filname
#返回文件名#
#参数区域#
ip = "1.1.1.1"
port = 22
backup_path = "./config/"
#执行检查文件夹函数#
folder = check_folder(ip,backup_path)
#获取一个以时间命名的文件名称#
file_name = creat_filename(time.localtime())
#获取SFTP参数local_file,remote_file#
local_file = folder + "/" + file_name
device_file = "/vrpcfg.cfg"
#配置sock参数#
sock = (ip,port)
#将sock传给paramiko transport#
sftp_proc = paramiko.Transport(sock)
#建立SFTP连接#
sftp_proc.connect(username="devuser",password="Admin@123")
#建立一个SFTP实例#
sftp_con = paramiko.SFTPClient.from_transport(sftp_proc)
#获取sftp远端文件#
sftp_con.get(remotepath=device_file,localpath=local_file)
#传送sftp文件到远端#
sftp_con.put(localpath="./config/1.1.1.1/2024_7_17_9_20_30.cfg",remotepath="test.cfg")
sftp_proc.close()
查看创建的文件夹和获取的文件。正常。
查看设备收到了文件。
基于NETCONF的网络自动化实验
通过 NetConf 协议对设备下发配置是南向设备管理的标准解决方案
实验目标
掌握 ncclient 基本用法
能够编写代码通过 NetConf 完成设备运维
配置设备开启NETCONF服务,端口830,SSH用户名devuser,密码Admin@123,netconf用户名netconf,密码Huawe@123,接口地址1.1.1.1,
aaa
local-user devuser password irreversible-cipher Admin@123
local-user devuser service-type ssh
local-user devuser level 3
local-user netconf password irreversible-cipher Huawei@123
local-user netconf service-type ssh
local-user netconf level 3
#
interface GE1/0/0
undo portswitch
undo shutdown
ip address 1.1.1.1 255.255.255.0
#
开启三个服务。
stelnet server enable
sftp server enable
snetconf server enable
#
ssh user devuser
ssh user devuser authentication-type password
ssh user devuser service-type snetconf
ssh user devuser sftp-directory cfcard:
ssh user netconf
ssh user netconf authentication-type password
ssh user netconf service-type snetconf
ssh authorization-type default aaa
#
ssh server cipher aes256_gcm aes128_gcm aes256_ctr aes192_ctr aes128_ctr aes256_
cbc aes128_cbc 3des_cbc
#
ssh client cipher aes256_gcm aes128_gcm aes256_ctr aes192_ctr aes128_ctr aes256_
cbc aes128_cbc 3des_cbc
#
user-interface vty 0 4
authentication-mode aaa
user privilege level 3
protocol inbound ssh
#
netconf
protocol inbound ssh port 830
测试连接
配置代码:
因为需要ncclient模块,所以提前pip安装ncclient
所有代码:
!pip install ncclient
from ncclient import manager
from ncclient import operations
import paramiko
import time
#设备参数
ip = '1.1.1.1'
netconf_port = '830'
netconf_user = 'netconf'
netconf_password = 'Huawei@123'
filename='netconf.txt'
from ncclient import manager
# 定义NETCONF连接参数
ip = "1.1.1.1"
netconf_port = 830
netconf_user = "netconf"
netconf_password = "Huawei@123"
# 定义要发送的NETCONF配置
CONFIGURE_INTERFACE_DESCRIPTION = '''
<config>
<ifm xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<interfaces>
<interface operation="merge">
<ifName>GE1/0/0</ifName>
<ifDescr>Configured by NETCONF</ifDescr>
</interface>
</interfaces>
</ifm>
</config>
'''
# 定义NETCONF连接函数
def huawei_connect(host, port, user, password):
return manager.connect(host=host,
port=port,
username=user,
password=password,
hostkey_verify=False,
device_params={'name': "huawei"},
allow_agent=False,
look_for_keys=False)
# 主函数,建立NETCONF连接并发送配置
if __name__ == '__main__':
m = huawei_connect(ip, netconf_port, netconf_user, netconf_password)
if m:
print("NETCONF connection established")
response = m.edit_config(target='running', config=CONFIGURE_INTERFACE_DESCRIPTION)
print(response)
else:
print("Failed to establish NETCONF connection")
检查描述: