55from simulator .packet import PacketIP , PacketTCPUDP , PacketICMP
66from utils .logger import log_debug , log_warn
77
8+ # todo: add explicit match-tests
9+
810
911# pylint: disable=R0912
1012class RuleMatcherNetfilter (RuleMatcher ):
@@ -16,95 +18,95 @@ def matches(self, packet: (PacketIP, PacketTCPUDP, PacketICMP), rule: Rule) -> R
1618 """
1719 nf_rule : NftRule = rule .raw
1820
19- if rule .action is None :
21+ if rule .action is None or \
22+ not issubclass (rule .action , (RuleActionKindTerminal , RuleActionKindToChain , RuleActionKindNAT )):
2023 return RuleMatchResult (False , None , None , None , None )
2124
22- if issubclass (rule .action , (RuleActionKindTerminal , RuleActionKindToChain , RuleActionKindNAT )):
23- results = []
24-
25- if len (nf_rule .matches ) == 0 :
26- return RuleMatchResult (
27- matched = True ,
28- action = rule .action ,
29- target_chain_name = nf_rule .target_chain ,
30- target_nat_ip = nf_rule .target_nat_ip ,
31- target_nat_port = nf_rule .target_nat_port ,
32- )
33-
34- for match in nf_rule .matches :
35- single_l3_result = True # 'ip6 daddr != XXX' would drop any IPv4 traffic
36- single_results = []
37- # NETWORK INTERFACES
38- if match .match_ni_in :
39- single_results .append (packet .ni_in in match .value )
40-
41- if match .match_ni_out :
42- single_results .append (packet .ni_out in match .value )
43-
44- # IP PROTOCOL
45- if match .match_proto_l3 :
46- if match .value_proto_l3 :
47- single_l3_result = packet .proto_l3 == match .value_proto_l3
48-
49- else :
50- single_l3_result = packet .proto_l3 in match .value
51-
52- # IP SOURCE AND DESTINATION
53- if match .match_ip_saddr :
54- single_results .append (any (
55- packet .src in ip_net for ip_net in match .value
56- ))
57-
58- if match .match_ip_daddr :
59- single_results .append (any (
60- packet .dst in ip_net for ip_net in match .value
61- ))
62-
63- # TRANSPORT PROTOCOL
64- if match .match_proto_l4 :
65- if match .value_proto_l4 :
66- single_results .append (packet .proto_l4 == match .value_proto_l4 )
67-
68- else :
69- single_results .append (packet .proto_l4 in match .value )
70-
71- if isinstance (packet , PacketTCPUDP ):
72- # PORTS
73- if match .match_sport :
74- single_results .append (packet .sport in match .value )
75-
76- if match .match_dport :
77- single_results .append (packet .dport in match .value )
78-
79- # CONNECTION TRACKING STATE
80- if match .match_ct :
81- single_results .append (packet .ct in match .value )
82-
83- # if we need to separate the L3-result from the actual condition as it can impact the match
84- results .append (single_l3_result )
85-
86- if len (single_results ) > 0 :
87- if match .operator in [match .OP_EQ , match .OP_IN ]:
88- results .append (all (single_results ))
89-
90- elif match .operator in [match .OP_NE , match .OP_NOT ]:
91- results .append (not all (single_results ))
92-
93- else :
94- log_warn ('Firewall Plugin' , f' > Unable to get results for operator "{ match .operator } "' )
95-
96- if len (results ) == 0 :
97- log_warn ('Firewall Plugin' , ' > Matches: Found not matches we could process - skipping rule' )
98-
99- else :
100- log_debug ('Firewall Plugin' , f' > Match Results: { nf_rule .get_match_types ()} => { results } ' )
101-
102- return RuleMatchResult (
103- matched = all (results ),
104- action = rule .action ,
105- target_chain_name = nf_rule .target_chain ,
106- target_nat_ip = nf_rule .target_nat_ip ,
107- target_nat_port = nf_rule .target_nat_port ,
108- )
25+ results = []
26+
27+ if len (nf_rule .matches ) == 0 :
28+ return RuleMatchResult (
29+ matched = True ,
30+ action = rule .action ,
31+ target_chain_name = nf_rule .target_chain ,
32+ target_nat_ip = nf_rule .target_nat_ip ,
33+ target_nat_port = nf_rule .target_nat_port ,
34+ )
35+
36+ for match in nf_rule .matches :
37+ single_l3_result = True # 'ip6 daddr != XXX' would drop any IPv4 traffic
38+ single_results = []
39+ # NETWORK INTERFACES
40+ if match .match_ni_in :
41+ single_results .append (packet .ni_in in match .value )
42+
43+ if match .match_ni_out :
44+ single_results .append (packet .ni_out in match .value )
45+
46+ # IP PROTOCOL
47+ if match .match_proto_l3 :
48+ if match .value_proto_l3 :
49+ single_l3_result = packet .proto_l3 == match .value_proto_l3
50+
51+ else :
52+ single_l3_result = packet .proto_l3 in match .value
53+
54+ # IP SOURCE AND DESTINATION
55+ if match .match_ip_saddr :
56+ single_results .append (any (
57+ packet .src in ip_net for ip_net in match .value
58+ ))
59+
60+ if match .match_ip_daddr :
61+ single_results .append (any (
62+ packet .dst in ip_net for ip_net in match .value
63+ ))
64+
65+ # TRANSPORT PROTOCOL
66+ if match .match_proto_l4 :
67+ if match .value_proto_l4 :
68+ single_results .append (packet .proto_l4 == match .value_proto_l4 )
69+
70+ else :
71+ single_results .append (packet .proto_l4 in match .value )
72+
73+ if isinstance (packet , PacketTCPUDP ):
74+ # PORTS
75+ if match .match_sport :
76+ single_results .append (packet .sport in match .value )
77+
78+ if match .match_dport :
79+ single_results .append (packet .dport in match .value )
80+
81+ # CONNECTION TRACKING STATE
82+ if match .match_ct :
83+ single_results .append (packet .ct in match .value )
84+
85+ # if we need to separate the L3-result from the actual condition as it can impact the match
86+ results .append (single_l3_result )
87+
88+ if len (single_results ) > 0 :
89+ if match .operator in [match .OP_EQ , match .OP_IN ]:
90+ results .append (all (single_results ))
91+
92+ elif match .operator in [match .OP_NE , match .OP_NOT ]:
93+ results .append (not all (single_results ))
94+
95+ else :
96+ log_warn ('Firewall Plugin' , f' > Unable to get results for operator "{ match .operator } "' )
97+
98+ if len (results ) == 0 :
99+ log_warn ('Firewall Plugin' , ' > Matches: Found not matches we could process - skipping rule' )
100+
101+ else :
102+ log_debug ('Firewall Plugin' , f' > Match Results: { nf_rule .get_matches ()} => { results } ' )
103+
104+ return RuleMatchResult (
105+ matched = all (results ),
106+ action = rule .action ,
107+ target_chain_name = nf_rule .target_chain ,
108+ target_nat_ip = nf_rule .target_nat_ip ,
109+ target_nat_port = nf_rule .target_nat_port ,
110+ )
109111
110112 return RuleMatchResult (False , None , None , None , None )
0 commit comments