网络描述

网络描述

网络描述

虚拟主机环境(KVM):

客人:

Ubuntu 14.04.5 LTS \n \l
Linux ari 3.8.0-29-generic #42~precise1-Ubuntu SMP Wed Aug 14 15:31:16 UTC 2013 i686 i686 i686 GNU/Linux

主持人:

Ubuntu 14.04.3 LTS \n \l
Linux host 3.13.0-74-generic #118-Ubuntu SMP Thu Dec 17 22:52:10 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

网络:

          eth0 |----------| virbr63                    eth0 |----------|
---------------|   HOST   |---------------------------------|  ari     |
  11.22.33.44  |----------| 192.168.63.1       192.168.63.2 |----------|
  • 11.22.33.44是公有 IP 地址
  • ari是虚拟机(来宾)
  • HOST是一台物理机(虚拟机主机)
  • eth0是物理网卡HOST
  • virbr63是虚拟网络适配器

HOST 上有一条 iptables 规则:

-I PREROUTING -p tcp -d 11.22.33.44 --dport 80 -j DNAT --to 192.168.63.2:8888

假设mydomain.com解析为 11.22.33.44。ari 正在为 11.22.33.44 上的所有 HTTP 请求提供服务。Curl-ingmydomain.com可在互联网上的任何地方工作。

问题

当我尝试mydomain.com通过 HTTP访问时ari,它不起作用(curl 挂起)。

这是 tcpdump(在主机上)中不成功的 curl 尝试的结果:

host$ sudo tcpdump -i virbr63 port 8888
22:03:15.541155 IP 192.168.63.2.42740 > 192.168.63.2.8888: Flags [S], seq 786111635, win 14600, options [mss1460,sackOK,TS val 1662005624 ecr 0,nop,wscale 5], length 0
22:03:15.541173 IP 192.168.63.2.42740 > 192.168.63.2.8888: Flags [S], seq 786111635, win 14600, options [mss1460,sackOK,TS val 1662005624 ecr 0,nop,wscale 5], length 0

这种情况每隔几秒就会重复一次。

这是一次成功的 curl 尝试(从外部)在 tcpdump(在主机上)中的样子:

host$ sudo tcpdump -i virbr63 port 8888
21:59:10.924031 IP external.xxx.47812 > 192.168.63.2.8888: Flags [S], seq 2881442181, win 29200, options [mss 1420,sackOK,TS val 4022859071 ecr 0,nop,wscale 7], length 0
21:59:10.924339 IP 192.168.63.2.8888 > external.xxx.47812: Flags [S.], seq 1044842547, ack 2881442182, win 14480, options [mss 1460,sackOK,TS val 1661944471 ecr 4022859071,nop,wscale 5], length 0
21:59:10.968371 IP external.xxx.47812 > 192.168.63.2.8888: Flags [.], ack 1, win 229, options [nop,nop,TS val 4022859117 ecr 1661944471], length 0
21:59:10.976415 IP external.xxx.47812 > 192.168.63.2.8888: Flags [P.], seq 1:72, ack 1, win 229, options [nop,nop,TS val 4022859117 ecr 1661944471], length 71
21:59:10.976683 IP 192.168.63.2.8888 > external.xxx.47812: Flags [.], ack 72, win 453, options [nop,nop,TS val 1661944484 ecr 4022859117], length 0
21:59:10.977985 IP 192.168.63.2.8888 > external.xxx.47812: Flags [P.], seq 1:909, ack 72, win 453, options [nop,nop,TS val 1661944484 ecr 4022859117], length 908
21:59:11.025271 IP external.xxx.47812 > 192.168.63.2.8888: Flags [.], ack 909, win 243, options [nop,nop,TS val 4022859175 ecr 1661944484], length 0
21:59:11.030033 IP external.xxx.47812 > 192.168.63.2.8888: Flags [F.], seq 72, ack 909, win 243, options [nop,nop,TS val 4022859175 ecr 1661944484], length 0
21:59:11.030375 IP 192.168.63.2.8888 > external.xxx.47812: Flags [F.], seq 909, ack 73, win 453, options [nop,nop,TS val 1661944497 ecr 4022859175], length 0
21:59:11.075205 IP external.xxx.47812 > 192.168.63.2.8888: Flags [.], ack 910, win 243, options [nop,nop,TS val 4022859223 ecr 1661944497], length 0
  • external.xxx是发出请求的 IP 地址的反向 DNS

这是一个监控设置,所以我正在寻找一个host尽可能少做更改的解决方案。最好不要对主机进行任何更改,只需说服ari(客户)接受数据包并通过网络路由响应。

非解决方案

什么不能解决我的问题

直接访问 ari:8888

这没有帮助,因为这是一个监控设置,其全部目的是测试 11.22.33.44:80 是否有效。

从不同的客户机(虚拟机)访问

它确实有效(也是来自同一网络192.168.63.0/24),但并不能解决问题。

我尝试过但不起作用的方法

类似问题

我查看了以下问题及其答案:

来自本地主机的 DNAT(127.0.0.1)

KVM 客户机无法连接到主机,但反之亦然

接受本地

ari$ sudo sysctl -w net.ipv4.conf.eth0.accept_local=1

它不能解决问题,也不能改变 tcpdump 输出。

路由本地网络

ari$ sudo sysctl -w net.ipv4.conf.eth0.route_localnet=1

它不能解决问题,也不能改变 tcpdump 输出。

rp_过滤器

ari$ sudo sysctl -w net.ipv4.conf.eth0.rp_filter=0

它不能解决问题,也不能改变 tcpdump 输出。

第二个(虚拟)网络接口ari

我尝试添加第二个网络接口,eth0:1其 IP 地址为192.168.63.200。访问192.168.63.2:8888失败192.168.63.200,同样如此:

17:42:08.746328 IP 192.168.63.200.41676 > 192.168.63.2.8888: Flags [S], seq 3211292625, win 14600, options [mss 1460,sackOK,TS val 1744488483 ecr 0,nop,wscale 5], length 0
17:42:08.746351 IP 192.168.63.200.41676 > 192.168.63.2.8888: Flags [S], seq 3211292625, win 14600, options [mss 1460,sackOK,TS val 1744488483 ecr 0,nop,wscale 5], length 0

编辑:类似的解决方案

在 kupson 回答之后,我在这里找到了一个非常相似的解决方案:

http://idallen.com/dnat.txt(搜索“许多客户端 - 太多 SNAT”)。它具有:

iptables -t nat -A POSTROUTING -s 172.16.0.0/24 -d 172.16.0.0/24 -m conntrack --ctstate DNAT  -j SNAT --to 172.16.0.254

答案1

一种可能的解决方案是在主机上使用 SNAT 来更改数据包的源地址并将其转发回“ari”VM。这不是性能最高的解决方案,但它很简单,并且对于许多设置来说已经足够好了。

# fixup chain
iptables -t nat -N fixup-snat
iptables -t nat -A fixup-snat -m conntrack --ctstate DNAT -j MASQUERADE

# please select proper network ranges and NIC names below
iptables -t nat -I POSTROUTING -s 192.168.63.0/24 -d 192.168.63.0/24 -o virbr63 -j fixup-snat

您可以将其合并为单一iptables规则,但为了更清晰起见,我更喜欢使用单独的链。

您还应该禁用桥接接口上的 iptables 处理数据包:

sysctl -w net.bridge.bridge-nf-call-arptables=0
sysctl -w net.bridge.bridge-nf-call-ip6tables=0
sysctl -w net.bridge.bridge-nf-call-iptables=0

为了使这些在 Debian 系统重启时继续有效,请编辑该文件或在目录/etc/sysctl.conf中创建新文件。/etc/sysctl.d/

相关内容