同一數據中心的一台特定機器無法訪問 Web 伺服器
我是一名程序員,他被推到伺服器管理職責中,我遇到了一個讓我很困惑的問題。缺乏知識無疑是罪魁禍首,所以如果可以的話,請教育我。:)
問題簡介:由同一專用託管服務託管的兩台物理伺服器。一台伺服器上的 Web 伺服器(在 VM 中執行)無法被另一台伺服器訪問,但網際網路上任何嘗試訪問的人都可以訪問。
設置:
我們有兩台由 ServerBeach 託管的伺服器。兩者都執行 Debian,一個執行帶有兩個 VM 的 VMWare Server 2 - 每個都執行 Debian。每個虛擬機都執行 Apache 並提供一個網站。為了清楚起見,一些假IP:
伺服器 #1 (eth0):10.0.1.1
伺服器 #2 (eth0):11.0.0.1
伺服器 #2 輔助 IP (eth0:1) - 對於 VM #1:10.0.2.1
伺服器 #2 輔助 IP (eth0:2) -對於 VM #2:10.0.2.2
伺服器 #2 上的虛擬機通過僅主機網路連接到主機:
伺服器 #2 (vmnet1): 192.168.0.1
VM #1: 192.168.0.2
VM #2: 192.168.0.3
…而伺服器 #2 上的 iptables 規則將 Internet 流量綁定到這些輔助 IP,並將目標 IP 更改為前往 VM,然後再次返回從 VM 前往 Internet 的流量:
-A PREROUTING -d 10.0.2.1 -i eth0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.0.2:80 (...) -A POSTROUTING -s 192.168.0.2 -o eth0 -j SNAT --to-source 10.0.2.1
這行得通。Internet 上的電腦可以將其瀏覽器指向http://10.0.2.1,然後它會在 VM 上執行 Web 伺服器。這種設置,其中輔助 IP 是主機上的別名,而不是虛擬機本身,是 ServerBeach 堅持應該配置這樣的 VMWare 設置的方式。它完成了這項工作。
唯一奇怪的是,當 Server #1 嘗試像 Internet 上的任何其他客戶端一樣訪問 Server #2 VM 時,它會超時。(我通過 SSH 登錄到伺服器 #1 並使用連結嘗試瀏覽該站點,甚至在埠 80 上進行 telnet)
如果我在 VM #1 上執行 tshark,我會看到 SYN 數據包從伺服器 #1 到伺服器 #2 到達 VM:
4.607664 10.0.1.1 -> 192.168.0.2 TCP 44983 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=318986 TSER=0 WS=7 52.596287 10.0.1.1 -> 192.168.0.2 TCP 44983 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=330986 TSER=0 WS=7 (etc...)
SYN 數據包不斷出現,但虛擬機從不發回 SYN-ACK。
現在,如果我跳到任何其他電腦上並在瀏覽器中訪問該 URL,我會看到 SYN、SYN-ACK 和 ACK,當然還有接下來的流量(我們將這個其他系統稱為 170.0.0.1):
8.456176 170.0.0.1 -> 192.168.0.2 TCP 16945 > http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=1 TSV=972883011 TSER=0 8.456243 192.168.0.2 -> 170.0.0.1 TCP http > 16945 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=718068724 TSER=972883011 WS=4 8.522374 170.0.0.1 -> 192.168.0.2 TCP 16945 > http [ACK] Seq=1 Ack=1 Win=66608 Len=0 TSV=972883012 TSER=718068724 (... let the GETs begin! ...)
VM #2 上也會發生同樣的事情。除了Server #1 ,每個人都可以與 Web 伺服器聯繫並進行通信。
伺服器 #1 當然可以訪問 Internet 上的任何其他網站。
編輯:如果我從伺服器 #1 執行 nmap -sS 10.0.2.1,埠 80(以及伺服器 #2 設置為傳遞給 VM 的任何其他埠)將顯示為已過濾。但是,如果我從任何其他機器執行相同的 nmap,埠將顯示為打開。
我知道這個問題可能很難理解,而且我當然不希望任何不親身實踐的人當場就想出答案。但我想知道是否有人可以回答… VM #1 從伺服器 #1 獲取 SYN 數據包但不嘗試發回 SYN-ACK 的原因可能是什麼?我認為問題可能與主機有關,但 SYN 顯然確實會到達 VM,一旦它們到達那裡,它似乎就會忽略它們——但它會立即響應來自任何其他客戶端的 SYN。
只是在這裡尋找線索。
編輯#2:按照 kubanskamac 的建議,我可能已經找到了問題所在。
在 VM #1 上,netstat -rn 提供:
Destination Gateway Genmask Flags MSS Window irtt Iface 192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 10.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 eth0 0.0.0.0 192.168.0.1 0.0.0.0 UG 0 0 0 eth0
因此,如果我沒看錯的話,VM 發往 10.xxx 的任何東西都不會轉到 192.168.0.1(VMWare 主機的適配器,也是 VM #1 到外部世界的唯一路徑)。
那麼如何使 VM #1 至少通過 192.168.0.1 網關路由發往 10.0.1.x 的數據包?查看伺服器 #2 的 netstat -rn,在我看來,如果它接收到數據包,它將正確路由數據包。
編輯#3:解決了!
編輯#2 的線索是正確的。我使用“路由”命令回答了我自己的問題:
路由添加 -net 10.0.2.0 網路遮罩 255.255.255.0 gw 192.168.0.1
最後一個問題:如何使上述命令永久化?
Server1 似乎與 Server2 的介面 eth0:1 位於同一子網上,但您沒有提供網路遮罩,所以我不確定。
只有在 Server2 決定通過 eth0 或 eth0:1 或 eth0:2 發送數據包後,您的 POSTROUTING 規則才會啟動。為了發送數據包,Server2 需要找出哪個 MAC 地址是所需的目的地(它使用 ARP 來查找 MAC)。如果 Server1 在不同的子網上,那麼數據包應該被發送到預設網關的 MAC。如果 Server1 在同一個 IP 子網上(看起來如此),則無需打擾預設網關,並且 Server2 單獨嘗試將 IP 解析為某個可用的 MAC。如果不成功,數據包將無法發送——它無處可去。
arp -a # (on Server2) print known MACs netstat -rn # (on Server2 and VM1) print table for IP routing decisions