Cloudflare와 함께 Discourse 사용: 모범 사례

Cloudflare를 사용한 Discourse 설정

:bookmark: 이 가이드는 Cloudflare를 사용하여 Discourse를 구성하는 방법, 보안 모범 사례 및 문제 해결 팁을 설명합니다.

:person_raising_hand: 필요한 사용자 권한: 관리자

:information_source: 자체 호스팅 설치 환경에서는 콘솔 접근 권한이 필요합니다

요약

Cloudflare는 CDN을 통한 성능 향상, DDoS 보호와 같은 추가 보안 계층, 그리고 HTTPS 지원으로 Discourse 인스턴스를 강화할 수 있습니다. 이 가이드는 최적의 구성을 위한 설정 과정과 모범 사례를 다룹니다.

왜 Discourse에 Cloudflare를 사용해야 하는가

Discourse 인스턴스에 Cloudflare를 사용하면 다음과 같은 주요 이점이 있습니다:

  • 성능: Cloudflare의 CDN은 일반 자산에 대한 전 세계 접근성을 향상시켜 전역적으로 사용자 경험을 개선합니다 (출처)
  • 보안: 다음과 같은 추가 보호 계층을 제공합니다:

:warning: 자체 호스팅 설치 환경의 경우, Cloudflare가 이러한 이점을 제공하지만 설정에 복잡성을 더합니다.

Cloudflare 설정

  1. Cloudflare 기본 개념을 숙지합니다
  2. 설치 지침을 따라 도메인에 Cloudflare를 구성하고 보안, 성능, 신뢰성 이점을 얻습니다

구성 모범 사례

DNS 설정

  • Discourse 인스턴스로 가리키는 DNS 기록이 프록시되도록 확인합니다
  • 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는 최신 Rules 시스템을 권장하기 위해 Page Rules를 중단했습니다. dash.cloudflare.com/?to=/:account/:zone/rules에서 Cache Rules을 사용하여 다음을 생성합니다:

  • community.example.com/session/*에 대해 캐시 수준을 "Bypass"로 설정합니다
  • 수신 URL을 정규화하도록 URL 정규화 설정을 구성합니다

네트워크 설정

dash.cloudflare.com/?to=/:account/:zone/network의 네트워크 설정은 일반적으로 Discourse 기능에 영향을 미치지 않습니다. Discourse는 WebSockets, gRPC 또는 CF-IPCountry / True-Client-IP 헤더를 사용하지 않습니다. 동일한 도메인의 다른 소프트웨어가 특정 구성을 요구하지 않는 한 이러한 설정은 기본값으로 유지할 수 있습니다.

WAF(웹 애플리케이션 방화벽) 설정

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: Business 플랜 이상을 사용 중인 경우, 더 정확한 매칭을 위해 matches 정규식 연산자를 사용할 수 있습니다. 위에서 사용된 starts_withcontains 연산자는 Free와 Pro를 포함한 모든 플랜에서 작동합니다.

dash.cloudflare.com/?to=/:account/:zone/firewall/managed-rules에서 WAF 설정에 액세스합니다

콘텐츠 최적화

dash.cloudflare.com/?to=/:account/:zone/speed/optimization에서 다음을 구성합니다:

  • Brotli 활성화
  • Rocket Loader™ 비활성화

:warning: Rocket Loader™이 활성화되어 있어 사이트 다운 보고가 자주 접수되고 있습니다

자체 호스팅 설치 환경용 추가 구성

IP 주소 전달이 올바르게 이루어지도록 containers/app.yml의 templates 섹션에 다음을 추가합니다:

- "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 규칙 생성을 고려해 봅니다
30개의 좋아요

Good morning,

Thank you for this guide which I followed to the letter but I encounter a problem, each time I activate Cloudflare in my console I get an error with the CSP which displays to me (Refused to execute inline script because it violates the following Content Security Policy directive: "script-src) and after having indicated to me the urls present in my CSP: (Either the ‘unsafe-inline’ keyword, a hash (‘sha256-VCiGKEA…=’), or a nonce (‘nonce-…’) is required to enable inline execution.

I tried looking everywhere but I can’t find a solution other than disabling the proxy which solves my problem?

THANKS.

Can you check if rocket loader is turned off?

Another thing is to check that the scripts are appropriately added to content security policy script src site setting.

If none of these are working out, I suggest reaching out to Cloudflare @ https://community.cloudflare.com/t/using-discourse-with-cloudflare-best-practices/602890.

1개의 좋아요

Thanks for this @nat and @tcloonan

This has been on my list of things to do for a year or two, but I’ve been put off by the age of some of the older threads on this subject :smiley:

Any issues or special things for people using AWS S3 for storage and for backups? :thinking:

Do you still need the cloudflare template in app.yml for true IP addresses or has that changed over the years?

1개의 좋아요

Yes. You do need the cloudflare template. Without it, all traffic will appear to come from cloudflare’s servers rather than the user’s browser IP.

I don’t see it mentioned in the OP, which seems like a glaring omission. How did you infer that you needed it?

2개의 좋아요

Hi! Been around since 2014 (some years mostly silent) but have been working our getting our community migrated over since 2020 with a custom importer, and we are working on the second version of our in-house plugin to insert and enable bbob as a bbcode engine into Discourse. You can follow our progress here: GitHub - RpNation/bbcode: RpNation's Official BBCode Implementation for Discourse · GitHub

I’ve been breathing this software for a bit now. We do use Cloudflare, so I’ve been re-researching what if any issues it has with discourse, since we are now at the stage where I can start worrying about less vital things that are not considered blockers.

@nat Could you add an edit about the template for self-hosted instances!

4개의 좋아요

Done, thank you both for pointing this out!

4개의 좋아요

Thank you very much! That was probably also the reason why my site was suddenly no longer accessible. I must have played with the Cloudflare settings a bit too much.

Since my old domain provider only supported DNSSec inadequately & incorrectly, I had to look for something new. That’s when Cloudflare came to mind. The free plan is completely sufficient for me. It’s a shame that the tariffs don’t even scale reasonably to the requirements.

2개의 좋아요

Is it adding to this location?

1개의 좋아요

Just for accuracy, the query for the WAF exclusion is:

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

You can copy-paste it if you click on the Edit expression on the left instead of using the form selection.

Noticed today as I updated and suddenly half the forum wasn’t working due to Auto Minify :weary:

Edit: just noticed this is a wiki post. Silly me, I have edited the initial post.

4개의 좋아요

SSL/TLS encryption mode Full (strict). Will there be a problem if it is not closed? Won’t automatic SSL be defined anyway?

Just to add to this, seems the OneBox functionality is being blocked when Super Bot Fight Mode is on and the setting Definitely automated is set to Managed or block..

You can get around this by setting up a custom WAF rule for the Onebox user agent but perhaps there is a more secure way of doing this?

Related to

this part might need some better wording:

@supermathie Suggestion:

you will want to add the following line to the end of your templates section in containers/app.yml.

as illustrated in Using Discourse with Cloudflare: Best Practices - #11 by shawa

At best, a link to a general how-to about templates in server configuration could be provided also, which I was not able to find at first sight.

I would suggest turning off AI bots within Cloudflare. This can be found under security->bots->block AI bots.

The AI bots were hammering my site with 30K to 40K page views daily. After turning on this filter, my AI bot traffic significantly dropped.

5개의 좋아요

The above code should be changed to:

 - "templates/cloudflare.template.yml"

thanks,
Major

2개의 좋아요

Is it really true that WebSockets support should be enabled in Cloudflare?

Worked well for us without for years, and as far as I could find info here on the forum, Discourse does not make any use of WebSockets.

i dont understand if i have to do this

You are right. I don’t believe we use Websockets.

I’ve removed it, and also updated the template snippet from the user above.

2개의 좋아요

While on it, I think the whole Network settings are irrelevant for Discourse:

  • IPv6 compatibility cannot be disabled anymore, and of course Discourse does not depend on it, but can perfectly run on an IPv4-only system.
  • IP Geolocation adds the CF-IPCountry header to requests, which is however not used by Discourse. It uses its own (optional) MaxMind feature.
  • Network Error Logging adds the Report-To response header, which browsers can use to report errors to. It is however deprecated, and even that the feature can be enabled with all Cloudflare plans, the dashboard element to actually view the reports is available only with Enterprise plan. So in this case for some old browsers it might just be a privacy regression and network overhead.
  • Onion Routing enhances privacy for requests coming from the Tor network. Discourse won’t care or even know this.
  • The Pseudo IPv4 feature might even be needed if the host runs some software, like ancient analytics or similar, which supports IPv4 addresses only. The proxy headers of Cloudflare, like Cf-Connecting-IP (or others, depending on what one configures) can then be adjusted to have a moreless unique IPv4 address, instead of the actual IPv6 address of the client, to work around the fact that IPv6 support for client->Cloudflare requests cannot be disabled anymore. Again, Discourse won’t care. I mean it would be a problem for e.g. GeoIP detection, but the feature is disabled by default, and admins of course should enable it only, if strictly required by whichever software they run, accepting the downside of non-true client IPs. It can be also configured to only add a new header with the pseudo IPv4 address, and analytics (or whatever) requests can then rewrite client IP headers where needed, while requests to Discourse would not be affected. In any case, for Discourse functionality in general, the feature is irrelevant.
  • True-Client-IP Header adds just this header in addition to CF-Connecting-IP and X-Forwarded-For. Discourse does not make use of it, also the Discourse config template uses CF-Connecting-IP instead. So it has no effect.
  • gRPC is not used by Discourse, but having Cloudflare enabled to forward gRPC requests does not hurt either, same as with WebSockets. Both might be needed enabled for other software running on the same Cloudflare domain.
  • Maximum Upload Size 100 MB is default and minimum. Larger upload sizes require Business or Enterprise plans, and Discourse won’t break if Cloudflare allows larger uploads.

The only thing I am not sure about whether it can have an effect is Response Buffering. And I cannot test as it is an Enterprise-only feature. But I cannot imagine that the client cares whether packets are streamed form CF edge as they come in, or sent in one chunk ones compete at the edge. For cached data (cached at Cloudflare I mean), this is done always anyway, and there is does not cause issues, at least. This feature only affects non-cached data.

So basically I would remove the whole “Network settings” section as something which is irrelevant for Cloudflare functionality, but other software might require certain settings or admins might prefer them a certain way, and should know that Discourse will function in any case.

1개의 좋아요