背景
在网络配置文件或类似的文本中,table是一种常见的结构,通常嵌套在其他table中。提取这些嵌套的table可以帮助我们理解文本的结构和内容。
示例文本
我们将使用以下示例文本作为演示的基础:
text = """
table inet fw4 {
chain INPUT {
type filter hook input priority 0; policy accept;
}
chain FORWARD {
type filter hook forward priority 0; policy accept;
}
}
"""
提取嵌套的table
首先,我们需要编写代码来提取嵌套的table。以下是提取table的Python代码:
import re
# 使用循环提取多层嵌套的table
def extract_tables(text):
tables = []
while True:
match = re.search(r'table ([^{]+) {', text)
if not match:
break
table_name = match.group(1)
start = match.start()
level = 1
for i in range(match.end(), len(text)):
if text[i] == '{':
level += 1
elif text[i] == '}':
level -= 1
if level == 0:
end = i + 1
table_content = text[match.end():i]
tables.append((table_name, table_content))
text = text[:start] + text[end:]
break
return tables
tables = extract_tables(text)
这段代码使用正则表达式来匹配table的定义,并逐层提取嵌套的table。每个table的名称和内容都被存储在一个元组中,然后添加到列表中。
输出提取的table
最后,我们可以输出提取的table。以下是输出的代码:
for i, (table_name, table) in enumerate(tables):
print(f"Table {i + 1}: {table_name}")
print(table)
print()
这段代码遍历提取的table列表,打印每个table的名称和内容。
升级版
import re
# 使用循环提取多层嵌套的table
def extract_tables(text):
tables = []
while True:
match = re.search(r'table ([^{]+) { # handle (\d+)', text)
if not match:
break
table_name = match.group(1)
start = match.start()
level = 1
for i in range(match.end(), len(text)):
if text[i] == '{':
level += 1
elif text[i] == '}':
level -= 1
if level == 0:
end = i + 1
table_content = text[match.end():i]
tables.append((table_name, table_content))
text = text[:start] + text[end:]
break
return tables
def extract_chains(text):
# 使用正则表达式提取chain名和规则
pattern = r'chain (\w+) \{ # handle (\d+)([\s\S]*?)\}'
matches = re.findall(pattern, text)
for match in matches:
chain_name = match[0]
handle = match[1]
rules = match[2]
print(f"\tChain名: {chain_name}, Handle:{handle}")
print(f"\t规则:{rules}\n")
with open ("rule.txt", "r") as fd:
text = fd.read()
tables = extract_tables(text)
for i, (table_name, table) in enumerate(tables):
print(f"Table {i + 1}: {table_name}")
extract_chains(table)
# print(table)
测试文本
$ sudo nft -a list ruleset
table ip filter { # handle 1
chain LIBVIRT_INP { # handle 1
iifname "virbr0" meta l4proto udp udp dport 53 counter packets 0 bytes 0 accept # handle 23
iifname "virbr0" meta l4proto tcp tcp dport 53 counter packets 0 bytes 0 accept # handle 22
iifname "virbr0" meta l4proto udp udp dport 67 counter packets 0 bytes 0 accept # handle 19
iifname "virbr0" meta l4proto tcp tcp dport 67 counter packets 0 bytes 0 accept # handle 18
}
chain INPUT { # handle 6
type filter hook input priority filter; policy accept;
counter packets 54430643 bytes 21660608472 jump LIBVIRT_INP # handle 7
}
chain LIBVIRT_OUT { # handle 8
oifname "virbr0" meta l4proto udp udp dport 53 counter packets 0 bytes 0 accept # handle 25
oifname "virbr0" meta l4proto tcp tcp dport 53 counter packets 0 bytes 0 accept # handle 24
oifname "virbr0" meta l4proto udp udp dport 68 counter packets 0 bytes 0 accept # handle 21
oifname "virbr0" meta l4proto tcp tcp dport 68 counter packets 0 bytes 0 accept # handle 20
}
chain OUTPUT { # handle 9
type filter hook output priority filter; policy accept;
counter packets 6307453 bytes 12068891202 jump LIBVIRT_OUT # handle 10
}
chain LIBVIRT_FWO { # handle 11
iifname "virbr0" ip saddr 192.168.122.0/24 counter packets 0 bytes 0 accept # handle 29
iifname "virbr0" counter packets 0 bytes 0 reject # handle 26
}
chain FORWARD { # handle 12
type filter hook forward priority filter; policy accept;
counter packets 6 bytes 614 jump LIBVIRT_FWX # handle 17
counter packets 6 bytes 614 jump LIBVIRT_FWI # handle 15
counter packets 6 bytes 614 jump LIBVIRT_FWO # handle 13
}
chain LIBVIRT_FWI { # handle 14
oifname "virbr0" ip daddr 192.168.122.0/24 ct state related,established counter packets 0 bytes 0 accept # handle 30
oifname "virbr0" counter packets 0 bytes 0 reject # handle 27
}
chain LIBVIRT_FWX { # handle 16
iifname "virbr0" oifname "virbr0" counter packets 0 bytes 0 accept # handle 28
}
}
table ip nat { # handle 2
chain LIBVIRT_PRT { # handle 1
ip saddr 192.168.122.0/24 ip daddr 224.0.0.0/24 counter packets 136 bytes 18835 return # handle 8
ip saddr 192.168.122.0/24 ip daddr 255.255.255.255 counter packets 0 bytes 0 return # handle 7
meta l4proto tcp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade to :1024-65535 # handle 6
meta l4proto udp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 4 bytes 2540 masquerade to :1024-65535 # handle 5
ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade # handle 4
}
chain POSTROUTING { # handle 2
type nat hook postrouting priority srcnat; policy accept;
counter packets 211353 bytes 15080785 jump LIBVIRT_PRT # handle 3
}
}
table ip mangle { # handle 3
chain LIBVIRT_PRT { # handle 1
oifname "virbr0" meta l4proto udp udp dport 68 counter packets 0 bytes 0 # CHECKSUM fill # handle 4
}
chain POSTROUTING { # handle 2
type filter hook postrouting priority mangle; policy accept;
counter packets 6310223 bytes 12069137654 jump LIBVIRT_PRT # handle 3
}
}
table ip6 filter { # handle 4
chain LIBVIRT_INP { # handle 1
}
chain INPUT { # handle 2
type filter hook input priority filter; policy accept;
counter packets 73361582 bytes 11778699736 jump LIBVIRT_INP # handle 3
}
chain LIBVIRT_OUT { # handle 4
}
chain OUTPUT { # handle 5
type filter hook output priority filter; policy accept;
counter packets 1212826 bytes 151695088 jump LIBVIRT_OUT # handle 6
}
chain LIBVIRT_FWO { # handle 7
}
chain FORWARD { # handle 8
type filter hook forward priority filter; policy accept;
counter packets 0 bytes 0 jump LIBVIRT_FWX # handle 13
counter packets 0 bytes 0 jump LIBVIRT_FWI # handle 11
counter packets 0 bytes 0 jump LIBVIRT_FWO # handle 9
}
chain LIBVIRT_FWI { # handle 10
}
chain LIBVIRT_FWX { # handle 12
}
}
table ip6 nat { # handle 5
chain LIBVIRT_PRT { # handle 1
}
chain POSTROUTING { # handle 2
type nat hook postrouting priority srcnat; policy accept;
counter packets 0 bytes 0 jump LIBVIRT_PRT # handle 3
}
}
table ip6 mangle { # handle 6
chain LIBVIRT_PRT { # handle 1
}
chain POSTROUTING { # handle 2
type filter hook postrouting priority mangle; policy accept;
counter packets 1214614 bytes 152003369 jump LIBVIRT_PRT # handle 3
}
}
测试输出
$ python3 test.py
Table 1: ip filter
Chain名: LIBVIRT_INP, Handle:1
规则:
iifname "virbr0" meta l4proto udp udp dport 53 counter packets 0 bytes 0 accept # handle 23
iifname "virbr0" meta l4proto tcp tcp dport 53 counter packets 0 bytes 0 accept # handle 22
iifname "virbr0" meta l4proto udp udp dport 67 counter packets 0 bytes 0 accept # handle 19
iifname "virbr0" meta l4proto tcp tcp dport 67 counter packets 0 bytes 0 accept # handle 18
Chain名: INPUT, Handle:6
规则:
type filter hook input priority filter; policy accept;
counter packets 54423964 bytes 21655605002 jump LIBVIRT_INP # handle 7
Chain名: LIBVIRT_OUT, Handle:8
规则:
oifname "virbr0" meta l4proto udp udp dport 53 counter packets 0 bytes 0 accept # handle 25
oifname "virbr0" meta l4proto tcp tcp dport 53 counter packets 0 bytes 0 accept # handle 24
oifname "virbr0" meta l4proto udp udp dport 68 counter packets 0 bytes 0 accept # handle 21
oifname "virbr0" meta l4proto tcp tcp dport 68 counter packets 0 bytes 0 accept # handle 20
Chain名: OUTPUT, Handle:9
规则:
type filter hook output priority filter; policy accept;
counter packets 6301967 bytes 12065260193 jump LIBVIRT_OUT # handle 10
Chain名: LIBVIRT_FWO, Handle:11
规则:
iifname "virbr0" ip saddr 192.168.122.0/24 counter packets 0 bytes 0 accept # handle 29
iifname "virbr0" counter packets 0 bytes 0 reject # handle 26
Chain名: FORWARD, Handle:12
规则:
type filter hook forward priority filter; policy accept;
counter packets 6 bytes 614 jump LIBVIRT_FWX # handle 17
counter packets 6 bytes 614 jump LIBVIRT_FWI # handle 15
counter packets 6 bytes 614 jump LIBVIRT_FWO # handle 13
Chain名: LIBVIRT_FWI, Handle:14
规则:
oifname "virbr0" ip daddr 192.168.122.0/24 ct state related,established counter packets 0 bytes 0 accept # handle 30
oifname "virbr0" counter packets 0 bytes 0 reject # handle 27
Chain名: LIBVIRT_FWX, Handle:16
规则:
iifname "virbr0" oifname "virbr0" counter packets 0 bytes 0 accept # handle 28
Table 2: ip nat
Chain名: LIBVIRT_PRT, Handle:1
规则:
ip saddr 192.168.122.0/24 ip daddr 224.0.0.0/24 counter packets 136 bytes 18835 return # handle 8
ip saddr 192.168.122.0/24 ip daddr 255.255.255.255 counter packets 0 bytes 0 return # handle 7
meta l4proto tcp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade to :1024-65535 # handle 6
meta l4proto udp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 4 bytes 2540 masquerade to :1024-65535 # handle 5
ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade # handle 4
Chain名: POSTROUTING, Handle:2
规则:
type nat hook postrouting priority srcnat; policy accept;
counter packets 211148 bytes 15066090 jump LIBVIRT_PRT # handle 3
Table 3: ip mangle
Chain名: LIBVIRT_PRT, Handle:1
规则:
oifname "virbr0" meta l4proto udp udp dport 68 counter packets 0 bytes 0 # CHECKSUM fill # handle 4
Chain名: POSTROUTING, Handle:2
规则:
type filter hook postrouting priority mangle; policy accept;
counter packets 6304722 bytes 12065504217 jump LIBVIRT_PRT # handle 3
Table 4: ip6 filter
Chain名: LIBVIRT_INP, Handle:1
规则:
Chain名: INPUT, Handle:2
规则:
type filter hook input priority filter; policy accept;
counter packets 73361177 bytes 11778651135 jump LIBVIRT_INP # handle 3
Chain名: LIBVIRT_OUT, Handle:4
规则:
Chain名: OUTPUT, Handle:5
规则:
type filter hook output priority filter; policy accept;
counter packets 1212826 bytes 151695088 jump LIBVIRT_OUT # handle 6
Chain名: LIBVIRT_FWO, Handle:7
规则:
Chain名: FORWARD, Handle:8
规则:
type filter hook forward priority filter; policy accept;
counter packets 0 bytes 0 jump LIBVIRT_FWX # handle 13
counter packets 0 bytes 0 jump LIBVIRT_FWI # handle 11
counter packets 0 bytes 0 jump LIBVIRT_FWO # handle 9
Chain名: LIBVIRT_FWI, Handle:10
规则:
Chain名: LIBVIRT_FWX, Handle:12
规则:
Table 5: ip6 nat
Chain名: LIBVIRT_PRT, Handle:1
规则:
Chain名: POSTROUTING, Handle:2
规则:
type nat hook postrouting priority srcnat; policy accept;
counter packets 0 bytes 0 jump LIBVIRT_PRT # handle 3
Table 6: ip6 mangle
Chain名: LIBVIRT_PRT, Handle:1
规则:
Chain名: POSTROUTING, Handle:2
规则:
type filter hook postrouting priority mangle; policy accept;
counter packets 1214614 bytes 152003369 jump LIBVIRT_PRT # handle 3