在 Discourse 中使用 Cloudflare 的最佳实践

使用 Cloudflare 部署 Discourse

:bookmark: 本指南介绍如何配置和使用 Cloudflare 部署 Discourse,包括安全最佳实践和故障排除技巧。

:person_raising_hand: 所需用户级别:管理员

:information_source: 自托管安装需要控制台访问权限

摘要

Cloudflare 可以通过 CDN 增强您的 Discourse 实例的性能,提供额外的安全层(如 DDoS 防护),并支持 HTTPS。本指南涵盖了设置过程和最佳实践,以实现最佳配置。

为什么要在 Discourse 中使用 Cloudflare

在 Discourse 实例中使用 Cloudflare 可带来多项关键优势:

:warning: 对于自托管安装,虽然 Cloudflare 提供了这些优势,但它会增加设置的复杂性。

设置 Cloudflare

  1. 熟悉 Cloudflare 基础知识
  2. 遵循 设置说明 为您的域名配置 Cloudflare,并获得 安全、性能和可靠性优势

配置最佳实践

DNS 设置

  • 确保指向您的 Discourse 实例的 DNS 记录已代理(proxied)
  • dash.cloudflare.com/?to=/:account/:zone/dns 访问 DNS 设置

SSL/TLS 配置

  • 将加密模式设置为“完全(严格)”(Full (strict))
  • dash.cloudflare.com/?to=/:account/:zone/ssl-tls 访问 SSL/TLS 设置

:warning: 不正确的 SSL/TLS 配置可能会导致重定向循环

缓存配置

  • 将缓存级别设置为“标准”(Standard)
  • dash.cloudflare.com/?to=/:account/:zone/caching/configuration 访问缓存设置

缓存规则

Cloudflare 已弃用页面规则,转而使用其现代的 规则 系统。使用 缓存规则 (Cache Rules)dash.cloudflare.com/?to=/:account/:zone/rules 创建以下规则:

  • community.example.com/session/* 将缓存级别设置为“绕过”(Bypass)
  • 配置 URL 规范化设置以规范化传入的 URL

网络设置

Cloudflare 在 dash.cloudflare.com/?to=/:account/:zone/network 的网络设置通常不会影响 Discourse 的功能。Discourse 不使用 WebSockets、gRPC 或 CF-IPCountry / True-Client-IP 标头。除非同一域上的其他软件需要特定配置,否则可以将这些设置保留为默认值。

WAF(Web 应用程序防火墙)设置

如果您的 Cloudflare 计划支持托管规则 (Managed Rules),请创建以下规则:

  1. 在发帖/编辑时跳过 WAF:
(starts_with(http.request.uri.path, "/posts") and http.request.method in {"POST" "PUT"})
  1. 对于数据资源管理器 (Data Explorer) 插件用户,在管理员查询时跳过 WAF:
((http.request.uri.path contains "/admin/plugins/explorer/queries/" or http.request.uri.path contains "/admin/plugins/discourse-data-explorer/queries/") and http.request.method eq "PUT")

对于两条规则:

  • 选择“跳过所有剩余规则”(Skip all remaining rules)
  • 启用“记录匹配的请求”(Log matching requests)

:information_source: 如果您使用的是商业版或更高版本,可以使用 matches 正则表达式运算符进行更精确的匹配。上面使用的 starts_withcontains 运算符适用于包括免费版和专业版在内的所有计划。

访问 dash.cloudflare.com/?to=/:account/:zone/firewall/managed-rules 处的 WAF 设置

内容优化

dash.cloudflare.com/?to=/:account/:zone/speed/optimization 配置以下内容:

  • 启用 Brotli
  • 禁用 Rocket Loader™

:warning: Discourse 经常收到网站宕机报告 是由于启用了 Rocket Loader™

自托管安装的附加配置

为确保正确的 IP 地址转发,请将以下内容添加到 containers/app.yml 的模板部分:

- "templates/cloudflare.template.yml"

:warning: 添加模板后,您必须使用 ./launcher rebuild app 重新构建容器以使更改生效。

相关内容:您如何设置 Cloudflare?

支持资源

故障排除

内容安全策略 (CSP) 问题

如果您遇到 CSP 错误:

  • 验证 Rocket Loader 是否已禁用
  • 检查脚本是否已正确添加到 content security policy script src 站点设置中

OneBox 功能

如果 OneBox 功能被阻止:

  • 检查是否启用了超级机器人大战模式 (Super Bot Fight Mode)
  • 如果“确定是自动”(Definitely automated) 设置为“托管”(Managed) 或“阻止”(Block),请进行调整
  • 考虑为 OneBox 用户代理创建自定义 WAF 规则
29 个赞

早上好,

感谢您提供的指南,我已严格按照指南操作,但遇到了一个问题。每次在我的控制台中激活 Cloudflare 时,我都会收到一个关于 CSP 的错误,提示(拒绝执行内联脚本,因为它违反了以下内容安全策略指令:“script-src),之后它会向我显示 CSP 中存在的网址:(需要“unsafe-inline”关键字、哈希值(“sha256-VCiGKEA…”)或随机数(“nonce-…”)才能启用内联执行。

我到处查找,但找不到除禁用代理以外的解决方案,禁用代理可以解决我的问题?

谢谢。

请检查 Rocket Loader 是否已关闭?

另外,请检查脚本是否已正确添加到 content security policy script src 网站设置中。

如果以上方法均无效,我建议您联系 Cloudflare,网址为 https://community.cloudflare.com/t/using-discourse-with-cloudflare-best-practices/602890。

1 个赞

感谢您 @nat@tcloonan 的分享。

这件事情在我待办事项列表上已经有一两年了,但我一直被这个主题下一些过时的帖子劝退 :smiley:

对于使用 AWS S3 进行存储和备份的人来说,有什么需要注意的问题或特别事项吗? :thinking:

您是否仍然需要在 app.yml 中使用 Cloudflare 模板来获取真实 IP 地址,或者这些年来是否已发生变化?

1 个赞

是的,你仍然需要 cloudflare 模板。没有它,所有流量都会显示来自 cloudflare 的服务器,而不是用户的浏览器 IP。

我没有在 OP 中看到它,这似乎是一个明显的疏漏。你是如何推断出你需要它的?

2 个赞

您好!我从 2014 年就开始接触这个领域(有些年份基本保持沉默),但自 2020 年以来,我一直在努力通过自定义导入器将我们的社区迁移过来,并且我们正在开发我们内部插件的第二版,以便将 bbob 作为 bbcode 引擎插入并启用到 Discourse 中。您可以在这里关注我们的进展:GitHub - RpNation/bbcode: RpNation's Official BBCode Implementation for Discourse

我一直在研究这个软件。我们确实使用 Cloudflare,所以自从我们现在可以开始担心那些不被视为障碍的、不太重要的事情以来,我一直在重新研究它与 discourse 是否存在任何问题。

@nat 您能否添加一个关于自托管实例模板的编辑!

4 个赞

已完成,感谢你们指出这一点!

4 个赞

非常感谢!这可能也是我的网站突然无法访问的原因。我可能对 Cloudflare 的设置玩得有点太多了。

由于我旧的域名提供商对 DNSSec 的支持不足且不正确,我不得不寻找新的。这时 Cloudflare 进入了我的视野。免费套餐对我来说完全足够了。可惜的是,套餐的定价并没有根据实际需求进行合理的扩展。

2 个赞

这是添加到这个位置吗?

1 个赞

为了准确起见,WAF 排除的查询是:

(http.request.uri.path eq "/posts(/[0-9]+)?" and http.request.method in {"POST" "PUT"})

如果您点击左侧的 Edit expression 而不是使用表单选择,您可以复制粘贴它。

今天我更新时注意到,由于自动最小化,一半的论坛无法正常工作 :weary:

编辑:刚注意到这是一个 wiki 帖子。我真傻,我已经编辑了初始帖子。

4 个赞

SSL/TLS 加密模式为“完全(严格)”。如果不关闭,会有问题吗?自动 SSL 不是本来就会定义吗?

另外,似乎当“Super Bot Fight Mode”开启且“Definitely automated”设置为“Managed”或“block”时,OneBox 功能会被阻止。

您可以通过为 Onebox 用户代理设置自定义 WAF 规则来绕过此问题,但也许有更安全的方法可以做到这一点?

相关内容

这部分可能需要更好的措辞:

@supermathie 建议:

您需要在 containers/app.yml 的模板部分末尾添加以下行。

如图所示:Using Discourse with Cloudflare: Best Practices - #11 by shawa

最好还能提供一个关于服务器配置中模板的通用操作指南链接,我一开始没有找到。

我建议在 Cloudflare 中关闭 AI 机器人。这可以在“安全”->“机器人”->“阻止 AI 机器人”下找到。

AI 机器人每天都在用 30,000 到 40,000 的页面浏览量攻击我的网站。启用此过滤器后,我的 AI 机器人流量显著下降。

5 个赞

上面的代码应更改为:

 - "templates/cloudflare.template.yml"

谢谢,
Major

2 个赞

WebSockets 支持是否真的应该在 Cloudflare 中启用?

我们多年来在没有它的情况下运行良好,而且据我在论坛上找到的信息,Discourse 并不使用 WebSockets。

我不明白我是否需要这样做

你说得对。我不认为我们使用 Websockets。

我已经将其删除,并更新了上面用户的模板代码片段。

2 个赞

顺便说一句,我认为整个网络设置对于 Discourse 来说都是不相关的:

  • IPv6 兼容性已无法禁用,当然 Discourse 也不依赖它,但完全可以在仅限 IPv4 的系统上运行。
  • IP 地理位置会将 CF-IPCountry 标头添加到请求中,但 Discourse 不会使用它。它使用自己的(可选)MaxMind 功能。
  • 网络错误日志记录会添加 Report-To 响应标头,浏览器可以使用它来报告错误。但是,它已被弃用,即使 Cloudflare 的所有套餐都可以启用该功能,但实际查看报告的仪表板元素仅在企业版套餐中可用。因此,在这种情况下,对于一些旧浏览器来说,这可能只是隐私退化和网络开销。
  • Onion Routing 增强了来自 Tor 网络的请求的隐私。Discourse 不会关心甚至不知道这一点。
  • 如果主机运行某些仅支持 IPv4 地址的软件(如旧版分析或类似软件),则可能需要伪 IPv4 功能。然后,可以调整 Cloudflare 的代理标头(如 Cf-Connecting-IP(或其他,取决于配置))以获得或多或少唯一的 IPv4 地址,而不是客户端的实际 IPv6 地址,以解决无法禁用客户端到 Cloudflare 请求的 IPv6 支持的问题。同样,Discourse 也不关心。我的意思是,这对于例如地理 IP 检测来说会是一个问题,但该功能默认是禁用的,并且管理员当然应该仅在他们运行的任何软件严格需要时才启用它,并接受非真实客户端 IP 的缺点。它也可以配置为仅添加一个带有伪 IPv4 地址的新标头,然后分析(或其他)请求可以在需要时重写客户端 IP 标头,而到 Discourse 的请求则不受影响。无论如何,对于 Discourse 的一般功能来说,该功能是无关紧要的。
  • True-Client-IP Header 除了 CF-Connecting-IPX-Forwarded-For 之外,还添加了这个标头。Discourse 不会使用它,Discourse 的配置模板也使用 CF-Connecting-IP 而不是它。所以它没有影响。
  • Discourse 不使用 gRPC,但启用 Cloudflare 来转发 gRPC 请求也没有坏处,与 WebSockets 相同。两者可能都需要为运行在同一 Cloudflare 域上的其他软件启用。
  • 最大上传大小 100 MB 是默认值和最小值。更大的上传大小需要商业版或企业版套餐,并且如果 Cloudflare 允许更大的上传,Discourse 不会中断。

唯一我不确定是否会产生影响的是响应缓冲。而且我无法测试,因为它是一个仅限企业版的独有功能。但我无法想象客户端会关心数据包是从 CF 边缘传入时流式传输的,还是在边缘完成时以一个块发送的。对于缓存的数据(我是指在 Cloudflare 缓存的数据),这总是会发生的,而且至少不会引起问题。此功能仅影响非缓存数据。

所以基本上,我会删除整个“网络设置”部分,因为它们与 Cloudflare 的功能无关,但其他软件可能需要某些设置,或者管理员可能希望它们以某种方式配置,并且应该知道 Discourse 在任何情况下都能正常运行。

1 个赞