十二周四次课(3月15日

12.13 Nginx防盗链

12.14 Nginx访问控制

12.15 Nginx解析php相关配置

12.16 Nginx代理

12.13 Nginx防盗链

配置如下,可以和上面的配置结合起来: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 ; //定义白名单

   if ($invalid_referer) { //不是白名单

       return 403; //返回403

   }

   access_log off;

}

-t && -s reload

测试:

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

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

查看日志:

cat /tmp/1.log //测试第一条是,状态码时403,没有被记录在日志里。第二天状态码时200,记录在日志里

12.14 Nginx访问控制

和httpd一样,nginx也需要限制某个IP不能访问或者只允许某些IP访问。配置方法和httpd很像,但更加简洁,而且不像httpd那样全部遍历一遍。

  • 根据IP限制

需求:访问/admin/目录的请求,只允许某几个IP访问,配置如下:vim /usr/local/nginx/conf/vhost/test.com.conf

location /admin/

{

   allow 192.168.37.101; //匹配192.168.37.101,如果匹配了匹配就结束,如果不匹配就去匹配下一

   allow 127.0.0.1; //匹配127.0.0.1,如果匹配了匹配就结束,如果不匹配就去匹配下一条

   deny all; //最终匹配是deny

}

在配置httpd的时候,还有一个order,来定义先allow还是先deny,在Nginx里并没有,只要匹配规则就结束了。假如来源IP为192.168.188.129,它会从上到下逐一去匹配,第一个IP(192.168.37.101)不匹配,第二个IP(127.0.0.1)不匹配,直到第三行(all)的时候才匹配到,匹配的这条规则为deny(也就是拒绝访问),所以最终会返回一个403的状态码。

配置文件中的IP也可以为IP段,比如可以写成allow 92.168.188.0/24;

-t && -s reload

测试

curl -e "http://www.test.com/1.txt" -x127.0.0.1:80 test.com/admin/ -I

curl -x192.168.37.101:80 test.com/admin/ -I

查看日志:

cat /tmp/1.log

用ifconfig命令查看到另外1块网卡地址是192.168.254.128

状态码:403 //ip并没有被允许

  • 可以匹配正则

配置如下:

location ~ .*(upload|image)/.*\.php$ //小括号里的竖线为“或者”的意思,把访问的url中带有upload或image字符串,并且是PHP的请求。

{

       deny all; //全部拒绝

}

测试:

-t && -s reload

创建upload目录:mkdir /data/wwwroot/test.com/upload

不能访问PHP文件:curl -x127.0.0.1:80 test.com/upload/1.php -I

可以访问txt文件:curl -x127.0.0.1:80 test.com/upload/1.txt –I

  • 根据user_agent限制

配置如下:

if ($http_user_agent ~ 'Spider/3.0|YoudaoBot|Tomato') //匹配符号后面加个星号:~* 就忽略大小写了

{

     return 403;

}

deny all和return 403效果一样

-t && -s reload

测试:

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

12.15 Nginx解析php相关配置

前面讲了很多Nginx的配置,一直都还没有提到和PHP相关的东西。在LAMP中,是作为 httpd的一个模块出现的,只要PHP模块被加载,那么就能解析PHP脚本了。而在LNMP中,PHP是以一个服务 ( php-fpm ) 的形式存在的,首先要启动php-fpm服务,然后Nginx再和php-fpm通信。也就是说,处理PHP脚本解析的工作是由php-fpm来完成的,Nginx仅仅是一个“搬运工",它把用户的请求传递给 ' php-fpm, php-fpm处理完成后把结果传递给Nginx,Nginx再把结果返回给用户。那么Nginx是如何和PHP 联系起来的呢?其实,上面给大家的nginx.conf中已经有展示。

配置如下:

location ~ \.php$

   {

       include fastcgi_params;

       fastcgi_pass unix:/tmp/php-fcgi.sock; // fastcgi_pass:用来指定php-fpm的地址。如果php-fpm监听的是一个tcp:port的地址(比如127.0.0.1:9000),那么也需要在这里改成

                                                  fastcgi_pass 127.0.0.1:9000。这个地址一定要和php-fpm服务监听的地址匹配,否则会报502错误。

       fastcgi_index index.php;

       fastcgi_param SCRIPT_FILENAME /data/wwwroot/test.com$fastcgi_script_name; // fastcgi_param SCRIPT_FILENAME后面跟的路径为该站点的根目录,和前面定义的root那个路径保持一致。如果

                                                                                            这里配置不对,访问php页面会出现404

}

先不加载新的配置。查看是否能解析php

-t && -s reload

再次执行curl命令:curl -x127.0.0.1:80 test.com/3.php //能解析了

如果遇到出现502的问题时,查看日志文件

tail /usr/local/nginx/logs/nginx_error.log

查看php-fpm.conf文件:cat /usr/local/php-fpm/etc/php-fpm.conf

listen这行后面写的什么,那在nginx配置文件里写什么。二者要相同。

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

监听ip:port也是一样的

vi /usr/local/php-fpm/etc/php-fpm.conf //更改listen=127.0.0.1:9000

vim /usr/local/nginx/conf/vhost/test.com.conf //更改fastcgi_pass 127.0.0.1:9000

-t && -s reload

再次访问:curl -x127.0.0.1:80 test.com/3.php

就不是502

在php-fpm.conf配置文件里:cat /usr/local/php-fpm/etc/php-fpm.conf

listen.mode = 666 //定义mode=666,使任何用户都能有读写的权限

如果注释掉,查看/tmp/php-fcgi.sock,会发现变成了440

访问报502

查看日志,发现没有权限

因为现在/tmp/php-fcgi.sock的权限是440,root用户和root组是可以读的,其他用户不能读。但nginx的用户是nobody,属组是nobody,所以不能读

如果/tmp/php-fcgi.sock改为nobody用户就可以有读的权限了

12.16 Nginx代理

Nginx的代理功能非常实用,一家公司有很多台服务器,为了节省成本,不能所有服务器都分配公网ip,而如果一个没有公网ip的服务器要提供web服务,就可以通过代理来实现

如果nginx后面有多台web服务器,如果同时代理,那nginx在这里就起到一个负载均衡的作用。

写个新的配置文件

cd /usr/local/nginx/conf/vhost

vim proxy.conf //加入如下内容

server

{

   listen 80;

   server_name ask.apelearn.com; //指定域名

   location /

   {

       proxy_pass      http:// 47.91.145.78 /; //指定要代理的域名所在的服务器IP,就是远程web服务器的ip

       proxy_set_header Host   $host; //要访问的域名,$host就是上面server_name定义的域名,表示后端web服务器的域名和当前配置文件中的server_name保持一致

       proxy_set_header X-Real-IP      $remote_addr;

       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

   }

}

代理服务器就是虚拟机,web服务器就是ask.apelearn.com论坛

测试: