美文网首页
基于python的防火墙自动化验证小工具

基于python的防火墙自动化验证小工具

作者: 金融测试民工 | 来源:发表于2021-01-17 20:49 被阅读0次

一、基于python的防火墙自动化验证小工具

#!/usr/bin/env python

#coding:utf-8

import paramiko

import sys

import getpass

username=raw_input("Please give a usrname:")

password=getpass.getpass("Please input puhuiop's password:")

def ssh(sys_ip,username,password,cmds):

    try:

        #创建ssh客户端

        client = paramiko.SSHClient()

        #第一次ssh远程时会提示输入yes或者no

        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        #密码方式远程连接

        client.connect(sys_ip, 22, username=username, password=password, timeout=2000)

        #执行命令,远程命令的执行其实是stderr,所以这里取stderr的值,这里还有待学习

        stdin, stdout,stderr = client.exec_command(cmds)

        print(stderr.read().strip())

    except Exception, e:

        print e

    finally:

        client.close()

if __name__=="__main__":

    sys_ip='XX.XX.XX.XX'

    sip=sys.argv[1]

    port=sys.argv[2]

    cmds = "echo '\n'|telnet %s %s |grep 'connected' |tail -n 1 1>&1" %(sip,port)

    ssh(sys_ip,username,password,cmds)

    运行命令:python 脚本名 目标IP 目标端口

    再输入用户名和密码,回车会输出运行结果,closed表示通的。

远程登录主机部分小结:

      1、使用python的getpass模块,可以在输入密码不将密码显示在屏幕上,即不回显;

      2、这里使用sys模块实现传参,但这种时候,IP和端口分别只能传单个值,我们验墙时通常都是批量的,需要考虑如何批量传参

二、使用argparse位置参数进行批量传参

  1、期望输入多个源IP、多个目标、多个端口

  2、脚本目前放置于堡垒机,期望源端也可以是系统名,使用squery命令来获取系统对应部署单元的IP;

import argparse

parser = argparse.ArgumentParser()

#源端IP

parser.add_argument('-s','--sip',help="Source ip", nargs = '+')

#目标IP

parser.add_argument('-d','--dip',help="Target IP", nargs = '+')

#目标端口

parser.add_argument('-p','--port',help="Target PORT", nargs = '+')

#系统名(下划线形式)

parser.add_argument('--sys',help="System NAME(eg:ph_yxd_pms)" )

args = parser.parse_args()

##取值实例

print (arfs.sip,args.dip,args.port)

   脚本运行命令:

python ver4.py -s 源ip1 源ip2 .. .. -d 目标ip1 目标ip2 .. .. -p 端口1 端口2 .. ..

或:

python ver4.py --sip 源ip1 源ip2 .. .. --dip 目标ip1 目标ip2 .. .. --port 端口1 端口2 .. ..

三、利用itertools模块得到列表之间的笛卡尔积:源地址、目标地址、端口分别有多个时,如何不遗漏地测试每个源地址到每个目标地址、每个端口的防火墙(笛卡尔积)。

def cartesian(sips,dips,ports):

    for x in itertools.product(sips,dips,ports):

        if __name__=="__main__":

            ##itertools生成的每行数据其实是元组形式(源IP,目标IP,端口IP)

            sys_ip=x[0]

            sys2_ip= x[1]

            sys2_port= x[2]

            cmds = "echo '\n'|telnet %s %s |grep 'connected' |tail -n 1 1>&1" % (sys2_ip,sys2_port)

            ssh(sys_ip,username,password,cmds,sys2_ip,sys2_port)

  笛卡尔积结果示例:

四、传参优化及参数判断

  1、有时候我们源端地址可能不局限与一个系统,源端IP非常多时,期望可以将这些IP以文件形式进行传参,所以利用python的open内置函数来读取文件,再将内容以列表形式传给上述生成笛卡尔积的方法;需要新增一个位置参数来接收文件。

  2、参数判断

    上述可以发现,源端地址的传参类型有IP(列表)、系统名(字符串)、文件名(文件),根据类型来确定该如何处理传入的源端地址:

列表:直接调用生成笛卡尔积的方法cartesian

系统名:先使用squery命令获取系统实例,生成列表,再调用cartesian方法

文件名:先读文件内容,生成列表,再调用cartesian方法

五、全量代码及传参说明

#!/usr/bin/env pythons

#coding:utf-8

import sys

import os

import paramiko

import argparse

import itertools

import getpass

username=raw_input("Please input a username: ")

password=getpass.getpass("Please input password: ")

'''

对远程执行命令的结果进行处理

'''

def result(sentence,sys_ip,sys2_ip,sys2_port):

        if 'closed' in sentence:

            print(sys_ip+' connected to '+sys2_ip +' '+ sys2_port+' is True')

        elif 'timed' in sentence:

            print(sys_ip+' connected to '+sys2_ip +' '+sys2_port +' is timed out')

        elif 'refused' in  sentence:

            print(sys_ip+' connected to '+sys2_ip +' ' +sys2_port +' is refused')

        else:

            print('False')

'''

远程登录验证防火墙实现方法

'''

def ssh(sys_ip,username,password,cmds,sys2_ip,sys2_port):

    try:

        client = paramiko.SSHClient()

        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        client.connect(sys_ip, 22, username=username, password=password, timeout=2000)

        stdin, stdout,stderr = client.exec_command(cmds)

        #print(stderr.read().strip())

        sentence=stderr.read().strip()

        result(sentence,sys_ip,sys2_ip,sys2_port)

    except Exception, e:

        print e

    finally:

        client.close()

'''

进行笛卡尔积计算(元组类型)

'''

def cartesian(sips,dips,ports):

    for x in itertools.product(sips,dips,ports):

        if __name__=="__main__":

            sys_ip=x[0]

            sys2_ip= x[1]

            sys2_port= x[2]

            cmds = "echo '\n'|telnet %s %s |grep 'connected' |tail -n 1 1>&1" % (sys2_ip,sys2_port)

            ssh(sys_ip,username,password,cmds,sys2_ip,sys2_port)

'''

处理传参,调用防火墙方法

'''       

parser = argparse.ArgumentParser()

parser.add_argument('-s','--sip',help="Source ip", nargs = '+')

parser.add_argument('--sys',help="System NAME(eg:ph_yxd_pms)" )

parser.add_argument('-f','--files',help="Source ip's File")

parser.add_argument('-d','--dip',help="Target IP", nargs = '+')

parser.add_argument('-p','--port',help="Target PORT", nargs = '+')

args = parser.parse_args()

if isinstance(args.sys,str):

    cmds="~/bin/servicetool squery -l |grep %s |grep -v -i 'PADIS' |grep -v -i 'docker'|grep -v -i 'openresty' |awk -F '.' '{print $1}'" %args.sys

    units=os.popen(cmds).read().split()

    for i in range(len(units)):

        print(units[i])

        cmd="~/bin/servicetool squery -s %s 2>/dev/null |grep [0-9]|awk -F ':' '{print $1}'" %units[i]

        val=os.popen(cmd).read().splitlines()

        cartesian(val,args.dip,args.port)

elif isinstance(args.sip,list):

    cartesian(args.sip,args.dip,args.port)

elif os.path.exists(args.files):

    f = open(args.files, 'r')

    val=f.read().decode('utf-8').splitlines()

    f.close()

    cartesian(filter(None,val),args.dip,args.port)

    传参方式:

python ver4.py --sys 系统名(下划线)-d 目标IP –p目标端口

python ver4.py --sys 系统名(下划线)--dip 目标IP  --port目标端口

python ver4.py -s 源ip1 源ip2 .. -d 目ip1 目ip1 .. -p 端口1 端口2 ..

python ver4.py -f 文件名(绝对路径或者相对路径)-d 目ip1 目ip1 .. -p 端口1 端口2 ..

说明:

  以上目标IP,既可以是IP地址,也可以是F5域名。

相关文章

网友评论

      本文标题:基于python的防火墙自动化验证小工具

      本文链接:https://www.haomeiwen.com/subject/eywiaktx.html