我有一个非常默认的 lxc 设置,其中包含一个主机和多个容器。一个容器网络前端通过 DNATing 端口获取端口 80 和 443 上的所有主机流量。网络前端通过虚拟主机决定哪个容器网页应用X应该获取请求并将请求代理到 webappX 的私有 IP:
host:443 <--prerouting--> webfrontend:443 <--nginx--> webappX-private:80
-A PREROUTING -d 80.x.x.x/32 -i eth0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 10.0.3.100:443
- 主机(公共):80.xxx
- web前端(lxcbr0):10.0.3.100
- webappX (lxcbr0): 10.0.3.200
- webappY (lxcbr0): 10.0.3.201
- ...
这工作正常并允许 letsencrypt-certificates 等的中心点。
但是,当 webappX 需要访问 webappY 时,连接被拒绝,并且 webfrontend 永远看不到该请求。我可以通过私有 IP 访问 webappY(来自 webappX),但无法访问 webappY-public(又名 webfrontend):
root@webappX:~# curl -I http://10.0.3.201
HTTP/1.1 200 OK
[...]
root@webappX:~# curl -I http://webappY.example.com
curl: (7) Failed to connect to webappY.example.com port 80: Connection refused
root@webappX:~# nslookup webappY.example.com
[...]
Name: webappY.example.com
Address: 80.x.x.x
容器之间的转发如下:
*filter
-A FORWARD -o lxcbr0 -j ACCEPT
-A FORWARD -i lxcbr0 -j ACCEPT
到目前为止,我已尝试在 eth0 和 lo 上设置 POSTROUTING 规则和 OUTPUT 规则,但没有成功。
有任何想法吗?
答案1
你需要的是所谓的NAT 发夹结构(又名 NAT 环回、NAT 反射):
NAT 环回,[...] 是许多消费类路由器的一项功能,允许从本地网络内部通过公共 IP 地址访问服务。
为什么它不起作用?您在问题中提供的 IPTables DNAT 规则指定了此规则应应用到的传入接口: 。但是,-i eth0
您的流量不是来自某个虚拟网络接口或任何其他接口。只需删除此限制就足以使其正常工作。eth0
eth0
或者,可以添加一条单独的规则lxcbr0
:
iptables -t nat -A PREROUTING -i lxcbr0 -p tcp --dport 443 \
--destination 80.x.x.x -j DNAT --to 10.0.3.100:443