通過 InetAddress.getAllByName() 獲取到網站的多個 IP (如 CSDN 的 4 個 IP),但在瀏覽器輸入 https://211.100.26.124 卻返回 403 Forbidden,而域名訪問正常。本文揭示背後原理:HTTP Host 頭與虛擬主機機制。
現象重現
https://www.csdn.net → 正常訪問
https://211.100.26.124 / .121 / .122 / .123 → 全部返回 HTTP 403 (非 404)
錯誤碼 403 表明**服務端主動拒絕**,而非資源不存在。
根本原因:HTTP Host 頭
HTTP/1.1 請求**強制包含 Host 頭**,服務端據此路由到正確的虛擬主機:
GET / HTTP/1.1
Host: www.csdn.net ← 瀏覽器自動填入域名
User-Agent: ...
GET / HTTP/1.1
Host: 211.100.26.124 ← 直接輸入 IP 時,Host 變為 IP
User-Agent: ...
虛擬主機工作原理
- 一台物理服務器 (單 IP) 運行多個網站 (虛擬主機)。
- 服務端 (Nginx/Apache/Tomcat) 根據
Host 頭匹配 server_name / Host 配置。
- 匹配成功 → 處理請求;匹配失敗或無 Host → 返回默認站點或 403/404。
為什麼大網站禁止 IP 直訪?
| 原因 | 說明 |
| 安全防護 | 隱藏真實後端拓撲,減少直接掃描/攻擊面 |
| 多租戶隔離 | 同 IP 承載多個業務,Host 頭是唯一路由依據 |
| SEO 與品牌 | 統一入口域名,避免搜索引擎收錄 IP 地址 |
| WAF/CDN 回源 | 邊緣節點回源需攜帶正確 Host,IP 直訪繞過防護 |
對比:重定向到域名的網站
部分網站 (如 Oracle, IBM) 採用**重定向策略**:
https://141.146.8.66 → 302 Redirect → https://www.oracle.com/
https://129.42.60.212 → 302 Redirect → https://www.ibm.com/us/
這屬於應用層邏輯,而非協議強制。
驗證方法:ping 與 getAllByName
> ping www.csdn.net
Reply from 211.100.26.122: bytes=32 time=31ms TTL=48 ← DNS 隨機返回一個 IP
> java MyInetAddress3 www.csdn.net
www.csdn.net/211.100.26.124
www.csdn.net/211.100.26.121
www.csdn.net/211.100.26.122
www.csdn.net/211.100.26.123
ping 返回的 IP 是 getAllByName 列表中的其中一個 (輪詢/隨機)。
開發啟示
- **爬蟲/測試工具**必須手動設置
Host 頭:request.setHeader("Host", "www.csdn.net")。
- **服務端配置**需顯式綁定域名,拒絕無 Host 或 IP Host 的請求 (返回 403/444)。
- **健康檢查/監控**探針應模擬真實用戶行為:發送帶正確 Host 的 HTTP 請求,而非單純 TCP 連接或 IP 請求。
- **內網服務**同理:Nginx/Ingress 根據 Host 路由,直接用 Service IP 訪問會失敗。
總結
IP 是網路層地址,域名是應用層標識。**HTTP 虛擬主機機制強制綁定域名與服務**,繞過域名直接用 IP 訪問,等於丟失了路由鑰匙,自然被門衛 (WAF/虛擬主機配置) 攔截。
- 上一篇文章: Java 網路程式設計精通指南(4):DNS 緩存機制 — 配置、驗證與負緩存陷阱
- 下一篇文章: Java 網路程式設計精通指南(2):InetAddress 四大靜態工廠方法 — 創建 IP 地址對象完全指南
Copyright ©
程式碼之家 All Rights Reserved