保护文件,防止盗链是每个站长都要面对的问题。最简单的办法是利用referer,但很容易被绕过。比较强的方式有下面两个,可以单独使用,也可以一起使用:
第一种,设定一个key,当用户浏览网页,网页生成文件链接的时候,把key和访问者的IP合在一起并进行哈希,得到的哈希值作为一个参数附加在文件链接上。服务器因为知道key和访问者的IP,可以验证参数是否正确,并相应的允许或拒绝文件下载。可以看到,使用这种方式的时候,链接是无法在用户间被分享的。因为不同的用户有着不同的IP地址。
第二种,同样需要设定一个key,当用户浏览网页,网页生成文件链接的时候,把key和当前时间戳合在一起并进行哈希,得到的哈希值作为一个参数附加在文件链接上。同时,把这个时间戳也作为参数附加在文件连接上。服务器拿到链接后,可以通过key及链接上的时间戳来验证链接是否有效。同时,也可以看收到文件链接时的时间戳是不是相比当前时间戳过去了很久。依据这些,服务器判断是否允许文件下载。这种方式中,链接可以在一段时间内被分享。但是,由于时间段是有限的(而且可以自由设定),因而也可以有效的防止盗链。
以上两种方式中,key都是不能被用户所知道的,其作用就是防止用户知道相关参数的生成方式后自行生成链接从而绕过反盗链机制。另外,依据个人经验,第一种方式容易出错导致合法用户无法访问文件,原因至少有二:(1)众所周知,IPv4地址枯竭,很多时候我们都是在运营商的内网中,由于各种原因,我们的公网IP可能常常变换,导致链接失效;(2)在3G和4G手机网络中,这个问题更严重,手机在不同基站间移动,不同基站的IP不同,这种变换也会导致链接失效。因此,我现在一般只是使用第二种方法。
对于nginx服务器,ngx_http_secure_link_module或者HttpAccessKeyModule这两个模块可以用来实现上面的防盗链方法。后者我曾经使用过,似乎只支持第一种方式;前者则两种方式都支持。针对Apache服务器,可以利用mod_perl或者mod_auth_token实现。其中,前者还需要自己写一些脚本文件,后者可以直接使用。1有意思的是,ngx_http_secure_link_module和HttpAccessKeyModule都是将参数附加在URL的末尾(例如,将example.com/file变为example.com/file?foo=bar),而mod_auth_token则是直接改变URL将参数嵌在URL之中(例如,将example.com/file变为example.com/foo/bar/file)。这两种方式可以说各有优劣,但没有本质区别。因此,在现实中,两者都各有被不同的大型文件分享网站采用。
下面就开始说说如何利用Apache的mod_auth_token模块保护wordpress上的文件。首先下载并安装mod_auth_token。需要注意的是,在我的服务器上,我所使用的1.0.6版本在处理URL中的“/”字符上似乎存在一些问题,需要对mod_auth_token.c进行一定的修改(分别在177行和201行左右):
如果大家也有遇见问题的话,为了方便调试,可以看Apache的日志并让mod_auth_token.c打印出相关信息。
安装好mod_auth_token后,就可以对Apache服务器进行配置了,下面是官网提供的一个例子,很直白,这里就不多解释了。
mod_auth_token的官网上也有利用各种语言生成链接的代码片段,此处不再赘述,有需要的朋友可以自己去看看。
下面就是wordpress这端的配置了。首先需要说明的是,最好将你要保护的文件放在wordpress根目录之外。(例如,如果你的wordpress在/html_root/blog/下,则最好将受保护文件放在类似/html_root/pri/这样的目录下,而不是/html_root/blog/pri/或者/html_root/blog/wp-content/uploads/pri/这样的目录下)这是因为——如上文所述——要使用mod_auth_token就要改变文件URL本身,并且如上面示例代码所示,mod_auth_token是在一个Location环境中设置的。但另一方面,如果你用了wordpress的permalink功能的话,wordpress会在其根目录下放一个.htaccess文件。最要命的是,根据Apache文档,在处理请求时,.htaccess的优先级比Location高。(事实上,Location的优先级基本是垫底的。)这样一来,由于文件URL并不对应一个实体文件,wordpress的.htaccess在处理时就会认为文件不存在并直接返回404错误!为了避免这种问题,最简单的方法就是将这些要保护文件放在wordpress根目录之外。
另外一个要说明的问题是,Apache从2.4版本开始,对所有目录和文件默认是拒绝访问的。因此,对那些受保护的文件夹,除了加上mod_auth_token的相关代码以外,不要忘了加上“Require all granted”(或者其他你需要的授权方式)。
OK,回到wordpress这边。基本上,需要保护的文件可以分为两大类:媒体文件(如音乐和视频)与一般文件。尤其是音乐文件和一些视频文件,需要重点照顾。
为了顺利播放视频和音乐文件,需要修改播放器的相应文件。这里仅以wordpress 4.0的内置播放器为例进行说明。内置播放器生成链接的代码在wp-includes/media.php文件中,我们可以做以下修改:
首先,添加一个函数将普通URL变成受保护的URL。
然后 ,检查代码,针对视频和音频文件,当最终的文件URL被生成时,调用上面的函数更新该URL为受保护的URL。我个人修改了五处地方,简单测试后没问题,但不保证正确性。
第一处是在wp_mediaelement_fallback函数中,1405行左右。
第二处和第三处是在wp_audio_shortcode函数中,分别是在1525和1611行左右。
第四处和第五处是在wp_video_shortcode函数中,分别是在1747行和1840行左右。
讲完媒体文件后,再说说一般的文件。这个就简单了,我已经写好了一个wordpress插件,大家直接下载使用就好了。23
这个插件的使用方法也很简单,在博文中相应位置添加如下所示代码即可。其中url就是你的文件的原始地址(例如http://example.com/pri/file),而密钥可以在wordpress的设置页面中设置。
写完收工,补觉去了~
脚注: