我正在使用 Arch Linux,并且已经使用 bridge-utils 设置了网桥。现在我想为它设置防火墙。我想丢弃一些通过该网桥的数据包,同时允许这台机器自由地与网桥后面的机器通信。我通常通过匹配来处理这种情况iifname lo
,但不幸的是它与我的数据包不匹配。
再次,希望更清楚
- 我有两台机器,
master
和slave
。 master
有两张以太网卡。一张连接到我的其余网络,另一张连接到slave
- 我希望
master
能够发送任何事物到slave
- 我想过滤来自网络其余部分的
slave
流量master
我想使用 nftables 来实现。你有什么想法吗?
答案1
该lo
接口不是以太网接口。它没有链路层地址,当然也不能成为网桥的一部分。因此,绝对不可能iifname lo
匹配。
桥接布局的组织方式与 IP 布局类似,但工作在第 2 层:交换(而不是路由)的以太网帧将进入前向链。发往主机或来自主机的以太网帧不会穿过任何链(它们不会在下面创建,因为它们在本用例中毫无用处)。
假设网络是这样的:
LAN <--------> eth0 master eth1 <--------> slave
(bridge0)
与eth0
并eth1
受 奴役bridge0
。
因此,只要主机上有一个唯一的网桥,这个“空” nft 规则集就足以隔离slave
,同时允许master
与 LAN 和 的不受限制的流量slave
,只需使用带有前向链的丢弃策略即可。
#!/usr/sbin/nft -f
flush ruleset
table bridge forward {
chain forward {
type filter hook forward priority 0; policy drop;
}
}
期望 ARP 双向工作当然是正常的(否则slave
在 IP 级别就无法做太多事情):
nft add rule bridge filter forward ether type arp accept
现在,如果允许 LAN ping slave
,但不允许相反操作:
nft add rule bridge filter forward oif eth1 ip protocol icmp icmp type echo-request accept
nft add rule bridge filter forward iif eth1 ip protocol icmp icmp type echo-reply accept
请注意,与 iptables 相比,在桥接级别使用 nftables 仍然有些受限(但更简洁),因为截至目前仍未集成 conntrack。因此据我所知,没有可用的状态防火墙。
因此,一些通常很容易的任务可能看起来很尴尬,例如:允许来自(可能是远程)IP 的 ssh 203.0.113.3
。它变成:允许双向流量,除了从从属到 LAN 的初始 syn 不允许:
nft add rule bridge filter forward oif eth1 ip saddr 203.0.113.3 ip protocol tcp tcp dport 22 accept
nft add rule bridge filter forward iif eth1 ip daddr 203.0.113.3 ip protocol tcp tcp sport 22 tcp flags != syn accept
如果上有多个桥梁master
,则可能需要调整规则和/或默认策略。
桥接层的状态防火墙
更新:内核5.3带来了该模块nf_conntrack_bridge
在桥接层启用 conntrack,从而允许状态防火墙。警告,与较旧的br_netfilter
通常在 Docker 环境中加载,可能会产生意外的结果。
有了这样的内核和足够新的nftables,用下面的规则集替换上面的规则将允许 ARP,并允许传入平或传入远程控制仅从 IP 地址 203.0.113.3 才能到达奴隶以有状态的方式:他们的回复被自动允许。奴隶仍然被禁止发起除 ARP 之外的任何通信。该setctzone
链完全是可选的:它允许通过为桥接跟踪条目分配不同的跟踪地址来单独跟踪桥接跟踪条目(例如:在 IP 路由层生成)连接跟踪区域id,以避免在非常特殊的设置中发生冲突的条目。
table bridge isolateslave
delete table bridge isolateslave
table bridge isolateslave {
chain setctzone {
type filter hook prerouting priority -300; policy accept;
ether type ip ct zone set 10
}
chain forward {
type filter hook forward priority 0; policy drop;
ether type arp accept
ct state established,related accept
ct state invalid drop
oif "eth1" ip saddr 203.0.113.3 tcp dport 22 accept
oif "eth1" icmp type echo-request accept
}
}