Skip to content

使用 Cloudflare Zero Trust 制作 Google Safe Browsing 平替

Published: at 22:48

之前做 L(O*62).ONG 的第一版时,使用的服务端跳转,上线第二天就被 Google 警告了安全风险,只能改成本地跳转提醒后跳转再去申诉。

Google警告

对于这种场景最好的做法是使用 Google Safe Browsing 来做跳转,但是 Safe Browsing 有使用限制,每天只能调用 10000 次,而且不支持自定义名单。由于我只想依赖 Cloudflare 一个平台就没有使用 Google Safe Browsing。

前段时间和一个网友交流的时候,突然脑洞大开,想到使用带成人和非法网站过滤的安全 DNS 服务器来做域名安全性的检查。 于是使用 家庭版 1.1.1.1 做了一下尝试发现是可行的。 但是 1.1.1.1 不支持自定义名单,想到之前在 HomeLab 用过 Cloudflare Zero Trust Gateway 就去研究了一下,发现了这个几乎完美的方案。

Cloudflare Zero Trust 提供的 Gateway 自带 DNS(DoH) 服务器,而且可以配置防火墙规则,支持按域名风险等级、内容分类、自定义名单等多种规则屏蔽解析。而且它收集的数据源来自 Cloudflare 专有数据、30 多个开放情报源、机器学习模型、社区反馈等,可以说是相当齐全了。 更多的细节可以在官方文档查看。

我屏蔽了高风险分类、成人、赌博、政府、少儿不宜、新注册等高风险的域名,并且手动维护了一些黑名单和白名单。

风险名单

配置完成以后就可以得到一个 DoH 地址:

DoH

我们使用下面的代码接入到项目中:

async function isSafeUrl(
  url,
  DoH = "https://family.cloudflare-dns.com/dns-query"
) {
  let safe = false;
  try {
    const { hostname } = new URL(url);
    const res = await fetch(`${DoH}?type=A&name=${hostname}`, {
      headers: {
        accept: "application/dns-json",
      },
      cf: {
        cacheEverything: true,
        cacheTtlByStatus: { "200-299": 86400 },
      },
    });
    const dnsResult = await res.json();
    if (dnsResult && Array.isArray(dnsResult.Answer)) {
      const isBlock = dnsResult.Answer.some(
        answer => answer.data === "0.0.0.0"
      );
      safe = !isBlock;
    }
  } catch (e) {
    console.warn("isSafeUrl fail: ", url, e);
  }
  return safe;
}

Cloudflare Zero Trust 管理面板也提供了一个可视化的界面,方便查屏蔽情况。可以看到一些成人网站和新注册域名都被屏蔽了。

可视化界面

如果域名被封了,还可以在日志查看原因。

日志