设置
____________________________ ____________________________
| 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 规则正确适配到我的设置上。任何建议和意见,包括对设置的建议和意见,都值得赞赏。
相关问题或文章,但没有帮助
- 使用公共 IP 的 LXC 网络
- 关于LXC的不同网络模式:http://containerops.org/2013/11/19/lxc-networking/
- https://coderwall.com/p/k0gutq
- 对具有私有 IP 的容器使用 NAT(明确指出它无法在私有网络内部工作):https://openvz.org/Using_NAT_for_container_with_private_IPs
- 清理 LXC + NAT 配置:https://coderwall.com/p/k0gutq
- iptables - 如何使用外部 IP 访问本地服务器(不建议这样做,建议设置 DNS 或编辑主机文件,但基于 FQDN):http://www.tomshardware.co.uk/forum/12532-42-iptables-access-local-server-external
- 我的路由器上的 NAT 环回是否存在安全问题?(给出 SNAT 规则:https://security.stackexchange.com/questions/16343/is-nat-loopback-on-my-router-a-security-problem
- 使用 iptables 进行 NAT 环回:http://for-invent.com/nat-loopback-using-iptables/
答案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