Nginx实现多租户隔离与XSS防护需分层设计:路由层按域名或路径识别租户并校验合法性,策略层限流、透传租户ID、记录独立日志,响应层加CSP等安全头;禁用X-XSS-Protection,启用严格Content-Security-Policy。

直接用 Nginx 实现多租户资源隔离和 XSS 防护,关键不在“开一个开关”,而在于分层设计:路由层做租户识别与分流,策略层做资源约束与请求净化,响应层加安全头增强终端防护。两者可并行配置,互不干扰。
按域名实现租户逻辑隔离
这是最推荐的方式,语义清晰、配置独立、天然支持 SNI 证书分离:
- 每个租户分配唯一子域名(如 tenant-a.api.example.com),用正则 server_name 提取租户 ID:
server_name ~^(?[a-z0-9\-]+)\.api\.example\.com$; - 校验租户名合法性,拒绝非法字符(如点号、下划线、路径穿越符号),可用 map + return 实现:
map $tenant $valid_tenant { default 0; "~^[a-z0-9\-]{2,16}$" 1; }<br>if ($valid_tenant = 0) { return 400; } - 将租户上下文透传给后端:
proxy_set_header X-Tenant-ID $tenant;
同时为每个租户配置独立 access_log 路径,例如/var/log/nginx/tenant-a-access.log - 为每个 server 块单独定义限流 zone,避免租户间争抢:
limit_req_zone $binary_remote_addr zone=tenant_a:10m rate=100r/m;<br>limit_req zone=tenant_a burst=50 nodelay;
用路径或请求头辅助识别(适用统一入口)
当客户端无法改域名时,可用 location 前缀或自定义 header 补充识别:
- 路径前缀方式(如 /t/a/):
location ^~ /t/a/ {<br> rewrite ^/t/a/(.*)$ /$1 break;<br> proxy_pass https://tenant-a-backend;<br> proxy_set_header X-Tenant-ID "a";<br>} - Header 或参数识别需配合 map 预定义映射,禁用 if 嵌套:
map $http_x_tenant_id $backend {<br> default "default_backend";<br> "a" "tenant_a_backend";<br> "b" "tenant_b_backend";<br>}
非法值统一返回 400,不转发到后端 - 所有方式都必须记录实际识别出的租户 ID 到日志:
log_format tenant_log '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_tenant_id"';
防御 XSS 注入的 Nginx 层配置
Nginx 不解析 HTML 或执行 JS,所以不能“过滤脚本”,但可通过三类手段阻断典型 XSS 攻击链:
-
禁用浏览器旧式 XSS 过滤器(仅在你有完整服务端防护时启用):
add_header X-XSS-Protection "0";
注意:这不是“开启防护”,而是关闭不可靠的浏览器自动过滤,把控制权交还给你的应用层 -
强制启用现代内容安全策略(CSP),这才是真正有效的防护:
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https:; style-src 'self' 'unsafe-inline'; img-src * data:; frame-ancestors 'none';" always;
其中frame-ancestors 'none'同时防点击劫持 -
阻止可疑输入进入后端(轻量级兜底):
对 API 路径限制特殊字符:location ~ ^/api/ {<br> if ($args ~ "(<script return> if ($request_uri ~ "(<iframe|onerror=|eval\()") { return 400; }<br>}</script>
注意:该方式仅作补充,不能替代输出编码与 CSP
配套加固要点
隔离不只是“分得开”,更是“关得严”:
- 每个租户的 SSL 证书必须独立配置,泛域名证书需确认覆盖所有子域;
- 错误页统一重定向到租户专属 404/403 页面,避免泄露服务器信息;
- 禁用不必要 header:
server_tokens off;,隐藏 Nginx 版本; - 静态资源启用
X-Content-Type-Options: nosniff和X-Frame-Options: DENY; - 所有租户响应头中注入
X-Tenant-ID,便于后端审计与链路追踪。











