Selenium初探之自动备份设备配置文件及上传 – 作者:hackerbaba

*本文原创作者:hackerbaba,本文属FreeBuf原创奖励计划,未经许可禁止转载

一、背景介绍   

在传统的网络安全架构中,难免会有一些重要的安全设备或是软件配置需要定期备份,统一归档。一是为了满足合规,二是在设备变更出现问题的时候,能够快速回滚。手工定期备份难免会有遗漏,且浪费大量人力。

为了满足这一需求,我利用Selenium (浏览器自动化测试框架)实现这个自动备份功能,当然其他的python爬虫模块(比如request)也能实现这个功能(大体步骤都差不多),这个后续会继续分享给大家,这次就不在这里讨论。实现自动备份后,再利用python  FTP模块实现统一归档到FTP服务器。备份周期直接利用cron命令即可。既然有脚本自然少不了是否备份成功告警,利用logging模块记录日志,然后再通过rsyslog或第三方转发器传至日志分析平台即可实现告警,我们公司由于使用的splunk,利用splunk forward传输日志即可。有些人可能对Selenium不是太了解,下面我稍微简单介绍一下Selenium。

二、Selenium+Chrome配置及功能说明

Selenium是一个浏览器自动化测试框架。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。Selenium在爬虫中的运用主要就是查找html相应元素并进行元素交互操作,常见的8种元素定位的方法如下:

find_element_by_name

find_element_by_id

find_element_by_xpath

find_element_by_link_text

find_element_by_partial_link_text

find_element_by_tag_name

find_element_by_class_name

find_element_by_css_selector

其中最常用的就是find_element_by_name/id/xpath/link_text,其中xpath推荐使用浏览器插件定位元素。火狐浏览器一般使用 firebug 和 firepath 定位元素;谷歌浏览器一般使用xpath helper插件定位元素。

Windows/linux除了安装Selenium模块外,一般需要下载浏览器对应的webdriver驱动到相应文件夹声明并调用浏览器,一个简单的示例如下:

from selenium import webdriver

browser = webdriver.Chrome() 或 browser =webdriver.Firefox()   #调用谷歌或者火狐浏览器

browser.get(“http://www.baidu.com“)  #浏览器打开百度

print(browser.page_source)  #打印百度首页的源码

browser.close()  #关闭浏览器

在linux系统中,还需要声明一些“无头”配置,具体见实现见脚本。

三、python+selenium+无头Chrome具体实现脚本

Python环境:3.7.0  selenium:3.141.0  chrome:72.0.3626.119

Webdriver下载地址  https://chromedriver.storage.googleapis.com/index.html

自动备份对象:某品牌WAF设备,其他设备更改IP地址、定位相关html元素即可。

#coding=utf-8

import os

import time

import logging

import ftplib

from ftplib import FTP

from selenium import webdriver

from selenium.webdriver.common.by import By

from selenium.webdriver.common.keys importKeys

from selenium.webdriver.support.ui import Select

from selenium.webdriver importDesiredCapabilities

from selenium.webdriver.chrome.optionsimport Options

 

Device = 'WAF'    #定义设备类型

IP = 'x.x.x.x'         #目标IP

dir_time = time.strftime('%Y-%m-%d',time.localtime())

#输出当前"年-月-日"时间

dir_backup =f'/opt/sec_backup/{IP}_{Device}/{dir_time}'

#chrome下载的地址备份文件的路径

log_name =f'/opt/sec_backup/log/{IP}/{dir_time}.log'

#存放日志文件的路径

if os.path.exists(dir_backup):

   pass

else:

   os.mkdir(f'/opt/sec_backup/{IP}_{Device}/{dir_time}')

#创建dir_backup路径

 

host = 'X.X.X.X'

port = 21

user = 'XXXX'

pwd = 'XXXXX'

#以上定义FTP服务器相关信息

logging.basicConfig(filename=log_name,level=logging.INFO,format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

logger = logging.getLogger(__name__)

#定义日志输出格式

try:

   opts = Options()

   opts.headless=True

   opts.add_argument('--no-sandbox')

   opts.add_argument('--disable-gpu')

   capabilities = DesiredCapabilities.CHROME.copy()

   capabilities['acceptSslCerts'] = True

   capabilities['acceptInsecureCerts'] = True

   prefs = {'download.prompt_for_download': False,

            'download.directory_upgrade': True,

            'safebrowsing.enabled': False,

            'safebrowsing.disable_download_protection': True}

   opts.add_experimental_option('prefs', prefs)

   driver = webdriver.Chrome(options=opts,desired_capabilities=capabilities)

#以上是“无头”的一些配置,具体就不一一展开

driver.implicitly_wait(10) 

#设置超时时间10秒钟

   driver.command_executor._commands["send_command"] =("POST",'/session/$sessionId/chromium/send_command')

   driver.desired_capabilities['browserName'] = 'ur mum'

   params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior':'allow', 'downloadPath': '%s' %dir_backup }}

   driver.execute("send_command", params)

#Chrome下载备份文件到dir_backup目录

   driver.get(f"https://{IP}/login/requireLogin")

   driver.find_element_by_id("username").send_keys("xxx")

   driver.find_element_by_id("password").send_keys("xxx")

   driver.find_element_by_id("loginButton").click()

    driver.find_element_by_id("one3").click()

   driver.find_element_by_id("two32").click()

   driver.switch_to.frame("mainFrame")

   driver.find_element_by_link_text("配置同步").click()

   driver.find_element_by_xpath("(//input[@id='tmp'])[2]").click()

   time.sleep(30)

   driver.switch_to.alert.accept()

   driver.find_element_by_xpath("//*[@id='backpointtable']/tbody/tr[2]/td[5]/img[3]").click()

   while True:

       if os.listdir(dir_backup) andos.listdir(dir_backup)[0].endswith('.wafc'):

#备份周期是天,一天只生成一个固定目录,里面只有一个备份文件,故判断是否有文件即可

           logger.info('备份成功')

           break

       else:

           continue

   

   driver.find_element_by_link_text("配置同步").click()

   driver.find_element_by_xpath("//*[@id='backpointtable']/tbody/tr[2]/td[5]/img[4]").click()

   confirm2 = driver.switch_to.alert

   confirm2.accept()

   driver.quit()

   #logger.info('删除旧备份成功')

except Exception as e:

   logger.info(f"自动备份出现异常,异常内容:{e}")

   

def ftpconnect():

   ftp_server = host

   username = user

    password = pwd

   ftp = FTP()

   ftp.set_debuglevel(0)

   ftp.connect(ftp_server, 21)

   ftp.login(username, password)

   return ftp

 

def uploadfile():

   try:

       ftp = ftpconnect()

       remotepath = ftp.mkd(f'/{IP}-{Device}/{dir_time}')

   except:

       pass

   ftp.cwd(remotepath)

   bufsize = 1024

   localfile = dir_backup + '/' + os.listdir(dir_backup)[0]

   remotefile = os.listdir(dir_backup)[0]

   print(localfile)

   fp = open(localfile, 'rb')

   ftp.storbinary('STOR ' + remotefile, fp, bufsize)

#上传本地localfile,至remotepath,并命名remotefile

   ftp.set_debuglevel(0)

#关闭ftp的调试模式,如果设置为2,则输出详细信息

   fp.close() 

 

if __name__ == '__main__':

   try:

       uploadfile()

   except Exception as e:

       logger.info(f"文件上传出现异常,异常内容:{e}")

   else:

       logger.info('文件上传成功')

四、效果图

image.pngimage.png image.pngimage.png

关于告警:log文件出现“异常”字样即可告警。

*本文原创作者:hackerbaba,本文属FreeBuf原创奖励计划,未经许可禁止转载

来源:freebuf.com 2019-03-19 09:00:52 by: hackerbaba

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论