@@ -218,3 +218,168 @@ def test_firewall_inherit_table_priority_chain(prio_table, prio_chain, result):
218218
219219 fw ._run_tables ._inherit_table_priority_to_chain (table = table , chain = chain )
220220 assert chain .priority == result
221+
222+
223+ def test_firewall_chain_filter_pre_routing ():
224+ from simulator .firewall import Firewall
225+ from plugins .system .system_linux_netfilter import SystemLinuxNetfilter
226+ from plugins .translate .netfilter .ruleset import NetfilterRuleset , NetfilterChainOutput as Chain
227+
228+ ruleset = NetfilterRuleset (TESTDATA_RULESET ).get ()
229+ fw = Firewall (
230+ system = SystemLinuxNetfilter ,
231+ ruleset = ruleset ,
232+ )
233+
234+ dnat = SystemLinuxNetfilter .FIREWALL_NAT [FlowForward ]['dnat' ]
235+
236+ chains = [
237+ Chain (name = 'ingress' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'ingress' ),
238+ Chain (name = 'prerouting-early' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'prerouting' , priority = dnat ['priority' ] - 1 ),
239+ Chain (name = 'prerouting-dnat' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'prerouting' , priority = dnat ['priority' ]),
240+ Chain (name = 'output-early' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'output' , priority = dnat ['priority' ] - 1 ),
241+ Chain (name = 'output-dnat' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'output' , priority = dnat ['priority' ]),
242+ Chain (name = 'prerouting' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'prerouting' , priority = 0 ),
243+ Chain (name = 'input' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'input' ),
244+ Chain (name = 'forward' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'forward' ),
245+ Chain (name = 'postrouting' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'postrouting' ),
246+ ]
247+
248+ filtered_chains = [c for c in chains if fw ._run_tables ._chain_filter_pre_routing (chain = c , flow = FlowForward )]
249+ assert len (filtered_chains ) == 3
250+ assert filtered_chains [0 ].name == 'ingress'
251+ assert filtered_chains [1 ].name == 'prerouting-early'
252+ assert filtered_chains [2 ].name == 'prerouting-dnat'
253+
254+ filtered_chains = [c for c in chains if fw ._run_tables ._chain_filter_pre_routing (chain = c , flow = FlowInput )]
255+ assert len (filtered_chains ) == 3
256+ assert filtered_chains [0 ].name == 'ingress'
257+ assert filtered_chains [1 ].name == 'prerouting-early'
258+ assert filtered_chains [2 ].name == 'prerouting-dnat'
259+
260+ filtered_chains = [c for c in chains if fw ._run_tables ._chain_filter_pre_routing (chain = c , flow = FlowOutput )]
261+ assert len (filtered_chains ) == 2
262+ assert filtered_chains [0 ].name == 'output-early'
263+ assert filtered_chains [1 ].name == 'output-dnat'
264+
265+
266+ def test_firewall_chain_filter_dnat ():
267+ from simulator .firewall import Firewall
268+ from plugins .system .system_linux_netfilter import SystemLinuxNetfilter
269+ from plugins .translate .netfilter .ruleset import NetfilterRuleset , NetfilterChainOutput as Chain
270+
271+ ruleset = NetfilterRuleset (TESTDATA_RULESET ).get ()
272+ fw = Firewall (
273+ system = SystemLinuxNetfilter ,
274+ ruleset = ruleset ,
275+ )
276+
277+ fwd_dnat = SystemLinuxNetfilter .FIREWALL_NAT [FlowForward ]['dnat' ]
278+ out_dnat = SystemLinuxNetfilter .FIREWALL_NAT [FlowOutput ]['dnat' ]
279+
280+ chains = [
281+ Chain (name = 'ingress' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'ingress' ),
282+ Chain (name = 'prerouting-early' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = fwd_dnat ['hook' ], priority = fwd_dnat ['priority' ] - 1 ),
283+ Chain (name = 'prerouting-filter' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = fwd_dnat ['hook' ], priority = fwd_dnat ['priority' ]),
284+ Chain (name = 'prerouting-dnat' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = fwd_dnat ['hook' ], priority = fwd_dnat ['priority' ], type = Chain .TYPE_NAT ),
285+ Chain (name = 'prerouting' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = fwd_dnat ['hook' ]),
286+ Chain (name = 'output' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = out_dnat ['hook' ]),
287+ Chain (name = 'output-dnat' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = out_dnat ['hook' ], priority = out_dnat ['priority' ], type = Chain .TYPE_NAT ),
288+ Chain (name = 'input' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'input' ),
289+ Chain (name = 'forward' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'forward' ),
290+ Chain (name = 'postrouting' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'postrouting' ),
291+ ]
292+
293+ filtered_chains = [c for c in chains if fw ._run_tables ._chain_filter_dnat (chain = c , flow = FlowForward )]
294+ assert len (filtered_chains ) == 1
295+ assert filtered_chains [0 ].name == 'prerouting-dnat'
296+
297+ filtered_chains = [c for c in chains if fw ._run_tables ._chain_filter_dnat (chain = c , flow = FlowOutput )]
298+ assert len (filtered_chains ) == 1
299+ assert filtered_chains [0 ].name == 'output-dnat'
300+
301+
302+ def test_firewall_chain_filter_main ():
303+ from simulator .firewall import Firewall
304+ from plugins .system .system_linux_netfilter import SystemLinuxNetfilter
305+ from plugins .translate .netfilter .ruleset import NetfilterRuleset , NetfilterChainOutput as Chain
306+
307+ ruleset = NetfilterRuleset (TESTDATA_RULESET ).get ()
308+ fw = Firewall (
309+ system = SystemLinuxNetfilter ,
310+ ruleset = ruleset ,
311+ )
312+
313+ dnat = SystemLinuxNetfilter .FIREWALL_NAT [FlowForward ]['dnat' ]
314+ snat = SystemLinuxNetfilter .FIREWALL_NAT [FlowForward ]['snat' ]
315+
316+ chains = [
317+ Chain (name = 'ingress' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'ingress' ),
318+ Chain (name = 'prerouting-dnat' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = dnat ['hook' ], priority = dnat ['priority' ], type = Chain .TYPE_NAT ),
319+ Chain (name = 'prerouting-late' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = dnat ['hook' ], priority = dnat ['priority' ] + 1 ),
320+ Chain (name = 'prerouting' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = dnat ['hook' ]),
321+ Chain (name = 'input' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'input' ),
322+ Chain (name = 'output' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'output' ),
323+ Chain (name = 'forward' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'forward' ),
324+ Chain (name = 'postrouting' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = snat ['hook' ]),
325+ Chain (name = 'postrouting-filter' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = snat ['hook' ], priority = snat ['priority' ]),
326+ Chain (name = 'postrouting-snat' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = snat ['hook' ], priority = snat ['priority' ], type = Chain .TYPE_NAT ),
327+ Chain (name = 'postrouting-late' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = snat ['hook' ], priority = snat ['priority' ] + 1 ),
328+ ]
329+
330+ filtered_chains = [c for c in chains if fw ._run_tables ._chain_filter_main (chain = c , flow = FlowForward )]
331+ assert len (filtered_chains ) == 5
332+ assert filtered_chains [0 ].name == 'prerouting-late'
333+ assert filtered_chains [1 ].name == 'prerouting'
334+ assert filtered_chains [2 ].name == 'forward'
335+ assert filtered_chains [3 ].name == 'postrouting'
336+ assert filtered_chains [4 ].name == 'postrouting-filter'
337+
338+ filtered_chains = [c for c in chains if fw ._run_tables ._chain_filter_main (chain = c , flow = FlowInput )]
339+ assert len (filtered_chains ) == 3
340+ assert filtered_chains [0 ].name == 'prerouting-late'
341+ assert filtered_chains [1 ].name == 'prerouting'
342+ assert filtered_chains [2 ].name == 'input'
343+
344+ filtered_chains = [c for c in chains if fw ._run_tables ._chain_filter_main (chain = c , flow = FlowOutput )]
345+ assert len (filtered_chains ) == 3
346+ assert filtered_chains [0 ].name == 'output'
347+ assert filtered_chains [1 ].name == 'postrouting'
348+ assert filtered_chains [2 ].name == 'postrouting-filter'
349+
350+
351+ def test_firewall_chain_filter_snat ():
352+ from simulator .firewall import Firewall
353+ from plugins .system .system_linux_netfilter import SystemLinuxNetfilter
354+ from plugins .translate .netfilter .ruleset import NetfilterRuleset , NetfilterChainOutput as Chain
355+
356+ ruleset = NetfilterRuleset (TESTDATA_RULESET ).get ()
357+ fw = Firewall (
358+ system = SystemLinuxNetfilter ,
359+ ruleset = ruleset ,
360+ )
361+
362+ snat = SystemLinuxNetfilter .FIREWALL_NAT [FlowForward ]['snat' ]
363+
364+ chains = [
365+ Chain (name = 'ingress' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'ingress' ),
366+ Chain (name = 'prerouting-dnat' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'prerouting' , priority = - 100 , type = Chain .TYPE_NAT ),
367+ Chain (name = 'prerouting' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'prerouting' , priority = 0 ),
368+ Chain (name = 'input' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'input' ),
369+ Chain (name = 'forward' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = 'forward' ),
370+ Chain (name = 'postrouting' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = snat ['hook' ]),
371+ Chain (name = 'postrouting-filter' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = snat ['hook' ], priority = snat ['priority' ]),
372+ Chain (name = 'postrouting-snat' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = snat ['hook' ], priority = snat ['priority' ], type = Chain .TYPE_NAT ),
373+ Chain (name = 'postrouting-late' , rules = [], family = ProtoL3IP4 , policy = Chain .POLICY_ACCEPT , hook = snat ['hook' ], priority = snat ['priority' ] + 1 ),
374+ ]
375+
376+ filtered_chains = [c for c in chains if fw ._run_tables ._chain_filter_snat (chain = c , flow = FlowForward )]
377+ assert len (filtered_chains ) == 1
378+ assert filtered_chains [0 ].name == 'postrouting-snat'
379+
380+ filtered_chains = [c for c in chains if fw ._run_tables ._chain_filter_snat (chain = c , flow = FlowInput )]
381+ assert len (filtered_chains ) == 0
382+
383+ filtered_chains = [c for c in chains if fw ._run_tables ._chain_filter_snat (chain = c , flow = FlowOutput )]
384+ assert len (filtered_chains ) == 1
385+ assert filtered_chains [0 ].name == 'postrouting-snat'
0 commit comments