感谢 @OrkoGrayskull!
关于这个问题,现在 /etc/docker/daemon.json 可以设置 firewall-backend 为 nftables,而且我猜你现在运行的是 Debian Trixie 或 Bookworm —— 我正在试验这个…… 是否有任何新进展?
我发现在 /etc/sysctl.conf 中需要设置 net.ipv4.ip_forward=1。
Docker with nftables 文档 中有提到:
不要直接修改 Docker 的表,因为修改可能会丢失,Docker 希望完全拥有其表。
所以我希望不要触碰 Docker 的规则……
这是我目前拥有的,一些是我通过 Ansible 添加的规则(这台服务器有 Postfix 转发 SMTP 到 Discourse,所以需要端口 25):
table inet ansible_firewall {
chain inbound_ipv4 {
icmp type echo-request limit rate 5/second accept comment "Accept IPv4 rate limited ICMP pings"
}
chain inbound_ipv6 {
icmpv6 type { nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept comment "Accept IPv6 neighbour discovery"
icmpv6 type echo-request limit rate 5/second accept comment "Accept IPv6 rate limited ICMP pings"
}
chain inbound {
type filter hook input priority filter; policy drop;
ct state vmap { invalid : drop, established : accept, related : accept } comment "Allow traffic from established and related packets, drop invalid"
iifname "lo" accept comment "Allow loopback traffic"
meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 } comment "Jump to chain according to layer 3 protocol using a verdict map"
tcp dport 22 accept comment "Allow SSH on port TCP/22"
tcp dport { 80, 443 } accept comment "Allow HTTP on port TCP/80 and HTTPS on port TCP/443"
}
chain forward {
type filter hook forward priority filter; policy drop;
}
chain output {
type filter hook output priority filter; policy accept;
oifname "lo" accept comment "Allow outgoing from loopback interface"
}
}
以及来自 Docker / Discourse 的规则(注意这台服务器没有 IPv6 地址):
table ip docker-bridges {
map filter-forward-in-jumps {
type ifname : verdict
elements = { "docker0" : jump filter-forward-in__docker0 }
}
map filter-forward-out-jumps {
type ifname : verdict
elements = { "docker0" : jump filter-forward-out__docker0 }
}
map nat-postrouting-in-jumps {
type ifname : verdict
elements = { "docker0" : jump nat-postrouting-in__docker0 }
}
map nat-postrouting-out-jumps {
type ifname : verdict
elements = { "docker0" : jump nat-postrouting-out__docker0 }
}
chain filter-FORWARD {
type filter hook forward priority filter; policy accept;
oifname vmap @filter-forward-in-jumps
iifname vmap @filter-forward-out-jumps
}
chain nat-OUTPUT {
type nat hook output priority -100; policy accept;
ip daddr != 127.0.0.0/8 fib daddr type local counter jump nat-prerouting-and-output
}
chain nat-POSTROUTING {
type nat hook postrouting priority srcnat; policy accept;
iifname vmap @nat-postrouting-out-jumps
oifname vmap @nat-postrouting-in-jumps
}
chain nat-PREROUTING {
type nat hook prerouting priority dstnat; policy accept;
fib daddr type local counter jump nat-prerouting-and-output
}
chain nat-prerouting-and-output {
iifname != "docker0" tcp dport 80 counter dnat to 172.17.0.2:80 comment "DNAT"
iifname != "docker0" tcp dport 443 counter dnat to 172.17.0.2:443 comment "DNAT"
}
chain raw-PREROUTING {
type filter hook prerouting priority raw; policy accept;
ip daddr 172.17.0.2 iifname != "docker0" counter drop comment "DROP DIRECT ACCESS"
}
chain filter-forward-in__docker0 {
ct state established,related counter accept
iifname "docker0" counter accept comment "ICC"
ip daddr 172.17.0.2 tcp dport 80 counter accept
ip daddr 172.17.0.2 tcp dport 443 counter accept
counter drop comment "UNPUBLISHED PORT DROP"
}
chain filter-forward-out__docker0 {
ct state established,related counter accept
counter accept comment "OUTGOING"
}
chain nat-postrouting-in__docker0 {
}
chain nat-postrouting-out__docker0 {
oifname != "docker0" ip saddr 172.17.0.0/16 counter masquerade comment "MASQUERADE"
}
}
table ip6 docker-bridges {
map filter-forward-in-jumps {
type ifname : verdict
}
map filter-forward-out-jumps {
type ifname : verdict
}
map nat-postrouting-in-jumps {
type ifname : verdict
}
map nat-postrouting-out-jumps {
type ifname : verdict
}
chain filter-FORWARD {
type filter hook forward priority filter; policy accept;
oifname vmap @filter-forward-in-jumps
iifname vmap @filter-forward-out-jumps
}
chain nat-OUTPUT {
type nat hook output priority -100; policy accept;
ip6 daddr != ::1 fib daddr type local counter jump nat-prerouting-and-output
}
chain nat-POSTROUTING {
type nat hook postrouting priority srcnat; policy accept;
iifname vmap @nat-postrouting-out-jumps
oifname vmap @nat-postrouting-in-jumps
}
chain nat-PREROUTING {
type nat hook prerouting priority dstnat; policy accept;
fib daddr type local counter jump nat-prerouting-and-output
}
chain nat-prerouting-and-output {
}
chain raw-PREROUTING {
type filter hook prerouting priority raw; policy accept;
}
}
除了端口 80 和 443 之外的其他一切都正常…… ![]()