我有一组如下形式的 nftable 规则:
chain INPUT {
type filter hook input priority filter; policy drop;
ip saddr 11.37.79.97/29 counter packets 0 bytes 0 log prefix "'**A Log Prefix**'"
ct state established,related counter packets 70 bytes 12769 accept
iifname "lo" counter packets 0 bytes 0 accept
ct state new tcp dport 22 counter packets 0 bytes 0 accept
ip saddr 11.137.79.0/24 ct state new counter packets 0 bytes 0 accept comment "A comment"
ip saddr 11.37.79.0/24 ip daddr 11.37.140.0/22 ct state new counter packets 0 bytes 0 accept comment "another comment"
ip saddr 11.37.36.0/22 ip daddr 11.37.140.0/22 ct state new counter packets 0 bytes 0 accept comment "another comment"
ct state new tcp dport 1234 counter packets 0 bytes 0 accept
ct state new tcp dport 2234 counter packets 0 bytes 0 accept
ct state new tcp dport 2244 counter packets 0 bytes 0 accept
tcp dport 61151 ct state new counter packets 0 bytes 0 accept comment "Some Application"
counter packets 0 bytes 0 drop
}
}
...
#existing rules from firewall rich rules populating nftables are of the form:
table inet firewalld {
set OUR-NET {
type ipv4_addr
flags interval
elements = { 11.0.0.0/8 }
}
set OUR-VPN {
type ipv4_addr
flags interval
elements = { 72.60.16.0/20, 72.60.144.0/20,
72.60.192.0/24 }
}
set Management-Support {
type ipv4_addr
flags interval
elements = { 11.37.223.0/24, 11.37.128.0/24,
11.37.129.0/24, 11.37.130.0/24}
}
chain mangle_PREROUTING {
type filter hook prerouting priority mangle + 10; policy accept;
jump mangle_PREROUTING_POLICIES_pre
jump mangle_PREROUTING_ZONES
jump mangle_PREROUTING_POLICIES_post
}
chain mangle_PREROUTING_POLICIES_pre {
jump mangle_PRE_policy_allow-host-ipv6
}
chain mangle_PREROUTING_ZONES {
iifname "ens197" goto mangle_PRE_public
goto mangle_PRE_public
}
chain mangle_PREROUTING_POLICIES_post {
}
chain filter_PREROUTING {
type filter hook prerouting priority filter + 10; policy accept;
icmpv6 type { nd-router-advert, nd-neighbor-solicit } accept
meta nfproto ipv6 fib saddr . mark . iif oif missing log prefix "rpfilter_DROP: " drop
}
chain filter_INPUT {
type filter hook input priority filter + 10; policy accept;
ct state { established, related } accept
ct status dnat accept
iifname "lo" accept
jump filter_INPUT_POLICIES_pre
jump filter_INPUT_ZONES
ct state { invalid } log prefix "STATE_INVALID_DROP: "
ct state { invalid } drop
log prefix "FINAL_REJECT: "
reject with icmpx type admin-prohibited
}
chain filter_FORWARD {
type filter hook forward priority filter + 10; policy accept;
ct state { established, related } accept
ct status dnat accept
iifname "lo" accept
ip6 daddr { ::/96} log prefix "IPv4_REJECT: " reject with icmpv6 type addr-unreachable
jump filter_FORWARD_IN_ZONES
jump filter_FORWARD_OUT_ZONES
ct state { invalid } log prefix "STATE_INVALID_DROP: "
ct state { invalid } drop
log prefix "FINAL_REJECT: "
reject with icmpx type admin-prohibited
}
chain filter_OUTPUT {
type filter hook output priority filter + 10; policy accept;
ct state { established, related } accept
oifname "lo" accept
ip6 daddr { ::/96 } log prefix "IPv4_REJECT: " reject with icmpv6 type addr-unreachable
}
chain filter_INPUT_POLICIES_pre {
jump filter_IN_policy_allow-host-ipv6
}
chain filter_INPUT_ZONES {
iifname "ens197" goto filter_IN_public
goto filter_IN_public
}
chain filter_FORWARD_IN_ZONES {
iifname "ens197" goto filter_FWDI_public
goto filter_FWDI_public
}
chain filter_FORWARD_OUT_ZONES {
oifname "ens197" goto filter_FWDO_public
goto filter_FWDO_public
}
chain filter_IN_public {
jump filter_IN_public_log
jump filter_IN_public_allow
meta l4proto { icmp, ipv6-icmp } accept
}
chain filter_IN_public_log {
ip saddr @Management-Support tcp dport 22 ct state { new, untracked } limit rate 10/minute log prefix "SSH" level info
ip saddr @OUR-VPN tcp dport 22 ct state { new, untracked } limit rate 10/minute log prefix "SSH" level info
ip saddr @OUR-NET tcp dport 22 ct state { new, untracked } limit rate 10/minute log prefix "SSH" level info
}
chain filter_IN_public_allow {
ip saddr @Management-Support tcp dport 22 ct state { new, untracked } accept
ip saddr @OUR-VPN tcp dport 22 ct state { new, untracked } accept
ip saddr @OUR-NET tcp dport 22 ct state { new, untracked } accept
}
chain filter_FWDI_public {
jump filter_FWDI_public_allow
meta l4proto { icmp, ipv6-icmp } accept
}
chain filter_FWDI_public_allow {
ip saddr @OUR-NET icmp type destination-unreachable icmp code 4 accept
}
chain filter_IN_policy_allow-host-ipv6 {
jump filter_IN_policy_allow-host-ipv6_allow
}
chain filter_IN_policy_allow-host-ipv6_allow {
icmpv6 type nd-neighbor-advert accept
icmpv6 type nd-neighbor-solicit accept
icmpv6 type nd-router-advert accept
icmpv6 type nd-redirect accept
}
}
table ip firewalld {
set OUR-NET {
type ipv4_addr
flags interval
elements = { 11.0.0.0/8 }
}
set OUR-VPN {
type ipv4_addr
flags interval
elements = { 72.60.16.0/20, 72.60.144.0/20,
72.60.192.0/24 }
}
set Management-Support {
type ipv4_addr
flags interval
elements = { 11.37.223.0/24, 11.37.128.0/24,
11.37.129.0/24, 11.37.130.0/24 }
}
chain nat_PREROUTING {
type nat hook prerouting priority dstnat + 10; policy accept;
jump nat_PREROUTING_ZONES
}
chain nat_PREROUTING_ZONES {
iifname "ens197" goto nat_PRE_public
goto nat_PRE_public
}
chain nat_POSTROUTING {
type nat hook postrouting priority srcnat + 10; policy accept;
jump nat_POSTROUTING_ZONES
}
chain nat_POSTROUTING_ZONES {
oifname "ens197" goto nat_POST_public
goto nat_POST_public
}
}
table ip6 firewalld {
set OUR-NET {
type ipv4_addr
flags interval
elements = { 11.0.0.0/8 }
}
set OUR-VPN {
type ipv4_addr
flags interval
elements = { 72.60.16.0/20, 72.60.144.0/20,
72.60.192.0/24 }
}
set Management-Support {
type ipv4_addr
flags interval
elements = { 11.37.223.0/24, 11.37.128.0/24,
11.37.129.0/24, 11.37.130.0/24,
11.37.131.0/24, 11.37.132.0/24,
11.37.133.0/24, 11.137.128.0/24,
11.137.129.0/24, 11.137.130.0/24,
11.137.131.0/24, 11.137.132.0/24,
11.137.133.0/24 }
}
chain nat_PREROUTING {
type nat hook prerouting priority dstnat + 10; policy accept;
jump nat_PREROUTING_ZONES
}
chain nat_PREROUTING_ZONES {
iifname "ens197" goto nat_PRE_public
goto nat_PRE_public
}
chain nat_POSTROUTING {
type nat hook postrouting priority srcnat + 10; policy accept;
jump nat_POSTROUTING_ZONES
}
chain nat_POSTROUTING_ZONES {
oifname "ens197" goto nat_POST_public
goto nat_POST_public
}
}
在丰富的规则格式中,现有规则的形式为:
'rule family=ipv4 source ipset=Management-Support port port=22 protocol=tcp log prefix=SSH level=info limit value=10/m accept'
'rule family=ipv4 source ipset=OUR-NET port port=22 protocol=tcp log prefix=SSH level=info limit value=10/m accept'
'rule family=ipv4 source ipset=OUR-VPN port port=22 protocol=tcp log prefix=SSH level=info limit value=10/m accept'
据我了解:
- 如果源来自丰富规则中列出的 IP 集之一,则现有规则允许访问端口 22。
- 通过 nftables 的新规则会丢弃任何不遵循 INPUT 链中列出的任何模式的 INPUT 流量。
INPUT 链应该
- 记录源地址为 11.37.79.97/29 的任何内容
- 接受已建立或相关连接的所有流量
- 接受本地主机流量
- 接受目标端口 22 (SSH) 的所有流量
- 接受与 11.137.79.x 的源 IP 模式匹配的所有流量
- 接受与 11.37.79.x 的源 IP 模式匹配的所有流量 - 其中包括上面记录的流量。
- ETC。
那么问题来了,为什么这个实现会阻塞SSH呢?
我的分析表明,它正在命中此 INPUT 链,并且正在应用 DROP 的默认策略(无论防火墙链是首先执行还是最后执行 - 它们都会命中此 INPUT 并因此丢弃)。仅当链中没有其他说明时,才应执行 DROP 的默认策略。这意味着它不会评估链中的任何其他内容。这让我相信 SSH dport 22 接受行之前的某个地方存在语法错误。由于它正在删除现有的 SSH 连接,我怀疑它必须是记录 11.37.79.97/29 流量的第一行。
谁能澄清发生了什么事吗?
- - 更新 - -
我已经切换了顺序并将accept 添加到日志前缀行的末尾。现在它遵循 ct state new tcp dport 22 ....line。然后,我在刷新规则集后加载它nft -f <filename>
,然后执行firewall-cmd --reload。这也导致我断开连接并阻止 SSH 访问。