nft
让我头疼不已,无论我如何调整策略,仍然无法使其发挥作用。
我想到的概念是:
- 一个“基础”链,其中包含通用规则(例如允许
ssh
等) - 守护进程特定规则所在的一个或多个应用程序(例如 http 服务器链)
我尝试过许多不同的规则排列,但我永远无法同时使“基本”+守护进程流量流动,我总是最终阻止其中一个!;-(
这是我当前的(简化)配置(目前构成它允许ssh
但未能允许http
)
/etc/nftables.conf:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
counter input_ssh {}
set my_admin_ipv4 {
type ipv4_addr
flags interval
counter
elements = {
10.0.0.0/8,
172.16.0.0/12,
192.168.0.0/16
}
}
chain input {
type filter hook input priority filter;
iifname lo accept comment "Allow loopback traffic";
ct state established,related accept comment "Allow established/related connections";
ct state invalid drop comment "Deny invalid connections";
# SSH
tcp dport ssh ip saddr @my_admin_ipv4 counter name input_ssh accept comment "Allow IPv4 SSH from Admin";
policy drop;
}
chain forward {
type filter hook forward priority 0;
policy drop;
}
chain output {
type filter hook output priority 0;
}
include "/etc/nft/*.conf"
}
/etc/nft/http.conf:
counter input_http {}
chain http {
type filter hook input priority filter - 1;
# HTTP #
tcp dport {80,443} counter name input_nginx accept comment "Allow HTTP";
policy accept;
}
答案1
您可以选择将数据包标记为在同一钩子的后续链中被接受为安全行为。
每个接受规则都应该标记数据包
执行显式接受的规则应在接受数据包之前对其进行标记。任何出现的情况:
... accept
应替换为:
... meta mark set 0xf00 accept
如果标记没有其他作用,只要其值不为 0,则其值并不重要。
每个链都应该接受一个标记的数据包,因为这是安全的行为
通过在链的早期使用此规则:
meta mark != 0 accept
这就是总体思路。如果更合理的话,仍然可以进行调整和例外。
以下是按照这种方法重新审视的规则集。标记在规则之后被接受,ct ... invalid drop
这是一条不应被绕过的重要规则(实际上可以在较早的链中一劳永逸地完成,因为它是一条丢弃规则)。如果在下面,输入是过滤器/输入钩子中的最后一个链,则实际上不需要标记已接受的数据包,但这样做也无妨。
/etc/nftables.conf:
:
flush ruleset
table inet filter {
counter input_ssh {}
set my_admin_ipv4 {
type ipv4_addr
flags interval
counter
elements = {
10.0.0.0/8,
172.16.0.0/12,
192.168.0.0/16
}
}
chain input {
type filter hook input priority filter; policy drop;
iifname lo meta mark set 0x1 accept comment "Allow loopback traffic";
ct state established,related meta mark set 0x1 accept comment "Allow established/related connections";
ct state invalid drop comment "Deny invalid connections";
meta mark != 0 accept
# SSH
tcp dport ssh ip saddr @my_admin_ipv4 counter name input_ssh meta mark set 0x1 accept comment "Allow IPv4 SSH from Admin";
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
include "/etc/nft/*.conf"
}
/etc/nft/http.conf
(替换counter_nginx
为counter_http
)。meta mark != 0 accept
这里可能不需要该规则,因为之前可能没有其他链,但有它也不会有什么坏处。
counter input_http {}
chain http {
type filter hook input priority filter - 1; policy accept;
meta mark != 0 accept
# HTTP #
tcp dport {80,443} counter name input_http meta mark set 0x2 accept comment "Allow HTTP";
}
此方法使用标记,因此很难与其他已将标记用于其他用途的防火墙规则集成。通过按位运算保留标记的几个位,仍然可以实现。