Using Canasta with Cloudflare

From Canasta Wiki

This page gathers the configuration advice for running a Canasta instance behind Cloudflare. Cloudflare is one of the most common ways to put a public MediaWiki online β€” it terminates TLS at its edge, caches and shields the origin, and can absorb bot and DDoS traffic before it ever reaches your server. Because Cloudflare sits in front of Canasta's own Caddy edge, the two have to agree about who provisions the certificate and who handles the HTTP-to-HTTPS redirect β€” otherwise you get certificate failures (HTTP 525) or redirect loops.

The single most important decision is your Cloudflare SSL/TLS encryption mode, because it dictates how Canasta must be configured. Everything else on this page (locking down the origin, recovering the real visitor IP, blocking crawlers) is common to all modes.

Match the Cloudflare SSL/TLS mode to Canasta's TLS setting

In the Cloudflare dashboard, SSL/TLS β†’ Overview sets how Cloudflare talks to your origin. Prefer Full (strict) whenever you can β€” it is the only option that keeps traffic encrypted end to end, from the visitor all the way to your origin. Pick one of these two supported patterns:

Cloudflare mode Cloudflare β†’ origin Canasta configuration Origin port(s) needed
Full / Full (strict) β€” recommended HTTPS (encrypted) default (CADDY_AUTO_HTTPS=on) β€” Caddy obtains its own Let's Encrypt certificate 80 and 443
Flexible plain HTTP (unencrypted) CADDY_AUTO_HTTPS=off β€” Caddy serves HTTP only, no certificate 80

The two failure modes both come from mismatching these:

  • Full / Full (strict) + Caddy auto-HTTPS off β†’ Cloudflare tries HTTPS to the
 origin, but Caddy has no certificate on 443 β†’ HTTP 525 (SSL handshake failed).
  • Flexible + Caddy auto-HTTPS on β†’ Cloudflare sends HTTP, Caddy answers with a
 308 redirect to HTTPS, Cloudflare follows it back as HTTP again β€” a redirect loop:
 Client β†’ HTTPS β†’ Cloudflare β†’ HTTP:80 β†’ Caddy β†’ 308 HTTPS β†’ βœ—

Full and Full (strict) mode (recommended)

This is the most secure option and the one to use whenever you can: Cloudflare encrypts the connection to your origin, so HTTPS is preserved end to end β€” from the visitor all the way to Caddy. The origin must present a certificate, so leave Canasta at its default and Caddy provisions and renews a real Let's Encrypt certificate automatically. Because a Let's Encrypt certificate is publicly trusted, this works with both Full and Full (strict) β€” use Full (strict), which additionally validates the origin certificate, for the strongest protection.

For this to work:

  • Port 80 must be reachable from the public internet so Caddy can complete the
 ACME HTTP-01 challenge. Cloudflare automatically exempts
 /.well-known/acme-challenge/ from "Always Use HTTPS", so that redirect
 setting is fine to leave on.
  • Cloudflare security features must not challenge the ACME validator. If
 "Under Attack Mode" (Security Level) or "Bot Fight Mode" is on, Cloudflare returns
 a 403 to Let's Encrypt's validator, Caddy never gets a certificate, and the site
 returns 525. The fix is to turn those off (Caddy renews ~30 days before
 expiry, so they must stay off, not just during issuance). See #Troubleshooting.

Using a Cloudflare Origin CA certificate instead of Let's Encrypt is possible but not yet first-class in Canasta β€” it requires mounting your own cert and key into Caddy by hand. Support for custom certificates is tracked in issue #566; until then, the Let's Encrypt path above is the supported way to use Full mode.

Flexible mode (use only as a last resort)

Warning: in Flexible mode the connection between Cloudflare and your origin is plain, unencrypted HTTP. Visitors see a padlock in their browser, but the traffic between Cloudflare's edge and your server β€” including session cookies, login credentials, and anything posted to the wiki β€” crosses the public network in the clear, where it can be read or tampered with by anything on the path. Flexible gives you edge TLS only; it is not end-to-end encryption, and it is easy to mistake for a secure setup because the browser padlock looks identical. Use it only when you genuinely cannot run Full mode, and only when the Cloudflare-to-origin hop is itself private (e.g. both endpoints sit inside the same cloud VPC) and the origin is locked to Cloudflare's IPs (see below). When in doubt, use Full.

In Flexible mode Cloudflare holds the only certificate. Turn off Caddy's automatic HTTPS so it stops attempting Let's Encrypt and stops redirecting:

canasta config set -i myinstance CADDY_AUTO_HTTPS=off

You can also set it at create time in your env file (-e). Caddy then generates a Caddyfile with http:// site addresses and listens on port 80 only. This is the same switch described in Networking and TLS β€” it is not Cloudflare-specific (any TLS-terminating proxy in front needs it).

Lock the origin to Cloudflare

In every mode, your origin is still directly reachable on its public IP unless you restrict it. Configure your firewall or cloud security group to accept inbound traffic on the relevant ports (80 always; 443 too in Full mode) only from Cloudflare's published IP ranges. This prevents attackers from bypassing Cloudflare and hitting the origin directly.

Recover the real visitor IP

Behind Cloudflare, every request reaches your origin from a Cloudflare edge IP, so without this setting the real visitor address is lost. Tell Caddy to recover it from the CF-Connecting-IP header (which it trusts only from Cloudflare's own IP ranges, so a direct-to-origin client cannot spoof it):

canasta config set -i myinstance CADDY_TRUSTED_PROXIES=cloudflare

This is worth setting on every Cloudflare deployment, not only when CrowdSec is enabled. Once the real client IP is recovered:

  • Caddy's access log records the actual visitor instead of a Cloudflare edge IP.
  • The real IP is forwarded to MediaWiki, so anonymous-edit attribution, IP blocks
 (Special:Block), and rate limits apply to the visitor rather than to
 Cloudflare β€” without it, blocking one "IP" would block all Cloudflare traffic at
 once, and every anonymous edit would appear to come from Cloudflare.
  • CrowdSec, if enabled, bans the right addresses.

See Help:CrowdSec for more detail.

Blocking bots and crawlers

Cloudflare has its own bot-management features, but you can also combine them with Canasta's built-in defenses (CrawlerProtection, a Caddy User-Agent block, CrowdSec, and robots.txt). See Help:User journeys/Combatting bots and scrapers.

Verifying

# At the origin, with CADDY_AUTO_HTTPS=off (Flexible): expect 200, not 301/308
curl -s -o /dev/null -w "%{http_code}\n" http://localhost/

# Through Cloudflare: expect 200
curl -s -o /dev/null -w "%{http_code}\n" https://your-domain.example.com/

Troubleshooting

  • 525 (SSL handshake failed). Cloudflare can't establish TLS to the origin.
 Either you are in Full/strict mode but Caddy has no certificate (auto-HTTPS is off,
 or ACME is being blocked β€” see next item), or port 443 isn't open to Cloudflare.
  • 525 with Bot Fight Mode / Under Attack Mode on. Cloudflare's security
 challenge 403s Let's Encrypt's validator, so Caddy never gets a certificate. Turn
 both off (Security β†’ Settings and Security β†’ Bots) and leave them off so renewals
 keep working. A grey-cloud (DNS-only) bootstrap to issue the first certificate is a
 stopgap, but the security settings are the real fix because renewals need them too.
  • Redirect loop / "too many redirects". Flexible mode with Caddy still doing
 auto-HTTPS. Set CADDY_AUTO_HTTPS=off.
  • IPv6 is not the problem. Cloudflare always answers AAAA for proxied
 hostnames and it cannot be disabled; this is normal and not the cause of 525s.

See also