分享
 
 
 

【nginx】常见的陷阱和错误

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: |||超大  

很多人都可以碰到一个陷阱。下面我们列出,我们经常看到的问题,以及解释如何解决这些问题。在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.phpindex.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 Ifif 是邪恶的 参见 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 EverythingBAD:

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:

InFirefoxpress 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、VirtualBoxIf 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 HeadersIf 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 LocationsSome 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 RootNGINX packages that exist inUbuntu, Debian, or otherOperating 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 AddressesBAD:

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/

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有