我有一个 Debian 12 服务器(公共 IP85.xxx.xxx.xxx
地址为enp6s0
),在网桥上运行一堆 LXC 容器cbr0
。
由于公共 IP 是动态的,我必须设置forward
规则prerouting
才能dnat
使传入请求到达容器。例如。端口 80/443 已连接到容器10.10.0.1
。这是我的nftables
规则:
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state {established, related} accept
iifname lo accept
iifname cbr0 accept
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
}
chain forward {
type filter hook forward priority 0; policy accept;
}
chain output {
type filter hook output priority 0;
}
}
table ip filter {
chain forward {
type filter hook forward priority 0; policy drop;
oifname enp6s0 iifname cbr0 accept
iifname enp6s0 oifname cbr0 ct state related, established accept
# Webproxy
iifname enp6s0 oifname cbr0 tcp dport 80 accept
iifname enp6s0 oifname cbr0 udp dport 80 accept
iifname enp6s0 oifname cbr0 tcp dport 443 accept
iifname enp6s0 oifname cbr0 udp dport 443 accept
}
}
table ip nat {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
}
chain prerouting {
type nat hook prerouting priority -100; policy accept;
# Webproxy
iifname enp6s0 tcp dport 80 dnat to 10.10.0.1:80
iifname enp6s0 udp dport 80 dnat to 10.10.0.1:80
iifname enp6s0 tcp dport 443 dnat to 10.10.0.1:443
iifname enp6s0 udp dport 443 dnat to 10.10.0.1:443
}
}
现在的问题是:发夹NAT。我有多个容器托管网站,有时其中一些容器需要使用域名与其他容器进行通信。当他们对这些域运行 DNS 查询时,他们将获取主机 IP 并且通信失败:
如何在不诉诸 DNS 攻击的情况下解决这种情况?有没有办法nftables
在拥有动态IP的情况下设置在内部转发请求?上面的内容是如何实现iifname
的呢?
谢谢。
您可能需要的是 nft 手册页中的“FIB EXPRESSION”。这是我用于 DNAT 的规则(您需要根据您的设置进行调整):
fib daddr type local
daddr
是与任何匹配 NAT 框地址的部分相匹配的部分。请注意,您可能还需要提供适当的 SNAT 映射才能使其正常工作(因为返回数据包可能会直接发送到具有内部源地址的桥接口,该地址与虚拟机上的任何连接都不匹配)。
好吧,我设法解决了这个问题并简化了我的配置。
forward
链不需要明确接受特定端口的流量,我可以告诉它dnat
稍后转发具有特定规则的任何内容:dnat
可以来自enp6s0
和cbr0
:现在一切似乎都正常了,但是有一个小细节:当我的 webproxy 容器从互联网 (
enp6s0
) 获取请求时,它会将真实的远程计算机 IP 记录为这些请求的源,但是当它们来自另一个容器时,源 IP 显示为 10.0 .0.254 这是 .0.254 中主机的 IPcbr0
。