Nginx location指令
2013-05-10 by dongnan
举个栗子
来看一个location
配置示例:
server {
#... 其它配置项省略
# 匹配正则
location ~* /(fashion|life|men)/pic/ {
rewrite ^/ http://blog.test.com/ permanent;
}
# 匹配字符串
location ^~ /fashion/pic/ {
proxy_pass http://blog.test.com/;
}
}
测试结果:
curl -IL http://192.168.57.75/fashion/pic/
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 14 Aug 2012 07:56:10 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
Vary: Accept-Encoding
X-Powered-By: PHP/5.3.6
X-Pingback: http://blog.test.com/xmlrpc.php
从配置文件看这两个 location
都能匹配/fashion/pic/
,不同的是前者使用的是正则匹配,而后者是字符串匹配。
- 这里涉及到匹配顺序问题,从服务器返回的结果可以知道
nginx
选择了匹配字符串, - 这是因为使用了
^~
标识符字符串匹配后不再检查正则,也就是只使用字符串匹配结果。
location 指令
语法:location [=|^~|~|~*|@] /uri/ { … }
默认值:no
使用字段:server
功能: 根据URI的不同需求进行配置,可以使用字符串与正则表达式匹配。
如果要使用正则表达式,你必须指定下列前缀:
~* 不区分大小写。
~ 区分大小写。
匹配规则
要确定该指令匹配特定的查询,程序将首先对字符串进行匹配,字符串匹配将作为查询的开始,最确切的匹配将被使用。 然后正则表达式的匹配查询开始,匹配查询的第一个正则表达式找到后会停止搜索,如果没有找到正则表达式,将使用字符串的搜索结果。
- 可以使用
^~
标记禁止在字符串匹配后检查正则表达式,如果最确切的匹配location有这个标记,那么正则表达式不会被检查。 - 使用
=
标记可以在URI和location之间定义精确的匹配,在精确匹配完成后并不进行额外的搜索,例如有请求/
发生,则可以使用location = /
来加速这个处理。 - 即使没有
=
和^~
标记,精确的匹配location在找到后同样会停止查询。
匹配顺序
- 前缀
=
表示精确匹配查询,如果找到立即停止查询。 - 使用标准字符串,如果匹配到使用
^~
前缀则停止查询。 - 正则表达式按照他们在配置文件中定义的顺序。
- 如果第三条产生一个匹配,这个匹配将被使用,否则将使用第二条的匹配。
匹配示例
location = / {
# 只匹配 / 的查询.
[ configuration A ]
}
location / {
# 匹配任何以 / 开始的查询,但是正则表达式与一些较长的字符串将被首先匹配。
[ configuration B ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 开始的查询并且停止搜索,不检查正则表达式。
[ configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配任何以gif, jpg, or jpeg结尾的文件,但是所有 /images/ 目录的请求将在Configuration C中处理。
[ configuration D ]
}
各请求的处理如下例:
/
-> configuration A/documents/document.html
-> configuration B/images/1.gif
-> configuration C/documents/1.jpg
-> configuration D
注意,你可以以任何顺序定义这4个配置并且匹配结果是相同的,但当使用嵌套的location
结构时可能会意外的结果。
常用的location
PHP-FPM + Nginx
服务器:
server {
#... 其它配置项省略
# 使用正则匹配
location ~ .*\.(php|php5)?$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# 使用正则匹配
location ~ \.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 30d;
}
# 使用正则匹配
location ~ \.(js|css|htm|html|shtml)$ {
expires 60m;
}
# 使用字符串+正则匹配
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://www.test.com/images/;
}
# 使用字符串匹配不再检查正则
location ^~ /bao/m/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://m.bao.test.com/images/;
}
}
仅匹配字符串不匹配正则表达式
图片由php
程序输出,直接访问nginx
中的图片返回404
状态。
配置文件
location ^~ /upload/ {
return 404;
}
使用^~
标记禁止在字符串匹配后检查正则表达式,如果最确切的匹配location
有这个标记,那么正则表达式不会被检查。
验证
跳转到404
页面:
curl -IL -k -H "Host:trade.ywwd.net" https://server_ip/upload/qiyepack/000/00/00/06/zzjgz.jpg
HTTP/1.1 302 Found
Date: Wed, 16 Dec 2015 08:20:02 GMT
Content-Type: text/html
Content-Length: 235
Location: https://ywwd.net/404.html
程序生成的图片
URL:https://trade.ywwd.net/XXX/qyzzimg?path=qiyepack/000/00/00/06/yyzz.jpg
这种方式可能带来权限控制问题,造成的平行越权漏洞,导致信息泄露,例如:
/qyzzimg?path=../../../../../../../etc/passwd
解决方法是需要判断 path=something...
传递的参数是否合法。