背景:
公司內部有一套系統A部署在內網,這套系統嵌套了B網站(也是內網),只有內網才能訪問。現在需要將這個A系統暴露到公網。B系統的安全策略比較低,想快速上線并提高B系統的安全性。
通過 Nginx 代理層 設置一個 中間域名 C(如
proxy.b.com
),它代理訪問真正的 B 網站,并在 C 層做 驗簽(簽名校驗)邏輯,只允許來自 A 網站的請求訪問。
? 這個方案的優勢
這是一個非常 穩妥、可控、安全性較高 的架構,具備以下優點:
優勢 | 說明 |
---|---|
隱藏真實 B 網站地址 | 只有代理 C 知道 B 的地址,用戶無法繞過代理直連 B |
可插入多種驗證邏輯 | 在代理層校驗 token、Referer、Origin、IP 都可以實現 |
控制粒度細 | 你可以在 Nginx 針對不同路徑做不同校驗策略 |
防止瀏覽器直接訪問 | C 的域名本身可以設置校驗策略,只允許 iframe 請求或 token 訪問 |
🔐 如何實現這個方案
1. 前端 A 網站 iframe 使用 C 域名
<iframe src="https://proxy.b.com/some/page?token=xyz"></iframe>
2. A 后端生成一次性 token
- Token 可包含時間戳 + 簽名(如 HMAC)
- Token 通過 query 或 header 傳給 C
- 防止別人偽造
3. Nginx 中的驗簽邏輯實現方式:
Nginx 本身不擅長做復雜的簽名校驗邏輯,常見的實現有兩種方式:
? 方法一:使用 Lua + OpenResty 插件校驗 token
安裝 OpenResty 后配置:
location / {access_by_lua_block {local args = ngx.req.get_uri_args()local token = args.token-- 簡化示例:校驗 token(你可用 JWT、HMAC、時間戳等方式)if token ~= "valid_token_abc123" thenngx.status = 403ngx.say("Forbidden: Invalid token")return ngx.exit(403)end}proxy_pass https://real-b-site.com;
}
? 方法二:Nginx 僅轉發,請求先打到中間服務(如 Node/PHP)
架構圖:
A 網站 iframe -> C 域名 (Nginx) -> 驗簽服務 (如 Node) -> B 網站
在 Node 層驗證 token 簽名、Referer 等合法性,合法后轉發請求到 B。
4. 隱藏真實 B 網站地址
- B 網站 只允許 C 代理服務器的 IP 請求(設置防火墻或 nginx 白名單)
- 用戶即使知道 B 網站地址也無法訪問
🚫 防止被繞過的關鍵點
防繞過策略 | 方法 |
---|---|
禁止直連 B | B 網站禁止所有外部 IP,或僅允許 C 代理服務器 IP |
Token 有時效 | Token 攜帶時間戳,過期后失效 |
Token 防偽造 | 使用密鑰簽名(如 HMAC、JWT)避免被猜出 |
限 Referer | 驗證 Referer 來源是否是 A 網站 |
iframe 校驗 | JS 檢查 window !== window.parent 拒絕獨立打開頁面 |
? 總結
你的 Nginx 代理層 + 驗簽邏輯 方案是可行且推薦的。它可以:
- 保證只有 A 網站能訪問 B 的頁面(通過 C 域名)
- 防止 Postman、瀏覽器直接訪問
- 隱藏 B 的真實地址
- 支持復雜的訪問控制邏輯