Nginx配置带路径变量的Alias以提供静态文件的问题
Nginx配置带路径变量的Alias以提供静态文件的问题
我之前也碰到过类似的Nginx配置坑,带变量的alias确实有特殊的处理逻辑,而且还要兼顾安全防目录遍历,给你整理两个可行的解决思路:
首先得说清问题核心:当alias路径里包含变量(比如你的$map_user)时,Nginx对正则捕获(像$1)的处理逻辑和纯静态路径完全不一样,而且如果不对变量做校验,很容易被钻空子搞目录遍历。
方案一:用root配合rewrite(更推荐)
root的处理逻辑刚好适配你的场景:它会把root指定的路径,拼接上去掉location匹配前缀后的URI。同时一定要先给$map_user做安全校验:
location ~ ^/images/(.*\.(jpg|jpeg))$ { # 未登录的话直接拒绝,防止$map_user为空导致路径错误 if ($map_user = "") { return 403 Forbidden; } # 限制$map_user只能是合法字符,彻底阻断目录遍历的可能 if ($map_user !~ ^[a-zA-Z0-9_-]+$) { return 403 Forbidden; } # 指定当前用户的文件根目录 root /www/foo/$map_user; # 去掉URI里的/images/前缀,让Nginx到用户目录下找对应文件 rewrite ^/images/(.*)$ /$1 break; }
方案二:修正alias的写法
如果你坚持要用alias,得调整路径写法,同样不能少安全校验:
location ~ ^/images/(.*\.(jpg|jpeg))$ { if ($map_user = "") { return 403 Forbidden; } if ($map_user !~ ^[a-zA-Z0-9_-]+$) { return 403 Forbidden; } # 带变量的alias要明确拼接捕获的文件路径 alias /www/foo/$map_user/$1; # 强制关闭目录索引,防止用户浏览目录结构 autoindex off; }
额外的安全提醒
- 一定要确保
$map_user是通过map或者认证模块(比如auth_request)生成的安全变量,绝对不能让用户通过请求参数直接控制这个变量的值。 - 给每个用户的目录设置严格的权限:Nginx运行的系统用户(比如
www-data)只能读取当前用户的目录,完全禁止访问其他用户的目录。
这么配置后,用户访问/images/xxx.jpg时,Nginx会自动到/www/foo/[当前登录用户]/xxx.jpg找文件,未登录、变量非法的请求都会直接被拒绝,完全不用担心用户猜其他用户的目录。
备注:内容来源于stack exchange,提问作者P Stiffell




