問題是這樣的:
我內網主機nginx配置了 域名+80端口,然后防火墻沒有配置80端口,但是外網機子去telnet 80端口可以通,用瀏覽器請求域名不能訪問nginx,然后防火墻開了80端口后,瀏覽器就可以訪問nginx了,為什么防火墻沒開80端口,telnet可以訪問?nginx又不行?
其根本原因在于?TCP連接建立?和?HTTP應用層請求?是兩個不同的階段,而防火墻規則可以精細地控制這兩個階段。
讓我們來分解一下整個過程:
1. Telnet 為什么能通?
當您執行?telnet your_domain 80
?時,發生了以下事情:
TCP三次握手:Telnet 工具會嘗試與您服務器的80端口建立一個原始的?TCP 連接。
防火墻的默認策略:許多防火墻(如?
firewalld
、iptables
)的默認策略是?允許出站(OUTPUT)和相關的回包(ESTABLISHED, RELATED)。您的?
telnet
?請求從外網機器發出,是一個?出站請求。當這個請求到達您的內網服務器時,服務器需要回應這個SYN包來完成三次握手。這個回包屬于?與已有連接相關的包(RELATED/ESTABLISHED)。
關鍵點:在沒有明確添加?
80/tcp
?規則時,防火墻允許了這次TCP連接建立的“回包”。因此,三次握手成功,TCP連接建立。Telnet 的成功標準:對于 Telnet 來說,只要TCP連接能建立,它就認為“端口是通的”,并顯示?
Connected to your_domain...
。此時,連接已經建立,Telnet 在等待您輸入數據(雖然您沒輸入就退出了)。
簡單來說:Telnet 成功只證明了從外網到您服務器80端口的TCP通道是打開的,并且防火墻允許了針對外網請求的“回包”。
2. 瀏覽器為什么之前不能訪問?
當您在瀏覽器中輸入?http://your_domain
?并按下回車時,發生了更多事情:
TCP連接建立:和 Telnet 一樣,瀏覽器首先會發起一個到服務器80端口的TCP三次握手。由于上述同樣的原因,這一步成功了。
發送HTTP請求:TCP連接建立后,瀏覽器會通過這個連接,發送一個實際的HTTP請求,例如?
GET / HTTP/1.1 Host: your_domain ...
。nginx 處理請求:nginx 守護進程監聽在80端口,它接收到這個HTTP請求,開始處理。
nginx 發送HTTP響應:nginx 處理完請求后,需要將網頁內容(如HTML、CSS等)作為?HTTP響應,通過剛才建立的TCP連接發回給瀏覽器。
防火墻的攔截:問題就出在這里!nginx 發送回的數據包,在通過服務器的防火墻時,防火墻會檢查規則:
這條從內網服務器發往外部瀏覽器的HTTP響應數據,屬于?新建的出站連接??不是,它是ESTABLISHED連接的一部分。
但是,防火墻策略需要決定是否允許?從80端口發起的出站流量。雖然默認允許回包,但其規則的嚴格程度可能有細微差別。
更可能的情況是:在您沒有明確添加?
80/tcp
?規則時,防火墻認為80端口的所有通信(無論是進還是出)都沒有被顯式允許。雖然它放行了握手包,但對于后續數據傳輸的管控更加嚴格,它丟棄了nginx試圖發送出的HTTP響應數據包。
瀏覽器超時:瀏覽器發送了HTTP請求后,一直在等待服務器的響應。因為響應數據包被防火墻丟棄了,它什么也收不到。等待一段時間后,就會觸發超時,顯示?“無法訪問此網站”、“連接已重置”?或?“ERR_CONNECTION_TIMED_OUT”?等錯誤。
3. 為什么開了防火墻端口后就一切正常了?
當您在防火墻中明確添加了允許?80/tcp
?端口的規則后,您不僅僅是“打開了端口”。您實際上是創建了一條明確的、永久的策略,告訴防火墻:
“允許所有目的地為80端口的傳入流量,并且與此連接相關的所有進出流量都應被允許。”
這條規則確保了:
TCP三次握手的SYN包被允許進入。
nginx產生的HTTP響應數據包也能順利地通過防火墻發回給外部的瀏覽器。
因此,整個HTTP通信流程就暢通無阻了。
總結與類比
您可以把它想象成一個門衛和快遞員:
Telnet(敲門):門外有人敲門(SYN包),門衛聽到后,打開門看了一眼又關上了(回SYN-ACK包)。敲門的人知道門后有人(Telnet連接成功),但還沒等說話就走了。
瀏覽器(送貨請求):門外的人敲門,門衛開門(TCP握手成功)。門外的人說:“我是快遞員,這是給你的包裹(HTTP Request)”。門內的nginx接過包裹準備處理。但當nginx拿著回執單(HTTP Response)要遞給門外的快遞員時,門衛卻攔住了他,不讓他遞出去(防火墻丟棄數據包)。快遞員在門外等不到回執,只好離開(瀏覽器超時)。
開了防火墻(給門衛指令):門衛得到明確指令:“所有快遞相關事務都放行”。于是整個收取包裹、遞回回執的過程暢通無阻。
結論:
Telnet測試的是TCP層的連接性,而瀏覽器訪問需要完成完整的HTTP應用層交互。防火墻在沒有明確規則時,其默認行為可能允許簡單的連接測試,但會阻止更復雜的數據傳輸。顯式地打開端口意味著為整個通信流程提供了完整的允許策略。