nginx防盗链和代理配置

nginx防盗链

防盗链的意义在于防止网站中的文件链接在其他网站中被使用,盗链的文件或图片在其他网站中加载,在这个过程中,实质上加载的请求是被盗链服务器上响应的,这就造成了一些不正常流量(并非自己网站的正常打开页面加载的处理请求)造成了消耗不必要的带宽
要实现防盗链,需要了解HTTP协议中的请求头部的Referer头域和采用URL的格式表示访问当前网页或者文件的源地址。通过该头域的值,我们可以检测到访问目标资源的源地址。这样,如果我们检测到Referer(rui'fe~)头域中的值并不是自己站点内的URL,就采取组织措施,实现防盗链

nginx防盗链使用到了valid_referers这个名单定义项(相当是定义白名单域名,如需定义多个域名使用空格分隔,非这里定义的域名会在转跳中返回403状态码),if中定义:非名单里里的域名可以定义返回403状态拒绝访问或返回一个盗链显示图片,如果使用盗链显示图片就定义rewrite跳转到那个图片的URL
location中定义防止盗链的文件类型,以正则的语法进行匹配
expires、access_log定义了这些文件过期时间和日志不记录类型的配置,防盗链与静态文件过期时间和访问日志不记录可以在一个location中定义配置
rewrite设定指定转跳,设定指定转跳的URL地址,返回状态码302
return跟rewrite类似,只不过在最后处理请求时是直接拒绝掉这个盗链的请求,返回状态码403

注意配置中的空格分隔,配置完成后使用-t检查,nginx防盗链配置项如下:

location ~* ^.*\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)$
     {
          expires 7d;
          valid_referers none blocked server_name .*.aaa.com bbb.com;
          if ($invalid_referer) {
                      rewrite ^/ http://aaa.com/bmiddle/403.jpg;
                     # return 403;
                         }
          access_log off;
     }
-------------检查配置并reload重新加载配置
[root@localhost bmiddle]# /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@localhost bmiddle]# /usr/local/nginx/sbin/nginx -s reload

在浏览器中访问防盗链资源(在windows的hosts文件中添加一个虚拟机的解析),在公网博客写入本站的图片URL地址,在博客中点击该地址会被转跳至显示指定的图片,转跳状态码为302,拒绝访问的状态码则是403,第一条为虚拟机本站图片的URL,第二条为公网博客的来源地址

nginx访问控制

根据需求限制某些ip或者某些类型的文件不能访问或禁止解析,多个访问控制可以同时配置,防止解析某些可执行恶意的代码文和上传恶意的文件类型
配置指定字符的访问控制,在location 后定义匹配限制的字符,如果匹配到有这个字符的URL请求,会执行匹配规则,这里配置的是先允许指定的ip访问后,再拒绝所有的访问请求,只允许指定的ip访问指定的内容(如名称是admin的管理目录)
注意配置中的空格分隔,配置完成后使用-t检查

location /admin.*/
     {
      allow 127.0.0.1;
      allow 192.168.1.112;
      deny all;
     }
     

测试访问控制,查看日志记录信息,可以从日志中看到,允许了配置中的回环地址和192.168.1.112的windown本机的访问,拒绝了服务器本机通过自身的网卡ip访问,实现了ip反馈控制的需求

[root@localhost admin]# echo "123">1.html
[root@localhost admin]# curl -x127.0.0.1:80 -I aaa.com/admin/1.html
HTTP/1.1 200 OK
Server: nginx/1.15.2
Date: Tue, 14 Aug 2018 14:57:55 GMT
Content-Type: text/html
Content-Length: 4
Last-Modified: Tue, 14 Aug 2018 14:57:35 GMT
Connection: keep-alive
ETag: "5b72eddf-4"
Accept-Ranges: bytes

[root@localhost admin]# curl -x192.168.1.234:80 -I aaa.com/admin/1.html
HTTP/1.1 403 Forbidden
Server: nginx/1.15.2
Date: Tue, 14 Aug 2018 14:58:05 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
[root@localhost admin]# cat /data/wwwroot/log/aaa.com.log
192.168.1.112 - [14/Aug/2018:22:57:41 +0800] aaa.com "/admin/1.html" 200 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"
127.0.0.1 - [14/Aug/2018:22:57:55 +0800] aaa.com "/admin/1.html" 200 "-" "curl/7.29.0"
192.168.1.234 - [14/Aug/2018:22:58:05 +0800] aaa.com "/admin/1.html" 403 "-" "curl/7.29.0"

限制某些页面元素的访问控制,通过正则匹配实现,这里匹配以admin和abc开头、php结尾的文件URL访问,并把这些请求deny拒绝掉
注意配置中的空格分隔,配置完成后使用-t检查
配置如下

location ~.*(admin|abc)/.*\.php$
     {
     allow 127.0.0.1;
     deny all;
     }
[root@localhost admin]# /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@localhost admin]# /usr/local/nginx/sbin/nginx -s reload

测试访问控制,允许回环地址访问,拒绝通过服务器本机网卡ip进行访问,拒绝windown客户端访问,并查看访问日志记录的信息

[root@localhost admin]# curl -x127.0.0.1:80 -I aaa.com/admin/admin.php
HTTP/1.1 200 OK
Server: nginx/1.15.2
Date: Tue, 14 Aug 2018 15:11:19 GMT
Content-Type: application/octet-stream
Content-Length: 8
Last-Modified: Tue, 14 Aug 2018 15:07:24 GMT
Connection: keep-alive
ETag: "5b72f02c-8"
Accept-Ranges: bytes

[root@localhost admin]# curl -x192.168.1.234:80 -I aaa.com/admin/admin.php
HTTP/1.1 403 Forbidden
Server: nginx/1.15.2
Date: Tue, 14 Aug 2018 15:11:31 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive


访问日志记录了允许127.0.0.1访问状态码200,拒绝192.168.1.234和192.168.1.112访问并返回状态码403

[root@localhost admin]# cat /data/wwwroot/log/aaa.com.log
127.0.0.1 - [14/Aug/2018:23:11:19 +0800] aaa.com "/admin/admin.php" 200 "-" "curl/7.29.0"
192.168.1.234 - [14/Aug/2018:23:11:31 +0800] aaa.com "/admin/admin.php" 403 "-" "curl/7.29.0"
192.168.1.112 - [14/Aug/2018:23:11:47 +0800] aaa.com "/admin/admin.php" 403 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"

限制指定的user_agent的访问类型,用http_user_agent定义user_agent名单,然后使用return指定返回请求处理的状态码

if ($http_user_agent ~ 'Spider/3.0|YoudaoBot|Tomato')
     {
      return 403;
     }
[root@localhost admin]# /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@localhost admin]# /usr/local/nginx/sbin/nginx -s reload
测试限制user_agent访问
[root@localhost admin]# curl -A "Tomatoaaaadgd" -x127.0.0.1:80 aaa.com/girl.png -I
HTTP/1.1 403 Forbidden
Server: nginx/1.15.2
Date: Tue, 14 Aug 2018 15:27:09 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive

正常访问,使用127.0.0.1地址访问

HTTP/1.1 200 OK
Server: nginx/1.15.2
Date: Tue, 14 Aug 2018 15:27:17 GMT
Content-Type: image/png
Content-Length: 4666274
Last-Modified: Tue, 31 Jul 2018 08:55:41 GMT
Connection: keep-alive
ETag: "5b60240d-4733a2"
Expires: Tue, 21 Aug 2018 15:27:17 GMT
Cache-Control: max-age=604800
Accept-Ranges: bytes

nginx解析php相关配置

nginx中需要配置php-fpm解析才能正常解析php的代码页面,在未解析php的源码时会直接显示该页面的代码,配置解析后会执行php代码,显示出php页面
配置和php-fpm的通信方式有ip和sock文件两种模式,ip模式可以 提供ip方式的访问,sock只能在本机访问,sock适合nginx和php都在一台服务器上使用的场景
注意配置中fastcgi_param中定义的路径为网站根目录的路径,与server下的root根路径一直,否则会造成访问404状态
虚拟主机配置文件中的配置如下:    

location ~ \.php$
     {
     include fastcgi_params;
     fastcgi_pass unix:/tmp/php-fcgi.sock;
     fastcgi_index index.php;
     fastcgi_param SCRIPT_FILENAME /data/wwwroot/aaa$fastcgi_script_name;
     }
[root@localhost nginx]# /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@localhost nginx]# /usr/local/nginx/sbin/nginx -s reload

出现502错误:极大可能是nginx配置和php-fpm通信的方式配置问题,如php中定义的通信方式是127.0.0.1:9000,而nginx中定义的是php-fpm.sock,这样就造成了访问时nginx不能和php-fpm通信,调用不了php解析,就会报错502问题
sock文件权限,如果sock文件权限只有root用户可读,那样也会造成访问502问题,还有就是sock文件是否正常,是否有sock的通信文件
资源耗尽,如果通过调用php出现慢解析,会造成大量的等待响应的处理请求,这样会造成php进程的拥堵,就好像高速路大量的车辆通过的场景,这样的问题先从mysql语句是否有慢处理排查,其次配置php更多处理的进程,或者提供更多的php-fpm服务来处理请求

测试nginx调用php解析

nginx未调用php解析时访问php测试页面

[root@localhost nginx]# curl -x127.0.0.1:80 aaa.com

修改php-fpm提供解析的方式,和修改nginx调用php的方式,再次访问php测试页,会返回php的解析页代码

[root@localhost nginx]# curl -x127.0.0.1:80 aaa.com