nginx 中 rewrite 不直接拒绝访问,应结合 return、if 或 map 实现;推荐用 return 返回 403/302,map 适合复杂规则,error_page 统一处理拒绝页面。

在 Nginx 中,rewrite 指令本身不直接“拒绝访问”,它主要用于 URL 重写或重定向。若需动态跳转并同时拒绝某些请求,应结合 return、if(谨慎使用)或 map 指令实现逻辑判断与响应控制。单纯靠 rewrite 无法安全、可靠地完成“拒绝访问”动作,容易误跳或绕过限制。
用 return 配合条件判断实现拒绝跳转
更推荐的方式是:先通过变量或匹配识别非法请求,再用 return 直接返回状态码(如 403、404)或跳转到提示页。这种方式高效、语义明确,且避免 rewrite 的隐式循环风险。
- 禁止特定 User-Agent 访问并跳转到友好提示页:
if ($http_user_agent ~* "sqlmap|nikto|wget") { return 302 /blocked.html; } - 对恶意路径参数返回 403:
if ($args ~* "(?:%3C|%3E||javascript:|base64)") { return 403; }
用 map 构建动态拒绝规则(推荐用于复杂场景)
map 指令在全局块中定义变量映射关系,性能好、可读性强,适合基于域名、路径前缀、请求头等做多条件判断。
- 定义一个拒绝标志变量:
map $uri $deny_flag { default 0; ~^/admin/.+ 1; ~^/wp-admin 1; ~\.(php|exe|bat)$ 1; } - 在 server 块中应用:
if ($deny_flag) { return 403 "Access denied."; }
慎用 rewrite + break 实现“伪拒绝跳转”
虽然可用 rewrite ... last/break 将请求内部重定向到一个空 location 并返回错误,但逻辑绕弯、调试困难,且易引发重复执行或循环。仅在极少数兼容旧配置时考虑。
- 示例(不推荐但可理解原理):
location /forbidden/ { rewrite ^/forbidden/(.*)$ /_deny_ last; } location = /_deny_ { return 403; } - 注意:
last会重新匹配 location,break不会;两者均不等价于拒绝,只是间接跳转。
替代方案:用 error_page 统一处理拒绝响应
将拒绝逻辑与响应页面解耦,提升可维护性。例如所有 403 请求统一返回自定义页面:
- 配置自定义错误页:
error_page 403 /403.html; location = /403.html { internal; root /usr/share/nginx/html; } - 配合前面的
return 403或deny指令,即可呈现统一拒绝页面。











