0x01 accesskey

nginx-accesskey可以根据不同的请求IP生成不同的key,拒绝无效的请求。安装需重新编译Nginx增加nginx-accesskey模块。

./configure –prefix=/usr/local/nginx –with-http_stub_status_module –with-http_ssl_module –add-module=/root/nginx-1.8.1/nginx-accesskey-2.0.3

首先添加如下配置:

accesskey on;

accesskey_hashmethod md5;

accesskey_arg “key”;

accesskey_signature  “test”;

参数解释如下:

accesskey

语句: accesskey [on|off]

默认: accesskey off

可以用在: main, server, location

开启 access-key 功能。

accesskey_arg

语句: accesskey_arg “字符”

默认: accesskey “key”

可以用在: main, server, location

URL中包含 access key 的GET参数。

accesskey_hashmethod

语句: accesskey_hashmethod [md5|sha1]

默认: accesskey_hashmethod md5(默认用 md5 加密)

可以用在: main, server, location

用 MD5 还是 SHA1 加密 access key。

accesskey_signature

语句: accesskey_signature “字符”

默认: accesskey_signature “$remote_addr”

可用在: main, server, location

这个值用来生成 access key。

然后尝试访问http://192.168.192.120返回了403,原因是没有key参数。test的Md5对应为098f6bcd4621d373cade4e832627b4f6。

访问http://192.168.192.120/?key=098f6bcd4621d373cade4e832627b4f6返回200。

这样还是无法防盗链,这里可以结合客户端IP生成链接。

修改accesskey_signature   “mypass$remote_addr”;

服务端获取到客户端的IP后,组合mypass使用Md5后得到链接,别的站点即便复制了这个链接,其他人点击了也是会返回403。

生成链接的PHP代码如下:

<?php

$ipkey= md5("test".$_SERVER['REMOTE_ADDR']);

$output_add_key="<a href=http://192.168.192.120/download/a.jpg?key=".$ipkey.">

download_add_key</a>";

echo $output_add_key;

?>

 

0x02 secure_link

重新编译Nginx,添加参数–with-http_secure_link_module

secure_link $arg_st,$arg_e;

secure_link_md5 test$arg_e;

if ($secure_link = ""){

  return 402;

}

if ($secure_link = "0"){

  return 405;

}

#如果哈希不正确,$secure_link将为一个空字符串,状态码402。

#如果当前的时间晚于指定的过期时间,会返回0,状态码为405。

#一切正确的话$secure_link为1。

 

secure_link

语法:secure_link $md5_hash[,$expire_time]

默认值:none

使用字段:location

这个指令指定这个链接URL的MD5哈希值和过期时间,$md5_hash为基于URL的64位编码,$expired_time为自1970-01-01 00:00:00 UTC时间以来的秒数,如果你不增加$expire_time,那么这个URL永远不会过期。

secure_link_md5

语法:secure_link_md5 $the_uri_you_want_to_hashed_by_md5

默认值:none

使用字段:location

这个指令指定你需要通过MD5哈希的字符串,字符串可以包含变量,哈希值将和”secure_link”设置的$md5_hash变量进行比较,如果结果相同,$secure_link变量值为1,否则为空字符串。

生成链接的PHP代码如下:

<?php

$secret = 'test'; # 密钥

 $expire = time()+300; #5分钟后链接失效

 $md5 = base64_encode(md5($secret.$expire, true));

 $md5 = strtr($md5, '+/', '-_');

 $md5 = str_replace('=', '', $md5);

 echo '<a href=http://192.168.192.120/download/a.jpg?st='.$md5.'&e='.$expire.'>nginx-1.4.2</a>';

 ?>

访问生成的下载连接如下:http://192.168.192.120/download/a.jpg?st=wUht9FkhnfNI-KEGy81HFA&e=1487733535

如果修改st,会返回402。

如果超过5分钟后访问,会返回405。

 

0x03 ngx_http_referer_module

nginx模块ngx_http_referer_module通常用于阻挡来源非法的域名请求。需要注意的是有些合法的请求是不会带referer来源头部的,所以有时候不要拒绝来源头部(referer)为空的请求。

Nginx配置如下:

location ~* \.(gif|jpg|png|bmp)$ {

    valid_referers none blocked *.ttlsa.com server_names;

    if ($invalid_referer) {

        return 403;

    }

}

valid_referers [none|blocked|server_names] …

默认值:none

使用环境:server,location

该指令会根据Referer Header头的内容分配一个值为0或1给变量$invalid_referer。

如果Referer Header头不符合valid_referers指令设置的有效Referer,变量$invalid_referer

将被设置为1.

该指令的参数可以为下面的内容:

none

表示无Referer值的情况。

blocked

“Referer”来源头部不为空,但是里面的值被代理或者防火墙删除了,这些值都不以http://或者https://开头.

server_names

“Referer”来源头部包含当前的server_names(当前域名)