我有一個正在運行的 Raspberry Pi,我們在辦公室中使用它來進行我們不想在主開發伺服器上運行的小型測試專案。它正在運行阿帕奇。 DNS 透過 Cloudflare 處理,但處於僅 DNS 模式。目前,我測試時沒有 IP 限制。 A 記錄mysite.domain.tld
指向我的靜態 IP 位址123.123.123.123
,且 Internet 和 Pi 之間只有一個標準商業光纖路由器/數據機。
mysite.domain.tld
例如,當我使用沒有 Wi-Fi 的手機存取權時,手機電信業者 IP 會顯示。當我wget
從遠端伺服器上時,它是'IP 顯示在日誌中。一切都按預期進行。
mysite.domain.tld
但是,當我從 Pi 所在的相同網路內存取時,apache 會記錄路由器閘道 IP 192.168.1.1
。我希望看到我的公共 IP 位址,因為我與網域的連接透過 Cloudflare 解析為公共 IP。但我在日誌中看到了本地網路 IP。
(我在 macOS 上)和路由器上沒有任何設置/etc/hosts
,只有從連接埠 443 的連接的連接埠轉發是同一連接埠上的路由器到 Pi 的連接 - 任何地方都沒有引用任何有關網域的內容。當我 ping 時,mysite.domain.tld
它給我雲耀IP 位址,這正是我所期望的。
看起來好像在這條鏈的某個地方,我的 IP 位址和 Pi 的公共 IP 位址是匹配的,所以它用內部網關 IP 覆蓋了 IP。這裡到底發生了什麼事?我不頭腦就其本身而言,我只是想確保192.168.*
在防火牆上設置 IP 限制時可以信賴 IP 是可信的。
注意:這裡 Cloudflare 不會發送 CF-Connecting-IP 和類似的標頭,我認為只有在不處於僅 DNS 模式時才會發生這種情況。還有它似乎只有當我使用與 Pi 使用的相同網路連線時。
答案1
您的路由器運行的是 Linux,這種行為很容易在任何現有的 Linux 發行版上實現。我可以猜測路由器的防火牆中必須存在哪些規則才能使其像這樣運作。但請注意,這只是一種猜測,我們不知道規則在現實中到底是什麼樣子。
當您將連接埠轉送到網頁伺服器時,它會新增特定的 DNAT 規則,可能如下所示:
iptables -t nat -A PREROUTING -p tcp -d <your-external-address> --dport 443 -j DNAT --to-destination <raspberry-pi-address>
換句話說,這意味著:「在決定這個封包是發送到設備還是必須轉送之前,檢查封包的目的位址是否是你的外部位址,目的連接埠是否是443。如果匹配,則將目的位址更改為樹莓派的LAN位址」。請注意,此規則不會按介面進行過濾。
而且它肯定有 SNAT 類型的規則(用於為 LAN 提供對互聯網的訪問),可能看起來像這樣:
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE
換句話說,路由器決定封包要去哪裡後,在發送封包之前,會將其來源位址變更為出介面的位址(如果封包是從 LAN 傳送的)。同樣,介面不會過濾任何內容。
現在考慮您的 HTTPS 連線。您正在瀏覽器中指定主機名,對吧?您對其進行設置,以便將其解析為路由器的外部位址,該位址將成為目標位址。您的來源位址在 LAN 內部。因此,這兩條規則似乎都適用於您的連線封包。
處理它們時,路由器首先遇到 DNAT 規則,檢查目標位址和端口,並決定將目標位址更改為樹莓派的位址。然後發現封包要出去的介面是LAN 1。然後它根據第二個規則檢查部分轉換的封包,並發現來源位址來自 LAN。因此它將封包的來源位址替換為 LAN 介面的位址 192.168.1.1。這就是你的樹莓派所看到的。
NAT 操作是有狀態的,即它還維護一個表記錄,其中說明哪個被替換為什麼以及如何檢測後續轉發和回复資料包,因此它可以正確地轉換所有資料包。是的,事實證明 Linux 可以在同一個流中同時進行 DNAT 和 SNAT。
你能相信這種行為嗎?我不知道。如果路由器的韌體是開源的,我們就有機會進行檢查。沒有來源,我們無法確定。當原始碼關閉時,情況總是如此,這就是為什麼如果您擔心安全性,則必須避免使用閉源產品。