zl程序教程

您现在的位置是:首页 >  后端

当前栏目

python实用脚本:网络设备批量调试及备份

Python批量调试备份 脚本 实用 网络设备
2023-06-13 09:14:08 时间

本脚本由群友似水年华大佬分享,

大佬为了简化脚本的环境搭建把脚本封装成了exe方便大家哪来即用。

dev_config.exe是批量配置的脚本,调用ip.txt里放的ip输入用户名密码登陆设备,运行cmd.txt的命令。

dev_bak.exe是备份脚本,调用ip.txt的ip输入用户名密码登陆设备,实现配置备份。

视频演示如下: http://mpvideo.qpic.cn/0bf2kmaaiaaa2uanlfqkizqfau6darjqabaa.f10002.mp4?

以下是脚本部分为三个文件:

说明:第一个文件,devlogin.py是做的一个设备登陆的类,其他使用的时候引入这个就好了,dev_bak是配置备份的文件,其中设备登陆部分是从第一个文件引入的,第二个同理。如果需要多设备支持,就需要对devlogin.py里面去优化。

现在devlogin里面做了思科,华为,juniper-netscreen,所以其他的需要优化这部分。

devlogin.py登陆文件

import netmiko
import socket
import re
from netmiko import ConnectHandler, SSHDetect
from netmiko.ssh_exception import NetMikoTimeoutException
from netmiko.ssh_exception import NetMikoAuthenticationException
##This script use to login device by ssh or telnet,it will detect the TCP port (22,23) automaticly and
#find out which is open to use,you can use port_scan to comfirm which metod will be used to connect device
#and following two Classes are the different because the first one is only use to login cisco device,and 
#second one is use to login all devices now it supports 'cisco','huawei','juniper',and it can be detect 
#automatic!
##
class CiscoLogin():
    ##Only use to Login cisco device!!!
    #
    def __init__(self,username,password,enable_pwd,ip):
        self.username = username
        self.password = password
        self.enable_pwd = enable_pwd
        self.ip = ip

    def port_scan(self):
        connect_protocol = 'unknown'
        sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        try:
            sock.connect((self.ip,22))
            sock.shutdown(2)
            sock.close()
            connect_protocol = 'ssh'
        except Exception as e:
            try:
                sock.connect((self.ip,23))
                sock.shutdown(2)
                sock.close()
                connect_protocol = 'telnet'
            except Exception as e:
                print('[+]%s端口不可达'%self.ip)
        return connect_protocol

    def ssh_login(self):
        auth_flag = False
        net_conn = ''
        hostname = ''
        devtype = ''
        device = {
            'device_type': 'cisco_ios',
            'ip': self.ip,
            'username': self.username,
            'password': self.password,
            'secret': self.enable_pwd,
        #    'timeout': 5,
        }
        # 尝试探测设备型号以及登陆设备
        try:
            devtype = 'cisco_ios'
            print ('-' * 30)
            print ("[+] Trying to connect to: " + self.ip)
            net_conn = ConnectHandler(**device)
            # print (net_conn)
            print ("[+] connected to: " + self.ip)
            login_out = net_conn.find_prompt()
            print(login_out)
            hostname = login_out.replace('#', ' ').replace('>',' ').rstrip()
            if '#' in login_out:
                auth_flag = True
                print('login success')
            elif '>' in login_out:
                try:
                    net_conn.enable()
                    auth_flag = True
                except Exception as e:
                    print('ENABLE authtication fail')
        except (EOFError, NetMikoAuthenticationException):
            print ('username/password wrong!')
        except (ValueError,NetMikoAuthenticationException):
            print ('enable password wrong!')

        return net_conn, auth_flag, hostname, devtype

    def telnet_login(self):
        auth_flag = False
        net_conn = ''
        hostname = ''
        devtype = ''
        device = {
            'device_type': 'cisco_ios_telnet',
            'ip': self.ip,
            'username': self.username,
            'password': self.password,
            'secret': self.enable_pwd,
        }
    # 尝试探测设备型号以及登陆设备
        print ('[+] 尝试TELNET登陆%s设备...' % self.ip)
        try:
            devtype = 'cisco_ios_telnet'
            net_conn = ConnectHandler(**device)
            login_out = net_conn.find_prompt()
            if '#' in login_out:
                auth_flag = True
                hostname = login_out.replace('#', '')
            elif '>' in login_out:
                try:
                    net_conn.enable()
                    if net_conn.check_enable_mode():
                        auth_flag = True
                        hostname = login_out.replace('#', '')
                        print('[+] 登陆ASA:%s设备成功...' % self.ip)
                except Exception as e:
                    print('ENABLE认证失败')
        except (EOFError, NetMikoAuthenticationException):
            print ('username/password wrong!')
        except (ValueError,NetMikoAuthenticationException):
            print ('enable password wrong!')
        return net_conn, auth_flag, hostname, devtype


class AllDevLogin():
    ##Use to login all devices,and it can autodetect device brand,support 'cisco','huawei','juniper'
    ##
    def __init__ (self,username,password,enable_pwd,ip):
        self.username = username
        self.password = password
        self.enable_pwd = enable_pwd
        self.ip = ip  

    def port_scan(self):
        connect_protocol = 'unknown'
        sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        try:
            sock.connect((self.ip,22))
            sock.shutdown(2)
            sock.close()
            connect_protocol = 'ssh'
        except Exception as e:
            try:
                sock.connect((self.ip,23))
                sock.shutdown(2)
                sock.close()
                connect_protocol = 'telnet'
            except Exception as e:
                print('[+]%s端口不可达'%self.ip)
        return connect_protocol

    def telnet_autodetect(self):
        dev_detect_flag = False
        dev_telnet = {
            'device_type': 'cisco_ios_telnet',
            'ip': self.ip,
            'username': self.username,
            'password': self.password,
            'secret': self.enable_pwd,
          #  'timeout':5,
          #  'global_delay_factor':1.3,
        }
        net_conn = ConnectHandler(**dev_telnet)
        if True:
            dev_out = net_conn.send_command('show version')
            if 'Adaptive' in dev_out:
                devtype = 'cisco_asa_telnet'
            elif 'Cisco' in dev_out:
                devtype = 'cisco_ios_telnet'
            elif 'Unrecognized command' in dev_out:
                dev_out = net_conn.send_command('display version')
                devtype = 'huawei_telnet'
            elif 'unknown keyword' in dev_out:
                dev_out = net_conn.send_command('get sys')
                devtype = 'juniper_junos_telnet'
            else:
                devtype = 'None'
        return devtype


    def ssh_login(self):
        auth_flag = False
        net_conn = ''
        hostname = ''
        devtype = 'cisco_ios'
        device = {
            'device_type': 'autodetect',
            'ip': self.ip,
            'username': self.username,
            'password': self.password,
            'secret': self.enable_pwd,
            'timeout':5,
          #  'global_delay_factor':1.3,
        }
    # 尝试探测设备型号以及登陆设备
        try:   
            ###device autodetect
            print('[+] 正在尝试分析'+self.ip+'的设备品牌...')
            devtype_detect = SSHDetect(**device)
            devtype = devtype_detect.autodetect()
            device['device_type'] = devtype
            print ("[+] 正在尝试SSH登陆: " + self.ip)
            net_conn = ConnectHandler(**device)
            login_out = net_conn.find_prompt()
            print (login_out)
            ###SSH to device
            if  'cisco' in devtype:
                if '#' in login_out:
                    auth_flag = True
                    hostname = login_out.replace('#', '')
                #print (hostname)
                elif '>' in login_out :
                    net_conn.enable()
                    print('enable')
                    if net_conn.check_enable_mode():
                        auth_flag = True
                        hostname = login_out.replace('#', '')
                        print('[+] 登陆:%s设备成功...' % self.ip)
                    else:
                        print('[+] Enable:%s设备失败...' % self.ip)
            elif devtype == 'huawei':
                hostname = login_out.replace('<','').replace('>','')
                if  login_out:
                    auth_flag = True
                    print('[+] 登陆%s设备成功...'%self.ip)
                    if '>' in login_out:
                        try:
                            net_conn.config_mode()
                            auth_flag = True
                        except Exception as e:
                            print('[+] Config_mode authtication fail')
            elif devtype == 'netscreen' or 'juniper':
                hostname = login_out.replace('->','')
                if '>' in login_out:
                    auth_flag = True
        except (EOFError, NetMikoAuthenticationException):
            print ('username/password wrong!')
        except (ValueError,NetMikoAuthenticationException):
            print ('enable password wrong!')
        return net_conn, auth_flag, hostname, devtype

    def telnet_login(self):
        device = {
            'device_type': 'cisco_ios',
            'ip': self.ip,
            'username': self.username,
            'password': self.password,
            'secret': self.enable_pwd,
        }

        try:
            devtype= telnet_autodetect()
            device['device_type'] = devtype
            net_conn = ConnectHandler(**device)
            login_out = net_conn.find_prompt()
            if 'cisco' in devtype:
                print ('-' * 30)
                print ("[+] 正在尝试TELNET登陆: " + self.ip)
                hostname = login_out.replace('#', '').replace('>','')
                # print (hostname)
                if '#' in login_out:
                    auth_flag = True
                    print('[+] 登陆%s设备成功...'%self.ip)
                elif '>' in login_out:
                    try:
                        net_conn.enable()
                        if net_conn.check_enable_mode():
                            auth_flag = True
                    except Exception as e:
                        print('ENABLE authtication fail')
            elif devtype == 'huawei_telnet':
                print ('-' * 30)
                print ("[+] Trying to connect to: " + self.ip)
                net_conn = ConnectHandler(**device)
                print ("[+] Connected to: " + ip)
                login_out = net_conn.find_prompt()
                print(login_out)
                hostname = login_out.replace('<', '').replace('>','')
                # print (hostname)
                if ']' in login_out:
                    auth_flag = True
                    print('[+] 登陆%s设备成功...'%self.ip)
                elif '>' in login_out:
                    auth_flag = True
                    try:
                        net_conn.config_mode()
                        auth_flag = True
                    except Exception as e:
                        print('[+] Config_mode authtication fail')
            elif devtype ==  'juniper_junos_telnet':
                hostname = login_out.replace('->', '')
                print (hostname)
                if '>' in login_out:
                    auth_flag = True
        except (EOFError, NetMikoAuthenticationException):
            print ('username/password wrong!')
        except (ValueError,NetMikoAuthenticationException):
            print ('enable password wrong!')
        return net_conn, auth_flag, hostname, devtype

dev_config.py调试命令文件

import netmiko
import time
import csv
import re
import getpass
import socket
import devlogin
import fileinput
from netmiko import ConnectHandler, SSHDetect
from devlogin import CiscoLogin

def fail_write(fail_path, data):
    with open(fail_path, 'a', encoding='utf-8', newline='') as faillogin:
        faillogin.write(data + '\r\n')
def config_write(fail_path, data):
    with open(fail_path, 'a', encoding='utf-8', newline='') as config_write:
        config_write.write(data + '\r\n')
        config_write.write('-'*30 + '\r\n')
def device_config(net_conn,hostname,devtype,ip,config_commands):
    config_output = net_conn.send_config_from_file ('cmd.txt')
    print (config_output)
    return config_output
def main():
    total_time = 0
    file_path = 'config.txt'
    fail_path = 'fail.txt'
    config_commands = []
    dev_count = 0

    username = input('[+] Please Enter Username:')
    password = getpass.getpass('[+] Please Enter password:')
    enable_pwd = getpass.getpass('[+] Please Enter enable secret:')
    print ('[+] starting...')
    for cmd in fileinput.input('cmd.txt'):
        cmd= cmd.rstrip()
        config_commands.append(cmd)
    print('您要配置的命令如下:')
    for value in config_commands:
        print (value)
    cmd_comfirm= input('请确认是否使用以上命令进行配置[Y/N]?')
    if cmd_comfirm == 'y' or cmd_comfirm == 'Y':
        print ('-'*30)
        print ('[+] 开始执行...')
        print ('-'*30)
        for ip in fileinput.input('ip.txt'):
            start_time = time.time()
            ip = ip.rstrip()
            dev_count +=1
            print ('-' * 30)
            print ('[+] 正在尝试用用户名:'+ username +'登陆%s设备...'%ip)

            login = CiscoLogin(username,password,enable_pwd,ip)
            connect_protocol = login.port_scan()
            if connect_protocol == 'ssh':
                net_conn, auth_flag, hostname, devtype = login.ssh_login()
            elif connect_protocol == 'telnet':
                net_conn, auth_flag, hostname, devtype = login.telnet_login()
            else:
                print ('[+] 设备的端口不可达..')
            if auth_flag:
                config_output = device_config(net_conn,hostname,devtype,ip,config_commands)
                config_write(file_path,config_output)

            else:
                fail_write(fail_path, ip)
            print ('-'*30)
    else :
        print ('请修改cmd.txt中的命令后重新执行!脚本将直接退出!')
        exit(1)
    print ('总共配置了{0}设备'.format(dev_count))
    end_time = time.time()
    run_time = end_time - start_time
    run_time = round(run_time,2)
    total_time += run_time
    total_time = round(total_time,2)
    print ('[+] 运行耗时%s秒'%run_time)
    print ('[+] 运行总耗时%s秒'%total_time)
    conti=input('[+] 请按任意键退出:')
    if conti:
        exit(1)
if __name__ == '__main__':

    login_info = u'''
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            此脚本为CISCO设备批量配置脚本,

    请将需要配置的命令行保存在程序目录下并以cmd.txt命名,

    请将需要登陆的设备IP保存在程序目录下并以ip.txt命名,

    系统将自动读取IP以及命令并自动配置到设备,

    注意,请在命令行最后加上'do copy running start'/'do write'以

    确保配置能正确保存到设备!

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    '''
    print(login_info)
    main()

dev+bak.py备份文件:

import netmiko
import sys
import os
import time
import re
import fileinput
from netmiko import ConnectHandler, SSHDetect
from devlogin import AllDevLogin

def config_bak(net_conn,devtype):
    cmd = 'show run'
    if 'cisco' in devtype:
        config = net_conn.send_command('show running-config')
    elif devtype == 'huawei':
        config = net_conn.send_command('display current-configuration')
    else:
        print('[+] Not in Config Mode,Please check enable password')
    return config,cmd
def file_write(hostname,config,cmd,ip):
    filename = (u'{0}_{1}_{2}.txt'.format(hostname,ip,cmd))
    filepath = r'configbak/'
    if os.path.exists(filepath):
        print ('[+] The  "%s" file exists.' %filepath)
    else:
        print ('[+] Now, I will create the %s'%filepath)
        os.makedirs(filepath)

    save = open(filepath + filename,'w')
    print(u'[+] executing {0} command'.format(cmd))
    save.write(config)
    print(u'[+] {0} command executed,result was saved at configbak,named {2}!'.format(cmd,filepath,filename))
def main():
    # fail_path = 'fail.txt'
    username = input('[+] Please Enter Username:')
    password = input('[+] Please Enter password:')
    enable_pwd = input('[+] Please Enter enable secret:')
    print ('[+] start to backup...')
    for ip in fileinput.input('ip.txt'):
        ip = ip.rstrip()
        login = AllDevLogin(username,password,enable_pwd,ip)
        connect_protocol = login.port_scan()
        if connect_protocol == 'ssh':
            net_conn, auth_flag, hostname, devtype = login.ssh_login()
        elif connect_protocol == 'telnet':
            net_conn, auth_flag, hostname, devtype = login.telnet_login()
        if auth_flag:
            config, cmd = config_bak(net_conn, devtype)
            file_write(hostname,config,cmd,ip)
if __name__ == '__main__':
    login_info = u'''
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            此脚本为CISCO设备配置备份脚本,

    请将需要登陆的设备IP保存在程序目录下并以ip.txt命名,

    系统将自动读取IP并登陆到设备完成备份,并将备份保存在configbak文件夹下

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    '''
    print(login_info)
    main()

END