Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T4072: firewall extend bridge firewall #3901

Merged
merged 5 commits into from
Aug 4, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
T4072: firewall: extend firewall bridge capabilities, in order to inc…
…lude new chains, priorities, and firewall groups
  • Loading branch information
nicolas-fort committed Aug 1, 2024
commit 20551379e8e2b4b6e342b39ea67738876e559bbf
85 changes: 85 additions & 0 deletions data/templates/firewall/nftables-bridge.j2
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
{% import 'firewall/nftables-defines.j2' as group_tmpl %}
{% macro bridge(bridge) %}
{% set ns = namespace(sets=[]) %}
{% if bridge.forward is vyos_defined %}
{% for prior, conf in bridge.forward.items() %}
chain VYOS_FORWARD_{{ prior }} {
type filter hook forward priority {{ prior }}; policy accept;
{% if global_options.state_policy is vyos_defined %}
jump VYOS_STATE_POLICY
{% endif %}
{% if conf.rule is vyos_defined %}
{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
{{ rule_conf | nft_rule('FWD', prior, rule_id, 'bri') }}
@@ -17,6 +21,46 @@
{% endfor %}
{% endif %}

{% if bridge.input is vyos_defined %}
{% for prior, conf in bridge.input.items() %}
chain VYOS_INPUT_{{ prior }} {
type filter hook input priority {{ prior }}; policy accept;
{% if global_options.state_policy is vyos_defined %}
jump VYOS_STATE_POLICY
{% endif %}
{% if conf.rule is vyos_defined %}
{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
{{ rule_conf | nft_rule('INP', prior, rule_id, 'bri') }}
{% if rule_conf.recent is vyos_defined %}
{% set ns.sets = ns.sets + ['INP_' + prior + '_' + rule_id] %}
{% endif %}
{% endfor %}
{% endif %}
{{ conf | nft_default_rule('INP-filter', 'bri') }}
}
{% endfor %}
{% endif %}

{% if bridge.output is vyos_defined %}
{% for prior, conf in bridge.output.items() %}
chain VYOS_OUTUT_{{ prior }} {
type filter hook output priority {{ prior }}; policy accept;
{% if global_options.state_policy is vyos_defined %}
jump VYOS_STATE_POLICY
{% endif %}
{% if conf.rule is vyos_defined %}
{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
{{ rule_conf | nft_rule('OUT', prior, rule_id, 'bri') }}
{% if rule_conf.recent is vyos_defined %}
{% set ns.sets = ns.sets + ['OUT_' + prior + '_' + rule_id] %}
{% endif %}
{% endfor %}
{% endif %}
{{ conf | nft_default_rule('OUT-filter', 'bri') }}
}
{% endfor %}
{% endif %}

{% if bridge.name is vyos_defined %}
{% for name_text, conf in bridge.name.items() %}
chain NAME_{{ name_text }} {
@@ -32,4 +76,45 @@
}
{% endfor %}
{% endif %}

{% for set_name in ns.sets %}
set RECENT_{{ set_name }} {
type ipv4_addr
size 65535
flags dynamic
}
{% endfor %}
{% for set_name in ip_fqdn %}
set FQDN_{{ set_name }} {
type ipv4_addr
flags interval
}
{% endfor %}
{% if geoip_updated.name is vyos_defined %}
{% for setname in geoip_updated.name %}
set {{ setname }} {
type ipv4_addr
flags interval
}
{% endfor %}
{% endif %}

{{ group_tmpl.groups(group, False, True) }}
{{ group_tmpl.groups(group, True, True) }}

{% if global_options.state_policy is vyos_defined %}
chain VYOS_STATE_POLICY {
{% if global_options.state_policy.established is vyos_defined %}
{{ global_options.state_policy.established | nft_state_policy('established') }}
{% endif %}
{% if global_options.state_policy.invalid is vyos_defined %}
{{ global_options.state_policy.invalid | nft_state_policy('invalid') }}
{% endif %}
{% if global_options.state_policy.related is vyos_defined %}
{{ global_options.state_policy.related | nft_state_policy('related') }}
{% endif %}
return
}
{% endif %}

{% endmacro %}
10 changes: 5 additions & 5 deletions data/templates/firewall/nftables-defines.j2
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% macro groups(group, is_ipv6, is_l3) %}
{% if group is vyos_defined %}
{% set ip_type = 'ipv6_addr' if is_ipv6 else 'ipv4_addr' %}
{% if group.address_group is vyos_defined and not is_ipv6 and is_l3 %}
{% if group.address_group is vyos_defined and not is_ipv6 %}
{% for group_name, group_conf in group.address_group.items() %}
{% set includes = group_conf.include if group_conf.include is vyos_defined else [] %}
set A_{{ group_name }} {
@@ -14,7 +14,7 @@
}
{% endfor %}
{% endif %}
{% if group.ipv6_address_group is vyos_defined and is_ipv6 and is_l3 %}
{% if group.ipv6_address_group is vyos_defined and is_ipv6 %}
{% for group_name, group_conf in group.ipv6_address_group.items() %}
{% set includes = group_conf.include if group_conf.include is vyos_defined else [] %}
set A6_{{ group_name }} {
@@ -46,7 +46,7 @@
}
{% endfor %}
{% endif %}
{% if group.network_group is vyos_defined and not is_ipv6 and is_l3 %}
{% if group.network_group is vyos_defined and not is_ipv6 %}
{% for group_name, group_conf in group.network_group.items() %}
{% set includes = group_conf.include if group_conf.include is vyos_defined else [] %}
set N_{{ group_name }} {
@@ -59,7 +59,7 @@
}
{% endfor %}
{% endif %}
{% if group.ipv6_network_group is vyos_defined and is_ipv6 and is_l3 %}
{% if group.ipv6_network_group is vyos_defined and is_ipv6 %}
{% for group_name, group_conf in group.ipv6_network_group.items() %}
{% set includes = group_conf.include if group_conf.include is vyos_defined else [] %}
set N6_{{ group_name }} {
@@ -72,7 +72,7 @@
}
{% endfor %}
{% endif %}
{% if group.port_group is vyos_defined and is_l3 %}
{% if group.port_group is vyos_defined %}
{% for group_name, group_conf in group.port_group.items() %}
{% set includes = group_conf.include if group_conf.include is vyos_defined else [] %}
set P_{{ group_name }} {
101 changes: 99 additions & 2 deletions data/templates/firewall/nftables.j2
Original file line number Diff line number Diff line change
@@ -339,7 +339,104 @@ table ip6 vyos_filter {
delete table bridge vyos_filter
{% endif %}
table bridge vyos_filter {
{{ bridge_tmpl.bridge(bridge) }}
{% if bridge is vyos_defined %}
{% if bridge.forward is vyos_defined %}
{% for prior, conf in bridge.forward.items() %}
chain VYOS_FORWARD_{{ prior }} {
type filter hook forward priority {{ prior }}; policy accept;
{% if global_options.state_policy is vyos_defined %}
jump VYOS_STATE_POLICY
{% endif %}
{% if conf.rule is vyos_defined %}
{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
{{ rule_conf | nft_rule('FWD', prior, rule_id, 'bri') }}
{% endfor %}
{% endif %}
{{ conf | nft_default_rule('FWD-' + prior, 'bri') }}
}
{% endfor %}
{% endif %}

{% if bridge.input is vyos_defined %}
{% for prior, conf in bridge.input.items() %}
chain VYOS_INPUT_{{ prior }} {
type filter hook input priority {{ prior }}; policy accept;
{% if global_options.state_policy is vyos_defined %}
jump VYOS_STATE_POLICY
{% endif %}
{% if conf.rule is vyos_defined %}
{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
{{ rule_conf | nft_rule('INP', prior, rule_id, 'bri') }}
{% endfor %}
{% endif %}
{{ conf | nft_default_rule('INP-' + prior, 'bri') }}
}
{% endfor %}
{% endif %}

{% if bridge.output is vyos_defined %}
{% for prior, conf in bridge.output.items() %}
chain VYOS_OUTUT_{{ prior }} {
type filter hook output priority {{ prior }}; policy accept;
{% if global_options.state_policy is vyos_defined %}
jump VYOS_STATE_POLICY
{% endif %}
{% if conf.rule is vyos_defined %}
{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
{{ rule_conf | nft_rule('OUT', prior, rule_id, 'bri') }}
{% endfor %}
{% endif %}
{{ conf | nft_default_rule('OUT-' + prior, 'bri') }}
}
{% endfor %}
{% endif %}

{% if bridge.prerouting is vyos_defined %}
{% for prior, conf in bridge.prerouting.items() %}
chain VYOS_PREROUTING_{{ prior }} {
type filter hook prerouting priority {{ prior }}; policy accept;
{% if conf.rule is vyos_defined %}
{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
{{ rule_conf | nft_rule('PRE', prior, rule_id, 'bri') }}
{% endfor %}
{% endif %}
{{ conf | nft_default_rule('PRE-' + prior, 'bri') }}
}
{% endfor %}
{% endif %}

{% if bridge.name is vyos_defined %}
{% for name_text, conf in bridge.name.items() %}
chain NAME_{{ name_text }} {
{% if conf.rule is vyos_defined %}
{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %}
{{ rule_conf | nft_rule('NAM', name_text, rule_id, 'bri') }}
{% if rule_conf.recent is vyos_defined %}
{% set ns.sets = ns.sets + ['NAM_' + name_text + '_' + rule_id] %}
{% endif %}
{% endfor %}
{% endif %}
{{ conf | nft_default_rule(name_text, 'bri') }}
}
{% endfor %}
{% endif %}

{% endif %}
{{ group_tmpl.groups(group, False, False) }}
{{ group_tmpl.groups(group, True, False) }}

}
{% if global_options.state_policy is vyos_defined %}
chain VYOS_STATE_POLICY {
{% if global_options.state_policy.established is vyos_defined %}
{{ global_options.state_policy.established | nft_state_policy('established') }}
{% endif %}
{% if global_options.state_policy.invalid is vyos_defined %}
{{ global_options.state_policy.invalid | nft_state_policy('invalid') }}
{% endif %}
{% if global_options.state_policy.related is vyos_defined %}
{{ global_options.state_policy.related | nft_state_policy('related') }}
{% endif %}
return
}
{% endif %}
}
3 changes: 3 additions & 0 deletions interface-definitions/firewall.xml.in
Original file line number Diff line number Diff line change
@@ -367,6 +367,9 @@
</properties>
<children>
#include <include/firewall/bridge-hook-forward.xml.i>
#include <include/firewall/bridge-hook-input.xml.i>
#include <include/firewall/bridge-hook-output.xml.i>
#include <include/firewall/bridge-hook-prerouting.xml.i>
#include <include/firewall/bridge-custom-name.xml.i>
</children>
</node>
63 changes: 63 additions & 0 deletions interface-definitions/include/firewall/address-inet.xml.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!-- include start from firewall/address-inet.xml.i -->
<leafNode name="address">
<properties>
<help>IP address, subnet, or range</help>
<valueHelp>
<format>ipv4</format>
<description>IPv4 address to match</description>
</valueHelp>
<valueHelp>
<format>ipv4net</format>
<description>IPv4 prefix to match</description>
</valueHelp>
<valueHelp>
<format>ipv4range</format>
<description>IPv4 address range to match</description>
</valueHelp>
<valueHelp>
<format>!ipv4</format>
<description>Match everything except the specified address</description>
</valueHelp>
<valueHelp>
<format>!ipv4net</format>
<description>Match everything except the specified prefix</description>
</valueHelp>
<valueHelp>
<format>!ipv4range</format>
<description>Match everything except the specified range</description>
</valueHelp>
<valueHelp>
<format>ipv6net</format>
<description>Subnet to match</description>
</valueHelp>
<valueHelp>
<format>ipv6range</format>
<description>IP range to match</description>
</valueHelp>
<valueHelp>
<format>!ipv6</format>
<description>Match everything except the specified address</description>
</valueHelp>
<valueHelp>
<format>!ipv6net</format>
<description>Match everything except the specified prefix</description>
</valueHelp>
<valueHelp>
<format>!ipv6range</format>
<description>Match everything except the specified range</description>
</valueHelp>
<constraint>
<validator name="ipv4-address"/>
<validator name="ipv4-prefix"/>
<validator name="ipv4-range"/>
<validator name="ipv4-address-exclude"/>
<validator name="ipv4-prefix-exclude"/>
<validator name="ipv4-range-exclude"/>
<validator name="ipv6"/>
<validator name="ipv6-exclude"/>
<validator name="ipv6-range"/>
<validator name="ipv6-range-exclude"/>
</constraint>
</properties>
</leafNode>
<!-- include end -->
19 changes: 19 additions & 0 deletions interface-definitions/include/firewall/address-mask-inet.xml.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!-- include start from firewall/address-mask-inet.xml.i -->
<leafNode name="address-mask">
<properties>
<help>IP mask</help>
<valueHelp>
<format>ipv4</format>
<description>IPv4 mask to apply</description>
</valueHelp>
<valueHelp>
<format>ipv6</format>
<description>IP mask to apply</description>
</valueHelp>
<constraint>
<validator name="ipv4-address"/>
<validator name="ipv6"/>
</constraint>
</properties>
</leafNode>
<!-- include end -->
Original file line number Diff line number Diff line change
@@ -32,6 +32,11 @@
</properties>
<children>
#include <include/firewall/common-rule-bridge.xml.i>
#include <include/firewall/connection-mark.xml.i>
#include <include/firewall/connection-status.xml.i>
#include <include/firewall/state.xml.i>
#include <include/firewall/inbound-interface.xml.i>
#include <include/firewall/outbound-interface.xml.i>
</children>
</tagNode>
</children>
Original file line number Diff line number Diff line change
@@ -26,6 +26,11 @@
</properties>
<children>
#include <include/firewall/common-rule-bridge.xml.i>
#include <include/firewall/connection-mark.xml.i>
#include <include/firewall/connection-status.xml.i>
#include <include/firewall/state.xml.i>
#include <include/firewall/inbound-interface.xml.i>
#include <include/firewall/outbound-interface.xml.i>
</children>
</tagNode>
</children>
Loading