使用 Cloudflare 配置 Discourse
本指南详细说明了如何配置和使用 Cloudflare 与 Discourse,包括安全最佳实践和故障排除技巧。
本文由林青枫翻译并且发布于星语思源社区,转载请注明作者。
所需用户级别:管理员
概述
Cloudflare 可以通过 CDN 提升您的 Discourse 服务器的性能,提供额外的安全层如 DDoS 保护和 HTTPS 支持。本指南涵盖了设置过程和最佳实践,以实现最佳配置。
为什么将 Cloudflare 与 Discourse 一起使用
将 Cloudflare 与您的 Discourse 实例结合使用可以带来几个关键好处:
- 性能:Cloudflare 的 CDN 可以改善全球对常见资产的访问,提升全球用户体验(来源)
- 安全性:额外的保护层包括:
- DDoS 保护(来源)
- HTTPS 支持(来源)(作为 Discourse 的 Let’s Encrypt 设置 的替代方案)
设置 Cloudflare
- 熟悉 Cloudflare 基础知识
- 按照 设置说明 为您的域配置 Cloudflare,并获得 安全性、性能和可靠性优势
配置最佳实践
DNS 设置
- 确保指向您的 Discourse 实例的 DNS 记录已代理
- 在
dns
访问 DNS 设置
SSL/TLS 配置
- 在
ssl-tls
访问 SSL/TLS 设置 - 将加密模式设置为“完全(严格)”
不正确的 SSL/TLS 配置可能导致重定向循环
缓存配置
- 在
缓存
访问缓存设置 - 将缓存级别设置为“标准”
页面规则
在规则
页面创建以下页面规则:
- 将缓存级别设置为“绕过”
community.example.com/session/*
- 配置规则设置以规范化传入的 URL
网络设置
在 网络
配置以下内容:
启用:
- IPv6 兼容性
- WebSockets
- IP 地理定位
- 网络错误日志
- 洋葱路由
禁用:
- 伪 IPv4
- 响应缓冲
- 真客户端 IP 头
- gRPC
根据您的站点策略设置最大上传大小(建议 100 MB)
WAF(Web 应用防火墙)设置
如果您的 Cloudflare 计划支持托管规则(免费版本也支持),请创建以下规则:
- 在创建/编辑帖子时跳过 WAF:
在安全性
访问 WAF 设置
(http.request.uri.path eq "/posts(/[0-9]+)?" and http.request.method in {"POST" "PUT"})
- 对于 [ Data Explorer] 插件用户,在管理员查询时跳过 WAF:
(http.request.uri.path contains "/admin/plugins/explorer/queries/" and http.request.method eq "PUT")
对于这两个规则:
- 选择“跳过所有剩余规则”
- 启用“记录匹配请求”
内容优化
在 优化
配置以下内容:
- 启用 Brotli(默认启用,不用找了)
- 禁用 Rocket Loader™
- 禁用自动压缩
由于启用了 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引用模板中去,
重建容器即可。