Nginx防盗链、爬虫和虚拟目录
写在前面
前面学习的都是一些比较枯燥的内容,接下来学习一下较为有趣的配置,如使用Nginx来设置防盗链、防爬虫和虚拟目录等,学习和掌握这些有趣的知识可以提升自己的综合能力。
防盗链
为什么需要防盗链?现在随着自媒体的发展,很多人开始以博流量为由,各种复制别人发布的文章,更有甚至将其标为原创来盗取他人的劳动成果,因此防盗链的设置显得尤为重要。
一般来说,当开发者对该网站做好防盗链之后,其他网站盗链本站的图片就会全部失效无法显示,但是如果用户是通过浏览器来访问本网站或者直接访问图片地址时,这些图片依旧是可以正常显示,且可以右键下载到本地,所以这只是对网站做的防盗链,对于用户还是挺友好的。
这是使用的是ngx_http_referer_module模块,通常使用它来阻挡非法的域名请求,请注意伪装Referer头部其实非常简单,因此这个模块只能用于阻挡大部分非法请求,而有些正常请求,如用户直接访问是不会携带Referer头部,但是这种情况是应当被允许的,因此不能拒绝来源Referer头部为空的请求。
在vhost文件夹下面新建一个hero.com.conf
的配置文件,其中的内容为:
1 | server { |
解释一下上述代码的含义:首先我们这个Nginx服务监听本地的92端口,然后设置网站根目录为D:\Application\Nginx-1.18.0\static
,注意这里必须使用绝对路径,然后设置网站首页为index.html文件,接着定义一个location,里面用于匹配图片,注意下面的一段代码:
1 | valid_referers none blocked *.store.com; |
其中valid_referers用来定义一个合法访问的白名单,其实就是判断请求中的referer来源;none表示通过浏览器直接访问图片地址,这种情况下请求中是没有referer的,但是这种请求通常也是允许访问的;blocked表示当请求中的referer不为空时,但是它的内容被防火墙或者代理服务器给删除了,这种请求通常也是允许访问的。*.store.com
是被允许访问的域名,可以使用通配符。$invalid_referer
是一个变量,用于判断valid_referers的结果是否合法,如果判断不合法则就返回403,当然开发者也可以使用重定向来自定义不合法时的显示信息。
请注意,上述localhost
和*.store.com
不能是同一台机器,否则会出现图片访问不到的情况,因为你对这台机器设置了防盗链,又使用这台机器来返回防盗链图片,这是不可能的。
上面只是对某个server进行防盗链设置,如果想对整站做防盗链,只需将配置添加到http区块中。
防爬虫
其实这里的防爬虫也只是针对那些比较符合约定的爬虫,对于那些流氓爬虫,这里介绍的配置还是无法解决。
开发者只需在用户访问网站首页时进行设置即可实现目的,可以在server区块中添加如下配置:
1 | location / { |
当然下面的配置也是可以的,因为user-agent种类较多:
1 | location / { |
虚拟目录
请注意Nginx是通过alias关键词来设置虚拟目录的,alias目录和root目录是有区别的,下面将详细进行分析:
(1)对于alias来说,它指定的目录是准确的,即location匹配访问path目录下的文件是直接在alias目录下查找的。
(2)对于root来说,它指定的目录是location匹配访问path目录的上一级目录,这个path目录必须真实存在于root指定目录下。
例子1,假设笔者配置的域名是www.envygo.com
,且域名配置文件名称为envygo.com.conf
,其中的代码为:
1 | server { |
为了访问http://www.envygo.com/book/main.html
文件,如果开发者使用root目录这一方式,那么应当添加如下location片段:
1 | location /book/ { |
也就是说此时文件的实际存储路径为/home/www/book/main.html
。
如果使用alias虚拟目录这一方式,那么应当添加如下location片段:
1 | location /book/ { |
注意使用alias虚拟目录时,后面的/home/www/book/
最后面必须添加/
表示这是一个目录,如果不加那么文件就无法查找的到。如果使用root,那么/home/www/
最后面的/
可加可不加,但是建议还是加,规范一下。
细心的你可能已经发现前面举的例子中,alias设置的目录名称和location匹配访问的path目录名称是一致的,这样就可以直接修改为root目录配置。但是在实际工作中,也经常会出现目录不一致情况,此时应该如何操作呢?
例子2,假设alias设置的目录名称和location匹配访问的path目录名称不一致,如下所示:
1 | location /web/ { |
这样当开发者访问http://www.envygo.com/web/main.html
的时候,Nginx就会去查找/home/www/html/main.html
文件。注意此时就不能直接修改为root目录配置,因为/home/www/html/
目录下是不存在web目录的,如果非要这么做的话,可以采用软链接的方式,即将/home/www/
目录下的html目录软链接到web目录。先执行如下软连接操作:
1 | ln -s /home/www/web /home/www/html |
之后location中的代码修改为如下所示:
1 | location /web/ { |
综合上述分析,我们建议在location /
中采用root目录配置;在location /path
中采用alias虚拟目录配置。
(3)在alias虚拟目录配置中,如果location匹配的path目录后面不携带/
,那么访问的url地址中这个path目录后面加不加/
不影响访问,因为在访问时会自动加上/
。但是如果location匹配的path目录后面携带了/
,那么访问的url地址中这个path目录后面必须添加/
,因为在访问时它不会自动加上/
,故访问的时候就会失败。
例子3,下面例子中的location匹配的path目录后面没有携带/
,那么
1 | location /book { |
用户使用http://www.envygo.com/book
或者http://www.envygo.com/book/
都是可以访问的到。但是如果location匹配的path目录后面携带了/
,那么
1 | location /book/ { |
用户必须使用http://www.envygo.com/book/
才能访问得到,使用http://www.envygo.com/book
则会抛错。
(4)使用alias标签的目录块中不能使用rewrite重写的break,且alias指定目录的后面必须添加/
,这一点不能忘记。
接下来将完整的展示一个配置信息,如下所示:
1 | server { |
当开发者访问http://www.envygo.com/index.html
时,Nginx会去/home/www
目录下查找index.html文件;访问http://www.envygo.com/book/test.html
时,Nginx会去/home/www/html
目录下查找test.html文件;访问http://www.envygo.com/movie/test.html
时,Nginx会去/home/www/html/movie
目录下查找test.html文件。