Linux-Networking

KVM 來賓在 DNAT 後無法連接到自身

  • May 29, 2018

網路描述

虛擬主機環境(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 請求提供服務。冰壺mydomain.com可以在 Internet 上的任何地方進行。

問題

當我嘗試mydomain.com通過 HTTP 從訪問時ari,它不起作用(捲曲掛起)。

這是 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

這會每隔幾秒鐘重複一次。

這是 tcpdump(在主機上)中成功的 curl 嘗試(從外部)的樣子:

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 輸出。

route_localnet

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

它不能解決問題,也不會改變 tcpdump 輸出。

rp_filter

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

它不能解決問題,也不會改變 tcpdump 輸出。

第二個(虛擬)網路介面打開ari

我嘗試eth0:1使用 IP 地址添加第二個網路介面192.168.63.200192.168.63.2:8888192.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

一種可能的解決方案是在主機上使用 SNAT 來更改數據包的源地址並將它們轉發回“ari”虛擬機。它不是最高效的解決方案,但對於許多設置來說它簡單且足夠好。

# 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/目錄中創建新文件。

引用自:https://serverfault.com/questions/913110