LNMP架构(四)

一 Nginx防盗链

1、修改虚拟主机配置文件

    # vim /usr/local/nginx/conf/vhost/test.com.conf

    在配置文件中加入以下内容,这里的内容是和静态元素过期时间、不记录日志结合起来的:

location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)$   //^表示以……开头,

{

    expires 7d;

    valid_referers none blocked server_names  *.test.com ;  //referer白名单

    if ($invalid_referer) {    //如果不是白名单中的referer,就返回403

        return 403;

    }

    access_log off;

}

2、测试语法错误并重新加载配置文件

    # /usr/local/nginx/sbin/nginx -t
    # /usr/local/nginx/sbin/nginx -s reload

3、测试验证

    当referer是白名单以外的链接时,就会被禁止访问

    # curl -e "http://www.baidu.com" -x127.0.0.1:80 test.com/1.gif -I

    当referer是白名单上的链接时,就会访问成功

    # curl -e "http://test.com" -x127.0.0.1:80 test.com/1.gif -I

二 Nginx访问控制

1、配置IP白名单

    编辑虚拟主机配置文件/usr/local/nginx/conf/vhost/test.com.conf,加入以下内容:

    locaton /admin/         //针对目录做访问控制
    {
        allow 192.168.31.157;  //注意配置白名单需要先允许,再deny
        allow 127.0.0.1;
        deny all;

    }
    不同于apache中的order ,先拒绝所有访问,再开启白名单,并且是顺序执行完所有代码;在nginx中,是没有order的,执行语句时候,只要匹配到访问的IP,则不会执行后面的语句,因此需要将allow写在前面,deny写在后面

2、检查语法错误并重新加载配置文件

    # /usr/local/nginx/sbin/nginx  -t

    # /usr/local/nginx/sbin/nginx -s reload

3、测试验证

    # curl -x192.168.31.157:80 -I test.com/admin/1.php

    # curl -x127.0.0.1:80 -I test.com/admin/1.php

    如果来源IP不在白名单内,则会出现403禁止访问

4、访问控制-正则匹配

    匹配正则表达式来进行访问控制允许访问或者拒绝访问

    比如可以在虚拟主机配置文件中加入以下内容,表示禁止上传文件或图片解析php

    location ~ .*(upload|image)/.*\.php$     //匹配upload或image目录下以php结尾的文件
    {
        deny all;   //拒绝访问
    }

    检查语法并加载配置文件后,我们来访问upload下的php文件test.com/upload/1.php提示禁止访问

    接下来访问upload下的txt文件test.com/upload/1.txt则访问OK

5、根据user_agent限制访问

    在虚拟主机配置文件中加入以下代码:

if ($http_user_agent ~ 'Spider/3.0|YoudaoBot|Tomato')    //表示匹配到user_agent包含Spider/3.0|YoudaoBot|Tomato中任意一个就拒绝访问

{      

    return 403;   //deny all和return 403效果一样

}

    现在来访问test.com/upload/1.txt  是能够成功访问的

    接下来模拟用户代理Tomatodsewre,因为匹配到Tomato,所有服务器拒绝访问

# curl -A "Tomatodsewre" -x127.0.0.1:80 -I test.com/upload/1.txt

但是下图中当我们模拟用户代理tomatodsewre,首字母由大小变成小写后,访问成功了,这说明我们当前的配置是对大小敏感的

# curl -A "tomatodsewre" -x127.0.0.1:80 -I test.com/upload/1.txt

    此时我们只需要在匹配符号~后面加上*号即可表示忽略大小写,如下

    加上*后,我们再来访问test.com/upload/1.txt就会提示禁止访问了

三 Nginx解析php相关配置

1、  编辑虚拟主机配置文件

    在虚拟主机配置文件中加入以下内容:

location ~ \.php$    

{        

    include fastcgi_params;        

    fastcgi_pass unix:/tmp/php-fcgi.sock;        

    fastcgi_index index.php;        

    fastcgi_param SCRIPT_FILENAME /data/wwwroot/test.com$fastcgi_script_name;    

}

    在重新加载配置文件前,我们先来测试访问一个页面3.php,文件内容如下

    下面我们来访问这个页面,访问结果出现的是3.php文件的内容,并未解析这个php文件

    # curl -x127.0.0.1:80 test.com/3.php

2、检测语法并重新加载配置文件

    # /usr/local/nginx/sbin/nginx  -t

    # /usr/local/nginx/sbin/nginx -s reload

3、测试验证

    现在我们再来访问3.php这个页面,文件里面的php语句被解析

    # curl -x127.0.0.1:80 test.com/3.php

4、502状态码

    当配置文件中fastcgi_pass unix:/tmp/php-fcgi.sock;   这一行配置的路径/tmp/php-fcgi.sock写错了,就会出现502错误,我们来将路径改成下面的错误路径

    然后来测试访问# curl -x127.0.0.1:80 test.com/3.php  就出现下面的502

当我们遇到502错误的时候,可以从几个方面来分析:

    1)我们来查看错误日志# tail /usr/local/nginx/logs/nginx_error.log

    提示说没有/tmp/php-cgi.sock这个目录或文件,我们# ls /tmp/php-cgi.sock 发现确实没有这个文件

    这时候我们就需要去php-fpm的配置文件中去查看php-fpm监听的这个socket的路径跟上面nginx配置文件中的路径作一个对比,发现nginx配置文件中的路径写错了

    这点总结起来就是:php-fpm配置文件中监听的socket路径是什么,nginx配置文件中的fastcgi_pass路径就应该写什么

    2)实验:首先php-fpm配置文件配置监听IP和端口,如下

    然后重启php-fpm

    # /etc/init.d/php-fpm reload

    此时我们可以看到127.0.0.1:9000已经被监听

    我们再来访问# curl -x127.0.0.1:80 test.com/3.php

    再来查看错误日志# tail /usr/local/nginx/logs/nginx_error.log

    出现这个错误的原因是nginx的配置文件还没有修改为IP+端口的形式,需要修改为下图

    重新加载配置文件后,我们再来查看访问结果,结果是成功访问到了

    总结:这点总结起来就是如果php-fpm配置文件使用的是IP+端口的形式,那么nginx配置文件中也应该使用同样的形式

    3)出现502错误还应该检查的一个地方是nginx配置文件下图中的路径

    

    应该对应下面这个图的路径

    4)在php5.4及以后的版本,有一个特点,就是如果我们在php-fpm配置文件中监听的是socket,而又不定义listen.mode的话,那么/tmp/php-fcgi.sock文件的权限就会变成440

    我们将配置文件修改为如下形式:

    重新加载配置文件后,再来查看/tmp/php-fcgi.sock的文件权限,可以看到其权限是440,所属组和所属主都是root用户

    然后将nginx的配置文件配置为socket,

    再来访问# curl -x127.0.0.1:80 test.com/3.php 结果还是502报错

    我们通过查看错误日志,可以看到502错误原因是因为权限被拒绝,

    上面我们提到/tmp/php-fcgi.sock的文件权限是440,所属组和所属主都是root用户,但是下面这个图显示nginx的进程的所属主和所属组都是nobody

    我们来测试下临时将/tmp/php-fcgi.sock的所属主和所属组改为nobody

    # chown nobody /tmp/php-fcgi.sock

    然后再来访问# curl -x127.0.0.1:80 test.com/3.php,结果访问成功,这是因为此时nobody用户有读写的权限了

    5)还有一种502错误的情况是php-fpm服务的资源耗尽了,比如有一个mysql查询卡死了,php-fpm的资源耗尽了,这个时候就需要去优化了

    以上修改过php-fpm的配置文件后需要restart  php-fpm服务

四 Nginx代理

    使用场景:a.用户不能直接访问到web服务器的网络

                     b.用户虽然能直接访问web服务器,但是网络太慢

    代理服务器特点:既能与用户通信,又能与web服务器通信

    这里我们尝试将自己的虚拟服务器配置为代理服务器,然后使用虚拟服务器内部的回环IP127.0.0.1来访问外部的网站www.cxkchina.com/robots.txt,内部的回环IP127.0.0.1原本是不能访问外网的

1、切换目录

        # cd /usr/local/nginx/conf/vhost/

2、新增虚拟主机配置文件

        在新增的虚拟主机配置文件proxy.conf中写入以下内容:

server

{    

    listen 80;    

    server_name www.cxkchina.com;     //给代理服务器取的域名

//这里没有写root,原因是因为这个服务器是代理服务器,它不需要访问本地服务器上的任何文件

    location /    

    {        

        proxy_pass      http://121.201.9.155/;         //此处告诉nginx真正的WEB服务器的IP

        proxy_set_header Host   $host;         //告诉nginx它要访问的域名Host是上面设置的域名$host,$host也就是server_name

        proxy_set_header X-Real-IP      $remote_addr;      // 定义X-Real-IP这个变量的值是$remote_addr

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    // 定义X-Forwarded-For这个变量的值是$proxy_add_x_forwarded_for

    }

}

2、检测语法错误并重新加载配置文件

    # /usr/local/nginx/sbin/nginx  -t

    # /usr/local/nginx/sbin/nginx -s reload

3、测试验证

    正常情况下来访问www.cxkchina.com/robots.txt这个页面

使用虚拟服务器内部的回环IP127.0.0.1来访问外部的网站www.cxkchina.com/robots.txt

相关推荐链接:

502问题汇总 http://ask.apelearn.com/question/9109

location优先级 http://blog.lishiming.net/?p=100

猜你喜欢

转载自my.oschina.net/u/3746774/blog/1633135