早上好,
在请求到达 Varnish 之前,有没有办法在 Hitch 上实现每个站点和每个 IP 的速率限制?
我尝试使用 Varnish 速率限制来处理一些 DoS 攻击,但是在 Varnish 阻止 HTTP 请求之前,DoS 会使 Varnish 和 Hitch 之间的连接过载。
谢谢。
答案1
Hitch 没有速率限制机制,但也不容易出现高负载。Hitch 可以在单台机器上处理超过 100 Gbps 的速率,因此这应该不是问题。
但是,您提到了 Hitch 和 Varnish 之间的连接饱和。
这两个组件是否托管在同一台机器上?如果是,您可以通过 Unix 域套接字进行通信。这可以减轻该连接的压力,并允许您在 Varnish 级别进行速率限制。
在 Hitch 中设置 UDS 后端连接
在您的hitch.conf
文件中,您可以按如下方式设置后端:
backend = "/var/run/varnish.sock"
write-proxy-v2 = on
此配置将通过/var/run/varnish.sock
Unix 域套接字发送所有后端请求。它还确保通信通过代理人协议,让生活变得更加轻松。
在 Varnish 中设置 UDS 连接
为了让 Hitch 通过 UDS 向 Varnish 发送数据,Varnish 需要监听该套接字。
下面是一个添加额外监听端口的示例/var/run/varnish.sock
:
varnishd -a /var/run/varnish.sock,PROXY,user=varnish,group=varnish,mode=660 \
-a :80 \
-s malloc, 256m \
-f /etc/varnish/default.vcl
其他参数只是为了使示例看起来更真实。主要关注的是-a
。
速率限制
Varnish 有一个速率限制模块,称为vsthrottle
。默认情况下不安装它,但可以通过以下方式访问https://github.com/varnish/varnish-modules。
编译并安装模块集合后,您可以使用以下 VCL 代码来限制传入请求的速率:
vcl 4.0;
import vsthrottle;
backend default { .host = "192.0.2.11"; .port = "8080"; }
sub vcl_recv {
# Varnish will set client.identity for you based on client IP.
if (vsthrottle.is_denied(client.identity, 15, 10s, 30s)) {
# Client has exceeded 15 reqs per 10s.
# When this happens, block altogether for the next 30s.
return (synth(429, "Too Many Requests"));
}
# There is a quota per API key that must be fulfilled.
if (vsthrottle.is_denied("apikey:" + req.http.Key, 30, 60s)) {
return (synth(429, "Too Many Requests"));
}
# Only allow a few POST/PUTs per client.
if (req.method == "POST" || req.method == "PUT") {
if (vsthrottle.is_denied("rw" + client.identity, 2, 10s)) {
return (synth(429, "Too Many Requests"));
}
}
}