以下是我的设置的简短/简化图表(抱歉标题):
Internet ----- eth0 (1.2.3.4) --- br0 (10.0.0.1)
|
+---------------+---------------+
| |
veth0 (10.0.0.2) veth1 (10.0.0.3)
httpd app
我通过常用的 DNAT/SNAT(使用 nftables)将外部流量从 eth0 转发到适当的服务(例如httpd
,如果有人与 eth0 上的端口 443 通信,则转发到 )。如果容器使用内部 IP 地址(10.0.0.X),我还可以在容器之间(例如从app
到httpd
)或容器与“主机”之间(通过 br0)通信。这一切都无需打开 即可工作route_localnet
。
我似乎无法让它正常工作的是,例如,如果容器尝试使用外部地址 (1.2.3.4)app
进行通信。例如,如果向 1.2.3.4:443 发送请求。它使用的是 1.2.3.4 而不是内部 10.0.0.2,这超出了我的控制范围(我可以通过添加拆分 DNS 视图来修复某些情况,但肯定不是全部,所以这真的不值得)。httpd
app
当我尝试从容器使用外部地址app
进行通信时httpd
,例如使用 socat ( socat -4 - TCP4:1.2.3.4:443
),我收到 EHOSTUNREACH(“没有到主机的路由”)。
我尝试为这种情况添加单独的 DNAT,例如:nft add rule ip contBr prerouting iif "br0" ip daddr 1.2.3.4 tcp dport { 80, 443 } dnat to 10.0.0.2
。这个想法是,由于它只在路由之前更改目标地址,因此它将知道在路由期间将其发送到哪里,并且源地址保持为 10.0.0.3,因此返回答案应该没问题。但不起作用。现在,当尝试httpd
从进行对话app
时,我得到了 ETIMEDOUT(“连接超时”) - 这不应该是我的任何过滤器,因为我拒绝所有我不想要的东西,而不是直接丢弃它。
不确定在互联网上或在这里到底要搜索什么。
答案1
在 Preston 对我的问题做出有益的评论后,我发现我正在寻找的术语/技术被称为Hairpinning
/ Hairpin NAT
(https://en.wikipedia.org/wiki/Hairpinning,https://newspaint.wordpress.com/2018/09/13/hairpin-for-lxc-containers-using-iptables/)。
nft add rule ip contBr prerouting iif "br0" ip daddr 1.2.3.4 tcp dport { 80, 443 } dnat to 10.0.0.2
我的单一规则不起作用的原因是,虽然目标地址更改为正确地址,但答案也会返回到预期的源( app
,10.0.0.3);运行的应用程序app
将期望从地址为 1.2.3.4 的主机得到答复,而不是 10.0.0.2 - 但由于 DNAT,情况就是这样。
解决办法就是对连接进行标记,在向 发送应答时app
,我们要么需要添加 SNAT,要么添加 MASQUERADE;这样应答包才能得到预期的源地址 1.2.3.4。
对我有用的是:
nft add rule ip contBr prerouting iif "br0" ip daddr 1.2.3.4 tcp dport { 80, 443 } ct mark set 0x61687269
nft add rule ip contBr prerouting iif "br0" ip daddr 1.2.3.4 tcp dport { 80, 443 } dnat to 10.0.0.2
nft add rule ip contBr postrouting oif "br0" ct mark 0x61687269 snat to 1.2.3.4
/------------------------------------\
/ \
RESP 10.0.0.3 / REQ 1.2.3.4:443 \
SNAT 1.2.3.4 / SRC 10.0.0.3 \
| /------------------------------------\ \
| | \ |
Internet ----- eth0 (1.2.3.4) --- br0 (10.0.0.1) | |
| | | | |
| | DNAT 10.0.0.2 | | |
| | SRC 10.0.0.3 | | |
| | | | |
RESP 10.0.0.3 | | +---------------+---------------+ | |
SRC 10.0.0.2 | | | | | |
| | | | | |
| | | | | |
^ v | | ^ v
veth0 (10.0.0.2) veth1 (10.0.0.3)
httpd app