Varnish 限制访问频率

Varnish 4 仍然没有内置的访问频率限制功能,要达到这一目的需要安装 vsthrottle VMOD。

这个 VMOD 可以从这里获取:https://github.com/varnish/libvmod-vsthrottle

可以使用源码目录中的 autogen.sh 利用 autotools 先生成 configure 脚本,然后再按照“./configure; make; make install”步骤安装好这个 VMOD(如果是使用官方 rpm 安装 Varnish 的话,还需要 varnish-libs-devel 这个包才能编译)。

安装好之后就可以在 vcl 配置里面使用它了。

vcl 4.0;

import vsthrottle;

sub vcl_recv {
        set client.identity = client.ip;
        if (vsthrottle.is_denied(client.identity, 15, 10s)) {
                # Client has exceeded 15 reqs per 10s
                return (synth(429, "Too Many Requests"));
        }
}

vsthrottle 的使用比较简单,只有一个“is_denied()”函数。函数原型为:

is_denied(STRING key, INT limit, DURATION period)

第一个 key 参数和 nginx 里面的 limit_req_zone 指令里面的 key 差不多,就是作为限制频率的依据。上面的配置里面我们按照客户端地址进行了访问限制,10s 内如果超过 15 次访问则给它返回 429 状态码——Too Many Requests。但是可以看到并没有直接将 client.ip 传递给 vsthrottle.is_denied,这是因为 key 参数必须是字符串类型,而 client.ip 则是个 IP 地址类型,只能将它先用 client.identity 保存起来后才能进行传递。key 的定义很灵活,我们可以把 req.http.User-Agent 等作为key,也可以利用类型转换,或者是 regsub 函数修改字符来作为 key。