Nginx 常见配置误区
1.在location中使用root指令
好的习惯应该是在server 块中配置root指令
server { server_name www.domain.com; root /var/www/nginx-default/; location / { [...] } location /foo { [...] } location /bar { [...] }}
2.多个索引指令
好的习惯是在http块中使用一次index,为什么要使用多次呢
http { index index.php index.htm index.html; server { server_name www.domain.com; location / { [...] } } server { server_name domain.com; location / { [...] } location /foo { [...] } }}
3.使用if指令
错误的配置:
server { server_name domain.com *.domain.com; if ($host ~* ^www\.(.+)) { set $raw_domain $1; rewrite ^/(.*)$ $raw_domain/$1 permanent; [...] } }
此时的if指令强制检测所有域的每个请求,效率很低,可以使用两个server指令代替
正确的配置:
server { server_name www.domain.com; return 301 $scheme://domain.com$request_uri;} server { server_name domain.com; [...] }
4.检查文件存在
使用if检测文件存在是很糟糕的,你应该使用try_files
错误的配置:
server { root /var/www/domain.com; location / { if (!-f $request_filename) { break; } }}
正确的配置:
server { root /var/www/domain.com; location / { try_files $uri $uri/ /index.html; }}
5.传递不受控制的请求到php
错误的配置:
location ~* \.php$ { fastcgi_pass backend; ...}
这样的话,每个以php结尾的请求都会传递到php,默认的php配置将会猜测你请求的文件是否存在。
例如,一个请求类似/forum/avatar/1232.jpg/file.php
,这个文件不存在,但是/forum/avatar/1232.jpg
这个文件存在,那样php就会处理替换处理这个文件,如果这个文件中嵌入了php代码,php将会执行相应的代码。
可以通过以下的方法避免:
*.在php.ini中设置cgi.fix_pathinfo=0,这将使得php只处理请求的文件,如果文件不存在,则停止继续处理。
*.确保nginx只处理模式匹配的php文件
location ~* (file_a|file_b|file_c)\.php$ { fastcgi_pass backend; ...}
*.在指定用户上传的目录中禁止执行php文件
location /uploaddir { location ~ \.php$ {return 403;} ...}
*.使用try_files过滤不存在的页面
location ~* \.php$ { try_files $uri =404; fastcgi_pass backend; ...}
*.使用嵌套的location过滤有问题的页面
location ~* \.php$ { location ~ \..*/.*\.php$ {return 404;} fastcgi_pass backend; ...}
6.script filename中的fastcgi path
不要使用绝对root路径,使用变量
错误的配置:
fastcgi_param SCRIPT_FILENAME /var/www/yoursite.com/$fastcgi_script_name;
正确的配置:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
这里的$document_root 就是在server块中的root指令的值
7.重写相关
错误的配置:
rewrite ^/(.*)$ http://domain.com/$1 permanent;
rewrite ^ http://domain.com$request_uri? permanent;
正确的配置:不需要检测正则表达式,效率更高
return 301 http://domain.com$request_uri;
8.重写丢失http://
错误的配置:
rewrite ^/blog(/.*)$ blog.domain.com$1 permanent;
正确的配置:
rewrite ^/blog(/.*)$ http://blog.domain.com$1 permanent;
9.代理相关
错误的配置:所有页面彤彤传递给php
server { server_name example.org; root /var/www/site; location / { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/tmp/phpcgi.socket; }}
正确的配置:优先处理静态页面,然手交给php处理
server { server_name example.org; root /var/www/site; location / { try_files $uri $uri/ @proxy; } location @proxy { include fastcgi.conf; fastcgi_pass unix:/tmp/php-fpm.sock; }}
或
server { server_name example.org; root /var/www/site; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { include fastcgi.conf; fastcgi_pass unix:/tmp/php-fpm.sock; }}