【nginx】常见的陷阱和错误
很多人都可以碰到一个陷阱。下面我们列出,我们经常看到的问题,以及解释如何解决这些问题。在Freenode上的#nginx IRC频道这些讨论很频繁。
1、权限
从来不要使用777权限,查看目录的权限
namei -om /path/to/check
2、root设置
BAD:
server {
server_name www.example.com;
location / {
root /var/www/nginx-default/;
# [...]
}
location /foo {
root /var/www/nginx-default/;
# [...]
}
location /bar {
root /var/www/nginx-default/;
# [...]
}
}
GOOD:
server {
server_name www.example.com;
root /var/www/nginx-default/;
location / {
# [...]
}
location /foo {
# [...]
}
location /bar {
# [...]
}
}
3、索引设置
BAD:
http {
index index.php index.htm index.html;
server {
server_name www.example.com;
location / {
index index.php index.htm index.html;
# [...]
}
}
server {
server_name example.com;
location / {
index index.php index.htm index.html;
# [...]
}
location /foo {
index index.php;
# [...]
}
}
}
GOOD:
http {
index index.php index.htm index.html;
server {
server_name www.example.com;
location / {
# [...]
}
}
server {
server_name example.com;
location / {
# [...]
}
location /foo {
# [...]
}
}
}
4、Using If
if 是邪恶的 参见 If Is Evil
5、Server Name (If)
BAD:
server {
server_name example.com *.example.com;
if ($host ~* ^www\.(.+)) {
set $raw_domain $1;
rewrite ^/(.*)$ $raw_domain/$1 permanent;
}
# [...]
}
}
每次都要检测主机头,这是低效的,你应该避免,推荐使用下面的
GOOD:
server {
server_name www.example.com;
return 301 $scheme://example.com$request_uri;
}
server {
server_name example.com;
# [...]
}
这样方式便于阅读,降低了nginx的处理要求,而且也避免了硬编码(http or https)
6、Check (If) File Exists
使用if来判断是可怕的,你应该使用 try_files
BAD:
server {
root /var/www/example.com;
location / {
if (!-f $request_filename) {
break;
}
}
}
GOOD:
server {
root /var/www/example.com;
location / {
try_files $uri $uri/ /index.html;
}
}
try_files 意味着你测试一个队列 $uri => $uri/ => index.html,这种方法简单,而且可以避免if
7、Web Apps中的控制器
Drupal, Joomla, etc. to work, just use this:
try_files $uri $uri/ /index.php?q=$uri&$args;
Note - the parameter names are different based on the package you’re using. For example:
- “q” is the parameter used by Drupal, Joomla, WordPress
- “page” is used by CMS Made Simple
一些软件不需要 query string, 可以读取 REQUEST_URI (例如,WordPress):
try_files $uri $uri/ /index.php;
如果你不关心目录是否存在,你可以移除 $uri/
8、Passing Uncontrolled Requests to PHP
很多PHP网站中,配置nginx的例子中建议使用 .php (to the PHP interpretet)作为uri的结尾,这例有一个严重的安全问题对于大多数PHP程序,因为它可能允许执行任何第三方代码
The problem section usually looks like this:
location ~* \.php$ {
fastcgi_pass backend;
# [...]
}
Here, every request ending in .php will be passed to the FastCGI backend. The issue with this is that the default PHP configuration tries to guess which file you want to execute if the full path does not lead to an actual file on the filesystem.
For instance, if a request is made for /forum/avatar/1232.jpg/file.php which does not exist but if/forum/avatar/1232.jpg does, the PHP interpreter will process /forum/avatar/1232.jpg instead. If this contains embedded PHP code, this code will be executed accordingly.
Options for avoiding this are:
- Set cgi.fix_pathinfo=0 in php.ini. This causes the PHP interpreter to only try the literal path given and to stop processing if the file is not found.
- Ensure that NGINX only passes specific PHP files for execution:
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 ~* \.php$ {
location ~ \..*/.*\.php$ {return 404;}
fastcgi_pass backend;
# [...]
}
9、FastCGI Path in Script Filename
尽量使用 include fastcgi_params 中的变量,不管什么语言都是一样
GOOD:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
BAD:
fastcgi_param SCRIPT_FILENAME /var/www/yoursite.com/$fastcgi_script_name;
10、Taxing Rewrites
我们应该努力让他们保持整洁。很简单,不添加冗余代码。
BAD:
rewrite ^/(.*)$ http://example.com/$1 permanent;
GOOD:
rewrite ^ http://example.com$request_uri? permanent;
BETTER:
return 301 http://example.com$request_uri;
通过使用内置的变量$ REQUEST_URI,我们可以有效地避免做任何捕获或匹配的。
11、Rewrite Missing http://
很简单,除非你告诉NGINX他们不是重写是相对的。一个重写绝对很简单。添加一个scheme
BAD:
rewrite ^ example.com permanent;
GOOD:
rewrite ^ http://example.com permanent;
添加 http://
到重写规则内,简单,高效
12、Proxy Everything
BAD:
server {
server_name _;
root /var/www/site;
location / {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/tmp/phpcgi.socket;
}
}
Yucky. In this instance, you pass EVERYTHING to PHP. Why? Apache might do this, you don’t need to. Let me put it this way... The try_files directive exists for an amazing reason. It tries files in a specific order. This means that NGINX can first try to server the static content. If it can’t, then it moves on. This means PHP doesn’t get involved at all. MUCH faster. Especially if you’re serving a 1MB image over PHP a few thousand times versus serving it directly. Let’s take a look at how to do that.
GOOD:
server {
server_name _;
root /var/www/site;
location / {
try_files $uri $uri/ @proxy;
}
location @proxy {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/tmp/phpcgi.socket;
}
}
Also GOOD:
server {
server_name _;
root /var/www/site;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/tmp/phpcgi.socket;
}
}
It’s easy, right? You see if the requested URI exists and can be served by NGINX. If not, is it a directory that can be served. If not, then you pass it to your proxy. Only when NGINX can’t serve that requested URI directly does your proxy overhead get involved.
Now.. consider how much of your requests are static content, such as images, css, javascript, etc. That’s probably a lot of overhead you just saved.
12、Config Changes Not Reflected
Browser cache. Your configuration may be perfect but you’ll sit there and beat your head against a cement wall for a month. What’s wrong is your browser cache. When you download something, your browser stores it. It also stores how that file was served. If you are playing with a types{} block you’ll encounter this.
The fix:
- In Firefox press Ctrl+Shift+Delete, check Cache, click Clear Now. In any other browser just ask your favorite search engine. Do this after every change (unless you know it’s not needed) and you’ll save yourself a lot of headaches.
- Use curl.
13、VirtualBox
If this does not work, and you’re running NGINX on a virtual machine in VirtualBox, it may be sendfile() that is causing the trouble. Simply comment out the sendfile directive or set it to “off”. The directive is most likely found in your nginx.conf file.:
sendfile off;
13、Missing (disappearing) HTTP Headers
If you do not explicitly set underscores_in_headers on, NGINX will silently drop HTTP headers with underscores (which are perfectly valid according to the HTTP standard). This is done in order to prevent ambiguities when mapping headers to CGI variables as both dashes and underscores are mapped to underscores during that process.
14、Not Using Standard Document Root Locations
Some directories in any file system should never be used for hosting data from. Some of these include /
androot
. You should never use these as your document root.
Doing this leaves you open to a request outside of your expected area returning private data.
NEVER DO THIS!!! (yes, we have seen this)
server {
root /; location / {
try_files /web/$uri $uri @php;
} location @php {
[...]
}
}
When a request is made for /foo, the request is passed to php because the file isn’t found. This can appear fine, until a request in made for /etc/passwd. Yup, you just gave us a list of all users on that server. In some cases, the NGINX server is even set up run workers as root. Yup, we now have your user list as well as password hashes and how they’ve been hashed. We now own your box.
The Filesystem Hierarchy Standard defines where data should exist. You should definitely read it. The short version is that you want your web content to exist in either /var/www/
, /srv
, /usr/share/www
.
15、Using the Default Document Root
NGINX packages that exist in Ubuntu, Debian, or other operating systems, as an easy-to-install package will often provide a ‘default’ configuration file as an example of configuration methods, and will often include a document root to hold a basic HTML file.
Most of these packaging systems do not check to see if files are modified or exist within the default document root, which can result in code loss when the packages are upgraded. Experienced system administrators know that there is no expectation of the data inside the default document root to remain untouched during upgrades.
You should not use the default document root for any site-critical files. There is no expectation that the default document root will be left untouched by the system and there is an extremely high possibility that your site-critical data may be lost upon updates and upgrades to the NGINX packages for your operating system.
16、Using a Hostname to Resolve Addresses
BAD:
upstream {
server http://someserver;
} server {
listen myhostname:80;
# [...]
}
You should never use a hostname in a listen directive. While this may work, it will come with a large number of issues. One such issue being that the hostname may not resolve at boot time or during a service restart. This can cause NGINX to be unable to bind to the desired TCP socket which will prevent NGINX from starting at all.
A safer practice is to know the IP address that needs to be bound to and use that address instead of the hostname. This prevents NGINX from needing to look up the address and removes dependencies on external and internal resolvers.
This same issue applies to upstream locations. While it may not always be possible to avoid using a hostname in an upstream block, it is bad practice and will require careful considerations to prevent issues.
GOOD:
upstream {
server http://10.48.41.12;
} server {
listen 127.0.0.16:80;
# [...]
}
17、Using SSLv3 with HTTPS
由于SSLv3的POODLE 漏洞,建议使用在SSL网站禁用,仅仅使用TLS协议代替
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
原文:https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
【nginx】常见的陷阱和错误的更多相关文章
- nginx常见内部参数,错误总结
1.日志简介 nginx日志主要有两种:访问日志和错误日志.访问日志主要记录客户端访问nginx的每一个请求,格式可以自定义:错误日志主要记录客户端访问nginx出错时的日志,格式不支持自定义.两种日 ...
- Nginx常见错误与问题之解决方法技术指南
Nginx常见错误与问题之解决方法技术指南. 安装环境: 系统环境:redhat enterprise 6.5 64bit 1.Nginx 常见启动错误 有的时候初次安装nginx的时候会报这样的 ...
- Java 中最常见的 5 个错误
在编程时,开发者经常会遭遇各式各样莫名错误.近日,Sushil Das 在 Geek On Java上列举了 Java 开发中常见的 5 个错误,与君共「免」. 原文链接:Top 5 Common M ...
- Nginx详解二十五:Nginx架构篇之Nginx常见的问题
Nginx常见的问题 1.相同server_name多个虚拟主机优先级访问,是按读取文件的优先级来排序 在/opt/app/下准备3个code文件夹,下面放入3个html文件,里面的内容分别是code ...
- Nginx常见的安装方式
Nginx常见的安装方式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Nginx概述 Nginx的安装版本分为开发版.稳定版和过期版, Nginx安装可以使用yum或源码安装 ...
- Nginx提示502和504错误的解决方案
一.错误提示说明: Nginx 502 Bad Gateway的含义是请求的PHP-CGI已经执行,但是由于某种原因(一般是读取资源的问题)没有执行完毕而导致PHP-CGI进程终止. Nginx 50 ...
- mysql 常见的几个错误问题
Mysql常见的几个错误问题及解决方法: 1.问题: mysql DNS反解:skip-name-resolve 错误日志有类似警告: 点击(此处)折叠或打开 120119 16:26:04 [War ...
- SEO中最常见的几个错误
昨天答应给放点干活的,今天如约而来! SEO中最常见的几个错误: 1.关键词 人们往往想当然的选择自己喜欢的keyword,但用户在搜索时,根本不会使用它们.比方说,你选择"优化果酱&q ...
- Nginx的500,502,504错误解决方法
Nginx的500,502,504错误解决方法 一.解决500错误: 1.500错误指的是服务器内部错误,也就是服务器遇到意外情况,而无法履行请求. 2.500错误一般有几种情况: (1)web脚本错 ...
随机推荐
- nginx的部署与发布
1.在http://nginx.org/en/download.html下载nginx.tar.gz包. 2.上传发送到服务器(wcp工具) 3.用tar -xf命令解压gz包 4.[配置安装变量]: ...
- C++中指针常量和常量指针的区别
在C++学习使用过程中,每个人都不可避免地使用指针,而且都或多或少的接触过常量指针或指针常量,但是对这两个的概念还是很容易搞糊涂的. 本文即是简单描述指针常量和常量指针的区别. 常量指针 定义: 又叫 ...
- CentOS6.5菜鸟之旅:关于搜索的shell命令
一.locate命令 用于模糊搜索文件(目录)的绝对路径. 示例1: // 凡是绝对路径当中含jdk字符串的文件(目录)均被搜索出来 fsjohnhuang@fsjohnhuang~# locate ...
- 汇编学习:float与double速度问题
X86处理器包含两种类型的浮点数寄存器.第一种使用8个浮点寄存器组成浮点寄存器栈,另一种为向量寄存器(XMM,YMM),它们对于单双精度的处理是不同的.本文将讨论两种模式下的浮点数计算速度问题. 一. ...
- 2016年5月11日摘自知乎的一些Redis大概了解
1. 知乎日报的基础数据和统计信息是用 Redis 存储的,这使得请求的平均响应时间能在 10ms 以下.其他数据仍然需要存放在另外的地方,其实完全用 Redis 也是可行的,主要的考量是内存占用.就 ...
- 改变Visual Studio 2012的皮肤
习惯了用vs的绿色背景,vs2012有自己的主题管理工具--Theme Editor vs2012默认没有安装Theme Editor,菜单:工具->扩展和更新,搜索栏里面输入Theme Edi ...
- JS实现注销功能
JS实现注销功能,代码如下: <script> window.history.forward(1); </script> 这个代码的用法就是: 比如,我们此时有两个页面:Log ...
- ahjesus根据身份证号码获取相关信息(生日,省市县,性别)
使用说明: //出自http://www.cnblogs.com/ahjesus 尊重作者辛苦劳动成果,转载请注明出处,谢谢! var idCard = new IdCard();var msg = ...
- ASP.NET Core1.0 带来的新特性
1.采用新的文件系统,不再通过工程文件(.sln和.csproj)来定义项目文件清单. 解决方案文件还是*.sln,但项目文件变成*.xproj了.在项目文件夹下新增的文件会被自动添加到项目中,不用再 ...
- ArrayList等常见集合的排序问题
对于ArrayList等常用的集合具体业务类,基本上都实现了Comparable接口,即可以用来比较装载的对象实体. 主要用Collections.sort方法对集合类中的对象进行排序 Collect ...