使用 Cloudflare 配置 Discourse——最佳设置

使用 Cloudflare 配置 Discourse

:bookmark: 本指南详细说明了如何配置和使用 Cloudflare 与 Discourse,包括安全最佳实践和故障排除技巧。

:heart:本文由林青枫翻译并且发布于星语思源社区,转载请注明作者。
:person_raising_hand: 所需用户级别:管理员

概述

Cloudflare 可以通过 CDN 提升您的 Discourse 服务器的性能,提供额外的安全层如 DDoS 保护和 HTTPS 支持。本指南涵盖了设置过程和最佳实践,以实现最佳配置。

为什么将 Cloudflare 与 Discourse 一起使用

将 Cloudflare 与您的 Discourse 实例结合使用可以带来几个关键好处:

设置 Cloudflare

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

配置最佳实践

DNS 设置

  • 确保指向您的 Discourse 实例的 DNS 记录已代理
  • dns 访问 DNS 设置

SSL/TLS 配置

  • ssl-tls 访问 SSL/TLS 设置
  • 将加密模式设置为“完全(严格)”

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

缓存配置

  • 缓存访问缓存设置
  • 将缓存级别设置为“标准”

页面规则

规则页面创建以下页面规则:

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

网络设置

网络配置以下内容:

启用:

  • IPv6 兼容性
  • WebSockets
  • IP 地理定位
  • 网络错误日志
  • 洋葱路由

禁用:

  • 伪 IPv4
  • 响应缓冲
  • 真客户端 IP 头
  • gRPC

根据您的站点策略设置最大上传大小(建议 100 MB)

WAF(Web 应用防火墙)设置

如果您的 Cloudflare 计划支持托管规则(免费版本也支持),请创建以下规则:

  1. 在创建/编辑帖子时跳过 WAF:

安全性访问 WAF 设置

(http.request.uri.path eq "/posts(/[0-9]+)?" and http.request.method in {"POST" "PUT"})
  1. 对于 [ Data Explorer] 插件用户,在管理员查询时跳过 WAF:
(http.request.uri.path contains "/admin/plugins/explorer/queries/" and http.request.method eq "PUT")

对于这两个规则:

  • 选择“跳过所有剩余规则”
  • 启用“记录匹配请求”

内容优化

优化配置以下内容:

  • 启用 Brotli(默认启用,不用找了)
  • 禁用 Rocket Loader™
  • 禁用自动压缩

:warning: 由于启用了 Rocket Loader™,Discourse 经常收到站点宕机报告(来源

自托管安装的额外配置

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

cloudflare.template.yml

并且在服务端重建容器。

相关内容:如何设置 Cloudflare?

支持资源

故障排除

内容安全策略(CSP)问题

如果遇到 CSP 错误:

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

OneBox 功能

如果 OneBox 被阻止:

  • 检查是否启用了自动程序攻击模式(在安全——自动化选项卡)
  • 如果设置为“托管”或“阻止”,请调整“绝对自动化”设置
  • 考虑为 OneBox 用户代理创建自定义 WAF 规则

报错解决

官方镜像中的cloudflare.template.yml文件会导致报错,我自己也踩了这个坑,解决方法如下:
/var/discourse/templates文件夹下,创建一个新的模板文件,命名为cloudflare-static.template.yml

run:
  - file:
      path: /tmp/add-cloudflare-ips
      chmod: +x
      contents: |
        #!/bin/bash -e
        cat <<EOF > /tmp/cloudflare-ips
        173.245.48.0/20
        103.21.244.0/22
        103.22.200.0/22
        103.31.4.0/22
        141.101.64.0/18
        108.162.192.0/18
        190.93.240.0/20
        188.114.96.0/20
        197.234.240.0/22
        198.41.128.0/17
        162.158.0.0/15
        104.16.0.0/13
        104.24.0.0/14
        172.64.0.0/13
        131.0.72.0/22
        2400:cb00::/32
        2606:4700::/32
        2803:f800::/32
        2405:b500::/32
        2405:8100::/32
        2a06:98c0::/29
        2c0f:f248::/32
        EOF
        # Make into nginx commands and escape for inclusion into sed append command
        CONTENTS=$(</tmp/cloudflare-ips sed '/^$/d; s/^.*/set_real_ip_from &;/' | tr '\n' '\\' | sed 's/\\/\\n/g')
        
        echo CloudFlare IPs:
        echo $(echo | sed "/^/a $CONTENTS")
        # Insert into discourse.conf
        sed -i "/sendfile on;/a $CONTENTS\nreal_ip_header CF-Connecting-IP;" /etc/nginx/conf.d/discourse.conf
        # Clean up
        rm /tmp/cloudflare-ips

  - exec: "/tmp/add-cloudflare-ips"
  - exec: "rm /tmp/add-cloudflare-ips"

里面是cloudflare的IPv4和IPv6地址,根据实际情况去更新即可。
https://www.cloudflare.com/ips-v4
https://www.cloudflare.com/ips-v6

然后把这个文件cloudflare-static.template.yml输入到 app.yml引用模板中去,
重建容器即可。