上一篇:工作必备:git综合手札(2019-03-17 22:47:58)
文章大纲

nginx location配置踩坑详细记录

2019年07月05日 23:21
这周前四天被nginx配置差不多快搞死了,总是nginx -s reload操作后配置不生效或者被浏览器的缓存影响,如此一来,每改一段配置,都得反反复复在配置里调试确定是否进入,浏览器缓存也是禁用、清除、开启私有窗口各种尝试反反复复的进行,确保影响正确的判断。

在此期间,也难得踩了很多坑,为日后方便温习,也方便分享给大家,先徒手记载下来。
由于是徒手写的,所以配置代码不是很可靠,仅仅只是提供下解决思路而已,望大家注意甄别。

1. 网站访问跳到404页面,返回值返回的是301,302,需求是也要返回404.

起初关于404的页面,我的配置如下:
error_page 404 @404page
location @404page {
    rewrite .* http://domain/404.html?
}
上面rewrite后带问号,是遇到跳转到404页面,url里404.html之后还含有多余部分,类如:
http://domain/404.html?data/goods.php
需要返回值是404,不要用上面名称定义的location,后面改成如下就ok了。
error_page 404  /404.html

2. 防止项目文件结构被人爬出来,现需求提出不区分403和404,统一展示给用户的是404页面。

直接在server块下,加下面这一行代码就ok了。
error_page 403=404  /404.html

3.为网站后台配置权限,只允许指定ip可以访问,却出现配置不生效的情形。

我配置过两种类型的网站,其中一种后台入口不是index.php的是ok的,不正常的是index.php入口这个。
先来看看我的配置:
index  index.html index.htm index.php 
#locationA
location ~ /(index|homepage|start)\.php {
    allow all;
    fastcgi_pass 127.0.0.1:9001;
    fastcgi_index index.php;
    include fastcgi.conf;
}
#locationB
location ~ /(admin|mbadmin)\/.*\.php {
    allow 128.78.89.34;
    deny all;
fastcgi_pass 127.0.0.1:9001;
    fastcgi_index index.php;
    include fastcgi.conf;
}
通过http://domain/admin/index.php访问网站后台时,由于会匹配locationA,从而导致不再进入locationB。
这样,在locationB配置的权限当然就没生效了。

后面对locationA的正则表达式稍加修改就ok了。
默认访问网站和访问网站后台,都走index.php时,区别就是后台路径的index.php前面会匹配斜杠。(本人是实践过才下这结论的)
#locationA
location ~ /[^\/](index|homepage|start)\.php {
    ...
}
改动就在正则表达式的开头之处,[^\/]表示非斜杠开头。
这样http://domain/admin/index.php就会进不去locationA,而走locationB了。

4. 当用户查看某些网站不存在的页面时,希望做一些特殊处理操作。

比如路径带有movie关键词,尽管我的网站没有相关页面,但我可以展示豆瓣的电影榜单页面。
如果项目用的比较流行的php框架,像thinkphp,laravel,ci,slim,phalcon诸如此类的,那处理操作大可放在中间件middleware或controller基类构造方法里就好了。
这里我想说的是,文件不存在时,让其走index.php入口,这样处理操作就可以写在index.php里了。
加上如下代码判断即可:
server {
    if( !-e $request_filename ){
        rewrite ^(.*)$ http://domain/index.php?$1
    }
}

5. 网站项目某个文件夹data,禁止所有人访问,对于已的存在文件会返回404,可是不存在的文件,会进入到index.php。

此情景是基于第4条发生的。
开始我的配置关于data部分:
location ~ /data {
    return 404;
}
如此一来,访问data下不存在的文件,根据第4条情景就会rewrite路径,从而带上index.php,导致无法匹配上面/data的配置了。
解决方法如下:
location ~ /(index|homepage|start)\.php {
if( $request_filename ~ data ){
        return 404;
    }
    allow all;
    fastcgi_pass 127.0.0.1:9001;
    fastcgi_index index.php;
    include fastcgi.conf;
}

6. 访问网站php文件,居然出现下载的情况。

这个问题很严重,一旦php文件被下载,就相当于服务器代码被人看到了,很容易被一些骇客加以利用。
出现下载的原因,是nginx配置里没有一个location能够匹配得上。
所以,为了安全,我们要加一个正则的配置,放在配置文件最底部,就像层层滤网下再放一个盆子,不遗漏任何一个php文件。
location ~ /.*\/.*\.php {
    allow all;
fastcgi_pass 127.0.0.1:9001;
......
}

7. 网站样式居然不见了。

我遇到这种情形,是因为配置问题,导致样式资源请求进入了php解析相关的配置(指的就是还有fastcgi的location块)。
方法一:
css、图片这些静态资源,其实是无需php解析的,所以可以在php相关location配置前,加上css、图片相关的配置。(不用正则的话,放在后面也可以,因为正则优先级低于非正则的)
大概如下:
location ~  .*\.css {
}
location ~ .*\.(png|jpeg|gif|jpg|swf|bmp) {
}
方法二:
除了这种防止静态资源进入php解析的方法外,也可以修改php-fpm配置,使其解析支持这些静态资源类型。
这里样式不见了,查看nginx错误日志,有如下提示:
Access denied (403) see security.limit_extensions
而php-fpm的配置文件里正好有这个配置,类型只有php,我们把静态资源类型加进去,重启php-fpm就ok了。
security.limit_extensions = .php .php3 .php4 .php5 .html .js .css .jpg .jpeg .gif .png .htm
不过从职责原则来看,我个人还是倾向方法一,php-fpm就只让它管php吧。

如果不是上面提到的原因,那就是网上贴的比较多的,在配置文件server块下加上如下部分:
include /etc/nginx/mime.types;
default_type application/octet-stream;

以上内容,昨天徒手也写了一次的,奈何最后手一抖,竟然全没了,骂了好几次操蛋,没办法还是冷静下来了。
其实后台发布之前就已经实现每隔5分钟存redis并写库来避免这种情况了,不过有个缺点是针对的是已经存在id的文章(就是先新增保存空内容,后编辑)。
昨天一心血来潮,一下子全给写完了,还在新增的编辑框里,结果鼠标复制不好使,一划拉滑倒其它链接上了,然后,然后,就无语了。
发布功能也是自己做的,自己把自己坑了,怨不得别人了。




  • 2019年07月05日 21:45文章创建
  • 2019年07月05日 23:21文章发布
上一篇:工作必备:git综合手札(2019-03-17 22:47:58)
我要评论
评论列表
暂无评论,期待你的评论哦!
回到顶部