12.13-12.16 Nginx的防盗链、访问控制、解析php相关配置、代理

12.13 Nginx防盗链

12.14 Nginx访问控制

12.15 Nginx解析php相关配置

12.16 Nginx代理



12.13 Nginx防盗链


大纲

blob.png

Nginx的防盗链思路和httpd是一样的,配置也不难。

准备工作:

可以把其中不用的功能给注释掉,

把配置静态文件不记录日志的配置给注释掉

#location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
#    {
#          expires      7d;
#          access_log off;
#    }
#location ~ .*\.(js|css)$
#    {
#          expires      12h;
#          access_log off;
#    }


本节主题

1 Nginx防盗链 的配置如下,可以和上面的配置结合起来

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;
    }
    access_log off;
}


2 参数解析,

~*表示(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)里面不区分大小写,利用了正则表达式的语法。

^.+\. ^表示xx开头

location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)$

整段参数的意思是:以xxxx(括号里面的关键词)结尾。

  valid_referers none blocked server_names  *.test.com ;

定义白名单的referer是*.test.com

valid_referers none blocked server_names  *.test.com ;
    if ($invalid_referer) {
        return 403;
    }

3 如果不是白名单的referer,就会返回到403


4 检查语法,并重新加载

[root@AliKvn vhost]# /usr/local/nginx/sbin/nginx -t

nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok

nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

[root@AliKvn vhost]# /usr/local/nginx/sbin/nginx -s reload


5 curl 测试防盗链

先测试一个正常的curl访问,状态码200

[root@AliKvn test.com]# curl -x127.0.0.1:80 test.com/1.gif -I

blob.png

curl -e指定referer测试,状态码403,实验成功,因为当初配置就是要得到403效果。

[root@AliKvn test.com]# curl -e "http://www.baidu.com " -x127.0.0.1:80 test.com/1.gif -I

blob.png


12.14 Nginx访问控制

image.png

访问控制是比较重要的一个部分,因为它还涉及到安全。

起原理跟httpd一样,Nginx也可以限制某些IP不能访问,或者只允许某些IP访问。

配置方法和httpd很想,但更加简洁,不像hettpd那样全部遍历一边。

比如我们有个需求,“是访问admin目录的请求只允许127.0.0.1访问,”


1 访问控制的配置如下,

location /admin/
{
allow 127.0.0.1;
deny all;
}

参数解释

在httpd中,利用order去规则allow与deny的顺序,先allow后deny,或者先deny后allow.

但在nginx里,如果参数的ip(127.0.0.1)被匹配到了,那么这个规则就会到此结束。

不会考虑deny与allow的顺序。如果是127.0.0.2访问进来,那么发现ip不被匹配,这样的话,访问会直接被deny,到此结束。


2 检查语法并重新加载 

[root@AliKvn test.com]# /usr/local/nginx/sbin/nginx -t

nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok

nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

[root@AliKvn test.com]# /usr/local/nginx/sbin/nginx -s reload

访问前的准备工作:

[root@AliKvn test.com]# mkdir -p /data/wwwroot/test.com/admin/

[root@AliKvn test.com]# cd /data/wwwroot/test.com/admin/

[root@AliKvn admin]# echo "admin test" > index.html



3 curl访问测试

利用127.0.0.1测试,状态码200,正常通过访问。

blob.png

利用172.18.171.157测试访问,状态码403,拒绝访问。

因为172.18.171.157没有被写入白名单中。

blob.png


访问控制,还可以匹配正则

1 写入如下参数

location ~ .*(upload|image)/.*\.php$
{
        deny all;
}

参数解释:

location ~ .*(upload|image)/.*\.php$

只要是匹配upload,image的,以.php结尾的url都给予deny.

写入参数后检查语法与重新加载。

[root@AliKvn vhost]# /usr/local/nginx/sbin/nginx -t

nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok

nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

[root@AliKvn vhost]# /usr/local/nginx/sbin/nginx -s reload


演示操作

2 准备工作,

建立upload目录,然后在其下创建1.php文件,echo任意内容1.php

[root@AliKvn vhost]# mkdir /data/wwwroot/test.com/upload/

[root@AliKvn vhost]# cd !$

cd /data/wwwroot/test.com/upload/

[root@AliKvn upload]# echo "1111" > 1.php


3 curl测试

[root@AliKvn upload]# curl -x127.0.0.1:80 test.com/upload/1.php -I

blob.png

当然,1.php不能访问是正常的,起到了效果作用了。

下面尝试一下访问没被标住的txt格式。

[root@AliKvn upload]# curl -x127.0.0.1:80 test.com/upload/1.txt -I

blob.png

访问通过,因为txt没有被标住,所以没有被限制访问。

可以参看日志内容,更详细的记录。

blob.png


根据user_agent限制

1 写入如下参数

if ($http_user_agent ~ 'Spider/3.0|YoudaoBot|Tomato')
{
      return 403;
}

参数解析,

$http_user_agent ~ 'Spider/3.0|YoudaoBot|Tomato'
return 403;

其中~是匹配符号,只要user_agent中含有Spider/3.0或者YoudaoBot或者Tomato字符串,

都会被拒绝访问,并返回403状态码。

这里的return 403跟deny all是一样的效果。

2 检查语法和重新加载

[root@AliKvn vhost]# /usr/local/nginx/sbin/nginx -t

nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok

nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

[root@AliKvn vhost]# /usr/local/nginx/sbin/nginx -s reload 

3 curl 测试

curl -A 指定user_agent,

[root@AliKvn vhost]# curl -A "Tomato1111" -x127.0.0.1:80  test.com/upload/1.txt -I

blob.png

当被比配到相应的字符串后,无论后面带什么字符都是生效了。

如果想匹配不区分大小写,则在~加上*即可(~*),对应参数。

$http_user_agent ~* 'Spider/3.0|YoudaoBot|Tomato'

再利用curl -A 测试

blob.png


12.5 Nginx解析php的配置

大纲

image.png

在LAMP中,PHP是作为httpd的一个模块出现的,只要PHP模块被加载,那么就能解析PHP脚本了。

在LNMP中,PHP是以一个服务(php-fpm)的形式存在的,首先要启动php-fpm服务,然后Nginx在和php-fpm通信。

换句话来说,处理PHP脚本解析的工作是由php-fmp来完成的,Nginx只是一个“搬运工”,它能把用户的请求传递给php-fpm,

php-fpm处理完结果会传递给Nginx,Nginx再把结果传递给用户。

在Nginx,PHP解析没做配置之前,解析是源码。

以下做测试说明,

1 首先在test.com/建立一个php脚本,信息内容是php的介绍页面。

[root@AliKvn test.com]# vim /data/wwwroot/test.com/jxphp.php 

<?php
phpinfo();

2 curl 测试

[root@AliKvn test.com]# curl -x127.0.0.1:80 test.com/jxphp.php

<?php

phpinfo();

此php脚本其实是一个php的自带的信息介绍页面,如果解析正常的话此处应该显示解析php信息,

但是此处显示源码,所以证明php解释失败。


 配置如下:

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;
    }

解析参数:

fastcgi_pass 用来指定php-fpm监听tcp:port的地址或者socket,如果这里配置不配对,会出现502错误。

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

fastcgi_param后面的路径要接root的路径,也是站点目录的路径。如果这里配置不配对,会出现440错误。


配置完成后

3 检查参数配置并重新加载-t&&-s reload

nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

[root@AliKvn test.com]# /usr/local/nginx/sbin/nginx -s reload

4 curl测试效果

 这是正确解析效果,正确解析php的效果是网页源代码,而不是配置源代码。

[root@AliKvn test.com]# curl -x127.0.0.1:80 test.com/jxphp.php

image.png

5 curl -I 200状态码通过,访问正常,解析php正常。

 [root@AliKvn test.com]# curl -x127.0.0.1:80 test.com/jxphp.php -I

HTTP/1.1 200 OK


fastcgi_pass 用来指定php-fpm监听的地址或者socket

如果curl解析是502错误,这里大多数是fastcgi_pass 地址不匹配,找不到sock。

遇到502错误,可以第一时间查看错误日志。

下面故意把fastcgi_pass地址改错,演示反面教材效果。

1 划掉路径其中的fc字符串

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

2 检查语法并重新加载,

[root@AliKvn vhost]# /usr/local/nginx/sbin/nginx -t

nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok

nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

[root@AliKvn vhost]# /usr/local/nginx/sbin/nginx -s reload

3 curl测试,出现502状态码,因为找不到socket

curl -x127.0.0.1:80 test.com/jxphp.php -I

HTTP/1.1 502 Bad Gateway

4 下面看看错误日志记录信息,nginx_error.log 

[root@AliKvn vhost]# tail -1 /usr/local/nginx/logs/nginx_error.log 

2018/04/28 20:38:49 [crit] 24338#0: *310 connect() to unix:/tmp/php-gi.sock failed (2: No such file or directory) while connecting to upstream, client: 127.0.0.1, server: test.com, request: "GET HTTP://test.com/jxphp.php HTTP/1.1", upstream: "fastcgi://unix:/tmp/php-gi.sock:", host: "test.com"

主要查看此段解释,connect() to unix:/tmp/php-gi.sock failed.

大致意思就是,连接php的sock失败,大概就是找不到正确的socket路径(其实此时ls这个错误的路径,文件应该是不存在的,就算存在也可能是有问题的)。

5 fastcgi_pass 的地址 必须要与 /php-fpm/etc/php-fpm.conf的listen路径一样,否则会出现上面的情况。

所以要将虚拟主机配置文件test.com.conf的fastcgi_pass改回来

[root@AliKvn vhost]# cat /usr/local/php-fpm/etc/php-fpm.conf

image.png

image.png


正如上面所实验的一样,如果监听IP端口的话,fastcgi_pass的地址也要配置成端口,如下操作:

1

image.png


2 检查php-fpm的语法并重新reload php-fpm(注意,此处的检查和重新加载时针对php-fpm,所以他们的命令和nginx -t , -s不同。修改php-fpm.conf需要reload或者restart)

[root@AliKvn ~]# /usr/local/php-fpm/sbin/php-fpm -t

[28-Apr-2018 21:04:01] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf

[root@AliKvn ~]# /etc/init.d/php-fpm reload 

Reload service php-fpm  done


3 检查监听端口

[root@AliKvn ~]# netstat -lntp |grep 9000

tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      24697/php-fpm: mast 

4 此时监听了ip端口后,需要再修改虚拟主机配置文件test.com.conf

[root@AliKvn vhost]# vim test.com.conf 

image.png

检查语法并重新加载

[root@AliKvn vhost]# /usr/local/nginx/sbin/nginx -t

nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok

nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

[root@AliKvn vhost]# /usr/local/nginx/sbin/nginx -s reload

5 curl测试,解释成功

image.png


总结上述各种状态码

502错误,

fastcgi_pass的路径错误,导致找不到socket。

监听的路径与fastcgi_pass不一样的话,就会监听失败,导致502错误出现。


440错误,

如果监听socket,但没有定义listen mode=666 就会导致440.


404错误,

fastcgi_param SCRIPT_FILENAME 路径不配对,会出现404错误。


12.6 Nginx代理

大纲

image.png


一家公司有很多太服务器,为了节省成本,不能为所有服务器都分配公网IP,而如果一个没有公网IP的服务器要提供Web服务,就可以通过代理来实现。

代理原理:

用户要访问Web服务器,但是中间不是相通的,想使其俩相通,必须通过代理服务器来实现。代理服务器能连通用户,也能连通Web服务器,它作为用户与Web服务器的中间者,它能反馈信息给用户与Web服务器。

举例说明:

例如大陆要访问美国的网址,但是大陆访问美国网址的速度是很慢的,但是香港访问美国是很快的。如果想在大陆访问美国的网也像香港访问美国一样快,那大陆可以通过香港作为代理,然后直接访问美国网站,从而速度大大提升了。

他们三者的关系相当于用户,代理服务器,web服务器。

image.png

配置操作如下:

1 cd /usr/local/nginx/conf/vhost

2 vim proxy.conf 

参数配置如下

server
{
    listen 80;
    server_name ask.apelearn.com;

    location /
    {
        proxy_pass      http://47.91.145.78/;
        proxy_set_header Host   $host;
        proxy_set_header X-Real-IP      $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

参数解析:

没有root,因为代理服务器不需要访问本地服务器上的任何文件。

proxy_pass http://47.91.145.78/;

指定要代理的域名所在的服务器IP,这个IP可以ping ask.apelearn.com得来。

proxy_set_header Host   $host;

表示后端Web服务器的域名和当前配置文件中的server_name保持一致

$host = server_name 


3 配置完成后,检查语法并重新加载

[root@AliKvn vhost]# /usr/local/nginx/sbin/nginx -t

nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok

nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

[root@AliKvn vhost]# /usr/local/nginx/sbin/nginx -s reload

4 curl测试,本机到ask.apelearn.com,相当于 Host $host

image.png

总结:

测试的最终目的是通过 47.91.145.78 可以访问ask.apelearn.com

代理服务器就是本机,

Web服务器就是ask.apelearn.com


猜你喜欢

转载自blog.51cto.com/13578154/2108264