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

It is impossible to add a rule accepting bridge traffic with FirewallBackend=nftables #1236

Open
GigabyteProductions opened this issue Nov 7, 2023 · 2 comments
Labels
blocked Blocked in some way. e.g. waiting on the user that opened the issue or pull request

Comments

@GigabyteProductions
Copy link

Similarly to #1235, having br_netfilter loaded automatically puts all would-be bridge-forwarded frames through netfilter to be filtered in the same way routed packets would be.

However, just as firewalld documentation describes (1), rule evaluation does not stop at an accept, but must go through all the tables hooking the same filter without hitting a drop or reject.

The problem now is that it is currently impossible to add a iifname "br0" oifname "br0" accept sort of rule in forward without encountering reject with icmpx type admin-prohibited or ct state { invalid } drop.

There's no rich language way to specify input/output interface. The direct interface goes through iptables so the iifname "br0" oifname "br0" accept translation go into the ip filter or ip6 filter tables instead of the inet firewalld table.

At this moment, it is necessary to set FirewallBackend=iptables in /etc/firewalld/firewalld.conf AND use direct rules like below to allow bridge forwarding when br_netfilter is loaded, or else all new connections are dropped:

  <rule ipv="ipv4" table="filter" chain="FORWARD" priority="10">-i br0 -o br0 -j ACCEPT</rule>
  <rule ipv="ipv6" table="filter" chain="FORWARD" priority="10">-i br0 -o br0 -j ACCEPT</rule>

Or preferrably:

  <rule ipv="ipv4" table="filter" chain="FORWARD" priority="10">-m physdev --physdev-is-bridged -i br0 -o br0 -j ACCEPT</rule>
  <rule ipv="ipv6" table="filter" chain="FORWARD" priority="10">-m physdev --physdev-is-bridged -i br0 -o br0 -j ACCEPT</rule>

Specifically, this is what I'm looking at:

table ip filter {
...
	chain FORWARD {
		type filter hook forward priority filter; policy accept;
		iifname "br0" oifname "br0" # PHYSDEV match --physdev-is-bridged counter packets 117 bytes 9448 accept
	}
...
}
table ip6 filter {
...
	chain FORWARD {
		type filter hook forward priority filter; policy accept;
		iifname "br0" oifname "br0" # PHYSDEV match --physdev-is-bridged counter packets 18 bytes 1152 accept
	}
...
}
...
table inet firewalld {
...
	chain filter_FORWARD {
		type filter hook forward priority filter + 10; policy accept;
		ct state { established, related } accept
...
		jump filter_FORWARD_POLICIES_pre
		jump filter_FORWARD_IN_ZONES_SOURCE
		jump filter_FORWARD_IN_ZONES
		jump filter_FORWARD_OUT_ZONES_SOURCE
		jump filter_FORWARD_OUT_ZONES
		jump filter_FORWARD_POLICIES_post
		ct state { invalid } drop
		reject with icmpx type admin-prohibited
	}
...
}

vs:

...
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT
...
-A FORWARD -j FORWARD_direct
-A FORWARD -j FORWARD_POLICIES_pre
-A FORWARD -j FORWARD_IN_ZONES_SOURCE
-A FORWARD -j FORWARD_IN_ZONES
-A FORWARD -j FORWARD_OUT_ZONES_SOURCE
-A FORWARD -j FORWARD_OUT_ZONES
-A FORWARD -j FORWARD_POLICIES_post
-A FORWARD -m conntrack --ctstate INVALID -j DROP
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
...
-A FORWARD_direct -i br0 -o br0 -m physdev --physdev-is-bridged -j ACCEPT
...
@erig0
Copy link
Collaborator

erig0 commented Nov 7, 2023

This is blocked by support in nftables. But I don't expect that to ever be supported because nftables has a true bridge family to support transparent firewalls.

@erig0 erig0 added the blocked Blocked in some way. e.g. waiting on the user that opened the issue or pull request label Nov 7, 2023
@GigabyteProductions
Copy link
Author

GigabyteProductions commented Nov 7, 2023

Well... it could work with current state of nftables if firewalld allowed a direct/rich rule utilizing iifname/oifname to be added to the inet firewalld filter_FORWARD chain prior to the final drop/rejects.

But... I see what you mean. Transparent bridge firewalling without interference from the inet/ip/ip6 type filter hook forward hooks is possible by ensuring that both the system-wide /proc/sys/net/bridge/bridge-nf-call-*tables and interface-specific /sys/devices/virtual/net/${interface_name}/bridge/nf_call_*tables are set to 0, but then I'd have to utilize something besides firewalld, and sacrifice its convenient zoning logic, for this purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked Blocked in some way. e.g. waiting on the user that opened the issue or pull request
Projects
None yet
Development

No branches or pull requests

2 participants