不使用 Varnish 限制故障率

不使用 Varnish 限制故障率

早上好,

在请求到达 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.sockUnix 域套接字发送所有后端请求。它还确保通信通过代理人协议,让生活变得更加轻松。

在 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"));
            }
        }
    }

相关内容