如何在桥接网络上从客户端本身通过公共 IP 访问 NATed、虚拟化(LXC)服务器?

如何在桥接网络上从客户端本身通过公共 IP 访问 NATed、虚拟化(LXC)服务器?

设置

    ____________________________             ____________________________ 
    | Host                     |             | Client                   |
    | Public IP:   66.66.66.66 |             |                          |
    | Internal IP: 10.0.3.1    | <---------> | Internal IP: 10.0.3.192  |
    ----------------------------             ----------------------------
  • 具有公网 IP 的主机 (=66.66.66.66)
  • Linux 容器(LXC),在本文的其余部分称为客户端,veth它从运行 Web 服务器的网络选项开始。
  • 在主机上,配置防火墙ufw并打开相应的端口并转发到客户端,这样就可以了。

iptables端口转发/etc/ufw/before.rules

# nat Table rules
*nat
:PREROUTING ACCEPT [0:0]

-A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.0.3.192:80
-A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.0.3.192:443
# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT

/etc/network/interfaces在主机上:

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet static
    address 66.66.66.66
    netmask 255.255.255.0
    network 66.66.66.0
    broadcast 66.66.66.255
    gateway 66.66.66.1
    # dns-* options are implemented by the resolvconf package, if installed
    dns-nameservers 8.8.8.8

/etc/network/interfaces在客户端:

# The loopback network interface
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 10.0.3.192
    netmask 255.255.255.0
    gateway 10.0.3.1
    broadcast 10.0.3.255

客户端的端口扫描

Starting Nmap 5.21 ( http://nmap.org ) at 2014-04-18 18:46 CEST
Nmap scan report for 66.66.66.66
Host is up (0.00011s latency).
PORT    STATE  SERVICE
80/tcp  closed http
443/tcp closed https

从“外部”进行端口扫描

Starting Nmap 6.40 ( http://nmap.org ) at 2014-04-18 19:54 CEST
Nmap scan report for 66.66.66.66
Host is up (0.41s latency).
PORT    STATE SERVICE
80/tcp  open  http
443/tcp open  https

Nmap done: 1 IP address (1 host up) scanned in 1.28 seconds

iptables 配置:

$ iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
DNAT       tcp  --  anywhere             anywhere             tcp dpt:http to:10.0.3.192:80
DNAT       tcp  --  anywhere             anywhere             tcp dpt:https to:10.0.3.192:443
DNAT       tcp  --  anywhere             anywhere             tcp dpt:43211 to:10.0.3.192:22
DNAT       tcp  --  anywhere             anywhere             tcp dpt:http-alt to:10.0.3.192:8080

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  tcp  --  anywhere             10.0.3.192           tcp dpt:http
MASQUERADE  tcp  --  anywhere             10.0.3.192           tcp dpt:https
MASQUERADE  all  --  10.0.3.0/24         !10.0.3.0/24

版本

  • Ubuntu 12.04(主机和客户端)
  • LXC(1.0.3-0ubuntu1~ubuntu12.04.1~ppa1)

期望结果

我想从客户端本身通过公有 IP例如

$ curl http://66.66.66.66
curl: (7) couldn't connect to host

应该得到相同的结果

$ curl http://10.0.3.192
<html>.....

奇怪的$ ping 66.66.66.66是,私有网络内部的客户端却可以工作。


我尝试过

我发现这个问题与所谓的发夹式 NAT/环回式 NAT,尽管我无法使用以下规则配置伪装,以使其起作用(在条目/etc/ufw/before.rules之后PREROUTING):

# nat Table rules
*nat
:POSTROUTING ACCEPT [0:0]

-A POSTROUTING -o eth0 -d 10.0.3.192 -p tcp --dport 80 -j MASQUERADE
-A POSTROUTING -o eth0 -d 10.0.3.192 -p tcp --dport 443 -j MASQUERADE

# don't delete the 'COMMIT' line or these nat table rules won't be processed
COMMIT

我猜想,问题出在桥接网络或我无法将 MASQUERADE 规则正确适配到我的设置上。任何建议和意见,包括对设置的建议和意见,都值得赞赏。

相关问题或文章,但没有帮助

答案1

(我首先写的是它是一个路由网络而不是桥接网络。现在我看到它正在使用 LXC,所以我真的不知道。但如果 PREROUTING 已经起作用,我真的希望我下面写的能够起作用)

您正在使用 PREROUTING 链,此链仅改变(即将)路由的数据包,即来自其他地方的数据包。数据包生成于主持人本身没有路由(它们只是输出,就像任何主机都可以做的那样),所以这个链永远不会收到 curl 的数据包。curl 刚刚尝试连接主持人和平常一样。还有另一个链可以捕获本地生成的数据包:OUTPUT。

因此,您还将 DNAT 规则复制到 (-t nat) OUTPUT 链,并进行了一些修改:OUTPUT 不需要输入接口。您可以-i eth0-o lo ! -s 127.0.0.0/8-d 66.66.66.66或其他东西替换,但您需要一些限制,否则对任何地方的任何 Web 请求都将转到客户. 第一个例子独立于主持人的 IP,第二个 IP 更短,随你喜欢。这不是拼写错误,如果你从自身连接到 66.66.66.66,这是一个本地数据包,因此它会通过接口lo。但是由于 127.0.0.1 之类的目的地无法重新路由(curl http://127.0.0.1/会超时而不是说无法连接),因此 127.0.0.0/8 被列为例外。

就是这样。其他一切都照常由 conntrack 处理。您应该删除 2 个特定于端口的 MASQUERADE 规则。它们是不必要的,甚至可能会造成干扰(我认为如果它们有效,结果是客户永远会看到主持人作为 Web 服务器上的源)

因此,简短的回答是(使用-t nat):

-A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.0.3.192
-A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.0.3.192
-A OUTPUT -o lo ! -s 127.0.0.0/8 -p tcp --dport 80 -j DNAT --to-destination 10.0.3.192
-A OUTPUT -o lo ! -s 127.0.0.0/8 -p tcp --dport 443 -j DNAT --to-destination 10.0.3.192

相关内容