12.13 Nginx防盗链
12.14 Nginx访问控制
12.15 Nginx解析php相关配置
12.16 Nginx代理
12.13 Nginx防盗链
大纲
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
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
12.14 Nginx访问控制
访问控制是比较重要的一个部分,因为它还涉及到安全。
起原理跟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,正常通过访问。
利用172.18.171.157测试访问,状态码403,拒绝访问。
因为172.18.171.157没有被写入白名单中。
访问控制,还可以匹配正则
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
当然,1.php不能访问是正常的,起到了效果作用了。
下面尝试一下访问没被标住的txt格式。
[root@AliKvn upload]# curl -x127.0.0.1:80 test.com/upload/1.txt -I
访问通过,因为txt没有被标住,所以没有被限制访问。
可以参看日志内容,更详细的记录。
根据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
当被比配到相应的字符串后,无论后面带什么字符都是生效了。
如果想匹配不区分大小写,则在~加上*即可(~*),对应参数。
$http_user_agent ~* 'Spider/3.0|YoudaoBot|Tomato'
再利用curl -A 测试
12.5 Nginx解析php的配置
大纲
在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
2 curl 测试
[root@AliKvn test.com]# curl -x127.0.0.1:80 test.com/jxphp.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的路径,也是站点目录的路径。如果这里配置不配对,会出现404错误。
配置完成后
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
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
正如上面所实验的一样,如果监听IP端口的话,fastcgi_pass的地址也要配置成端口,如下操作:
1
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
检查语法并重新加载
[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测试,解释成功
总结上述各种状态码
502错误,
fastcgi_pass的路径错误,导致找不到socket。
监听的路径与fastcgi_pass不一样的话,就会监听失败,导致502错误出现。
440错误,
如果监听socket,但没有定义listen mode=666 就会导致440.
404错误,
fastcgi_param SCRIPT_FILENAME 路径不配对,会出现404错误。
12.6 Nginx代理
大纲
一家公司有很多太服务器,为了节省成本,不能为所有服务器都分配公网IP,而如果一个没有公网IP的服务器要提供Web服务,就可以通过代理来实现。
代理原理:
用户要访问Web服务器,但是中间不是相通的,想使其俩相通,必须通过代理服务器来实现。代理服务器能连通用户,也能连通Web服务器,它作为用户与Web服务器的中间者,它能反馈信息给用户与Web服务器。
举例说明:
例如大陆要访问美国的网址,但是大陆访问美国网址的速度是很慢的,但是香港访问美国是很快的。如果想在大陆访问美国的网也像香港访问美国一样快,那大陆可以通过香港作为代理,然后直接访问美国网站,从而速度大大提升了。
他们三者的关系相当于用户,代理服务器,web服务器。
配置操作如下:
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
总结:
测试的最终目的是通过 47.91.145.78 可以访问ask.apelearn.com
代理服务器就是本机,
Web服务器就是ask.apelearn.com