背景:
公司内部有一套系统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 的真实地址
- 支持复杂的访问控制逻辑