一、背景

最近有一个需求是想基于 Neo4j 做设备关联关系的查询和关联图的输出。就是通过输入一个公网IP+端口就可以查询其对应的后端F5地址信息和realserver信息。在实现这个功能之前,需要先将防火墙数据F5数据做一个关联。效果类似如下:

firewall-f5
firewall-f5

二、数据关联

bigip F5配置,F5的配置有node、pool、destination部分组成并关联,以下逐步看其关联关系。

1、node配置

node即主机的节点关系,其配置类似如下:

1ltm node /Common/192.168.20.78 {
2    address 192.168.20.78
3}

上面主要配置是的里面的IP地址信息。

2、pool配置

pool除了池名称外,还有members信息,members里包含的是node地址,配置类似如下:

1ltm pool /Common/POOL-BI-VGOP20160304 {
2    members {
3        /Common/192.168.20.78:21 {
4            address 192.168.20.78
5        }
6    }
7    monitor /Common/tcp_half_open
8}

3、destination virtual配置

ltm virtual配置中,除了配置名称,这里会涉及关联关系部分,destination指定的是F5上的虚地址,其对应的有pool,pool和上面提到的node关联住了。其对应的配置类似如下:

 1ltm virtual /Common/VIP-BI-VGOP20160304 {
 2    destination /Common/172.16.2.120:8021
 3    ip-protocol tcp
 4    mask 255.255.255.255
 5    pool /Common/POOL-BI-VGOP20160304
 6    profiles {
 7        /Common/ftp { }
 8        /Common/client-tcp-prof {
 9            context clientside
10        }
11        /Common/server-tcp-prof {
12            context serverside
13        }
14    }
15    source 0.0.0.0/0
16    source-address-translation {
17        pool /Common/Group1_POOL
18        type snat
19    }
20    translate-address enabled
21    translate-port enabled
22}

这3部分数据处理完成以后,对应的列表如下:

三、实现代码

有了上面的效果,结下来就是和防火墙上的数据进行对应就行了,防火墙上的数据导出后的格式类似如下:

1nat server zone untrust protocol icmp global 211.140.17.81 inside 172.16.2.21 vrrp 20
2nat server zone untrust protocol tcp global 211.140.17.97 8090 inside 172.16.2.22 8090 vrrp 20
3nat server zone untrust protocol tcp global 211.140.17.112 22 inside 172.16.2.112 22 vrrp 20
4nat server zone untrust protocol tcp global 211.140.17.107 443 inside 172.16.2.107 443 vrrp 20
5nat server zone untrust protocol tcp global 211.140.17.80 www inside 172.16.2.20 www vrrp 20

具体一并处理的代码如下:

 1#!/usr/bin/env python
 2# coding=utf8
 3# ===============================================================================
 4#   Copyright (C) 2020 www.361way.com site All rights reserved.
 5#   Filename      :ltm.py
 6#   Author        :yangbk <[email protected]>
 7#   Create Time   :2020-06-12 11:53
 8#   Description   :
 9# ===============================================================================
10import re,mmap
11import pandas as pd
12fb = open('bigip.conf')
13text = fb.read()
14def Nodeinfo(text):
15  try:
16    m = re.compile(r'ltm\s+node\s+(.*?)\s+{', flags=re.DOTALL)
17    nodes = re.findall(m,text)
18  except:
19    pass
20  return nodes
21def Poolinfo(text):
22  try:
23    #m = re.compile(r'ltm\s+pool.*?(\d+.\d+.\d+.\d+)monitor', flags=re.MULTILINE)
24    #m = re.compile(r'ltm\s+pool\s+(.*?)monitor', flags=re.DOTALL + re.MULTILINE)
25    m = re.compile(r'ltm\s+pool\s+(.*?)monitor', flags=re.DOTALL)
26    pools = re.findall(m,text)
27  except:
28    #continue
29    pass
30  datapool = []
31  for pool in pools:
32     #m = re.compile(r'/Common/(.*?)\s+{', flags=re.DOTALL)
33     #poolinfo = re.findall(m,pool)
34     #print(poolinfo)
35     pname = re.findall(r"/Common/(.*?)\s+{",pool)
36     ips = re.findall(r"address\s+(.*?)\s+",pool,flags=re.DOTALL)
37     if len(ips) >0:
38      pooldata = [pname[0],", ".join(ips)]
39      datapool.append(pooldata)
40  return datapool
41def Virtinfo(text):
42  try:
43    m = re.compile(r'ltm\s+virtual\s+(.*?)profiles', flags=re.DOTALL)
44    virts = re.findall(m,text)
45  except:
46    #continue
47    pass
48  datavirt = []
49  for virt in virts:
50     m = re.compile(r'/Common/(.*?)\s+', flags=re.DOTALL)
51     virtname = re.findall(r"/Common/(.*?)\s+{",virt)
52     f5ipport = re.findall(r"destination\s+/Common/(.*?)\s+",virt,flags=re.DOTALL)
53     poolname = re.findall(r"pool\s+/Common/(.*?)\s+",virt,flags=re.DOTALL)
54     if poolname:
55      data = [virtname[0],poolname[0],f5ipport[0]]
56      datavirt.append(data)
57  return datavirt
58def Fwinfo(file):
59  fb = open(file)
60  fw = fb.read()
61  fw = fw.replace("www", "80")
62  fw = fw.replace("ftp", "21")
63  fw = fw.replace(" ", ":")
64  #print(fw)
65  try:
66    #m = re.compile(r'global:(.*?):inside:(.*?):vrrp', flags=re.DOTALL)
67    m = re.compile(r'global:(.*?):inside:(.*?):vrrp')
68    fwinfo = re.findall(m,fw)
69    return fwinfo
70  except:
71    pass
72datapool = Poolinfo(text)
73datavirt = Virtinfo(text)
74df1 = pd.DataFrame(data=datapool,columns=['poolname','ips'])
75df2 = pd.DataFrame(data=datavirt,columns=['virtname','poolname','f5iport'])
76df3 = pd.merge(df2,df1,left_on='poolname',right_on='poolname')
77#print(result)
78#result.to_excel("f5.xlsx")
79datafw = Fwinfo("FW.txt")
80dffw = pd.DataFrame(data=datafw,columns=['pubip','f5iport'])
81result = pd.merge(dffw,df3,left_on='f5iport',right_on='f5iport')
82result.to_excel("fw-f5.xlsx")