Varnish 在 ACL 较大的情况下启动缓慢

Varnish 在 ACL 较大的情况下启动缓慢

我有一个 varnish 配置文件,如下所示:

 backend web1 { .host = "1.2.3.1" ; ... }
 backend web2 { .host = "1.2.3.2" ; ... }
 backend web3 { .host = "1.2.3.3" ; ... }
 backend web4 { .host = "1.2.3.4" ; ... }


 director default_director round-robin {
   { .backend = web1; }
   { .backend = web2; }
   { .backend = web3; }
   { .backend = web4; }
 }

 include "blacklist.vcl";

 sub vcl_recv
 {
     if (client.ip ~ blacklist ) {
          error 403 "You're blacklisted";
     }
     ..
 }

显然,黑名单条目包含我不想访问我的服务器的网站。

不幸的是,我的黑名单文件很大,并且每天/每周都变得越来越大:

  $ wc -l varnish/blacklist.vcl 
  6664 varnish/blacklist.vcl

我已经从阻止 /32s 切换到阻止 /24s 以缩短列表,但我仍然发现无法在不到 5 秒的时间内重新启动 varnish。

我还能做什么来加载黑名单?我知道我可以使用 iptables,但对于如此大的条目来说,这也很慢 - 因为当有任何更改时我必须将它们全部清除并重新加载它们。

答案1

如果您只想解决重新启动 Varnish 所需的时间,这可能不是您想要的 - 但对于重新加载配置,我有以下解决方案给您;

Varnish 配置会转换为 C 源代码,并在加载时进行编译。因此,加载配置所需的时间包括编译时间。这很可能就是导致您等待时间过长的原因。

您可以使用 varnishadmin 加载新配置,如下所示:

# varnishadm
vcl.load my_alias_2013-04-13 /etc/varnish/config.vcl
vcl.use my_alias_2013-04-13

如果 VCL 存在语法错误,上述操作还将产生非常有用的调试信息。它不会清除缓存,也不会中断服务。vcl.use 基本上会加载构建的 .so 文件并更改内存中的某些指针 - 这使得在运行时非常容易执行此操作,而无需重新启动整个服务。

答案2

Varnish 在这方面尤其糟糕,它生成的执行此操作的 C 代码实际上是线性搜索——就像向 iptables 添加单独的规则一样糟糕。

但是你使用 iptables 并使其速度更快。

使用ipset相反。IPSets 是 ips 的快速哈希查找,它可以非常快速地在大量地址中查找 ip。

使用以下命令创建一个 ipset:

ipset create myset hash:ip

这将生成您放置地址的集合。

接下来,将您的 IP 添加到集合中。

ipset add myset 1.1.1.1
ipset add myset 1.1.1.2
ipset add myset 1.1.1.3
ipset add myset 1.1.1.4
...

最后,向IPtables添加一条规则,使用该集合进行匹配。

iptables -N VARNISH_BL
iptables -I VARNISH_BL -m set --match-set myset src -j REJECT
iptables -I INPUT -m tcp -p tcp --dport 80 -m conntrack --ctstate NEW -j VARNISH_BL
iptables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

您可以转储该集合以便稍后重新初始化(例如在重新启动后),并将ipset save myset其打印到标准输出。当然,您也可以随时使用 向该集合添加更多 IP ipset add

另外,您可能实际上希望 IP 黑名单自动过期。ipset也可以通过为在创建时添加到集合中的任何 IP 指定默认超时来做到这一点:ipset create myset hash:net timeout 86400

默认情况下,一组中最多允许 65535 个主机,但请查看手册页,您可以使用参数创建更大的集合maxelem

相关内容