Skip to content

CloudflareSupport stage

Protect the origin behind Cloudflare: allow-list, Authenticated Origin Pulls, or Tunnel

Allow-list, Authenticated Origin Pulls, or Cloudflare Tunnel: what each proves and costs, plus the nginx settings and rollout order to check first.

On this page13 sections

Short answer

How do you protect an origin server behind Cloudflare?

Treat an allow-list of Cloudflare’s IP ranges as a floor, not a wall: Cloudflare rates it moderately secure and open to IP spoofing. Add Authenticated Origin Pulls with a certificate you upload, so the origin accepts only requests tied to your account, or use Cloudflare Tunnel so the origin needs no inbound ports. Pair either with Full (strict) TLS.

Who this is for: engineers who run an nginx origin behind the Cloudflare proxy and want to know which control to use, in what order, and what breaks when it goes wrong. These are the settings we check first.

What does protecting the origin mean?

Making sure the only way to reach your application is through your Cloudflare zone, so the WAF, rate limits, and bot rules cannot be skipped by connecting to the origin IP directly. Cloudflare’s guide groups the controls into DNS, application, transport, and network layers.

The DNS points come first. Use proxied records to hide origin addresses, and rotate origin IPs after onboarding, because historical DNS records stay public. Review DNS-only, SPF, and other TXT records for leaked origin addresses, and if possible do not host mail on the same server: bounce messages can reveal its IP.

Which method should you use? The origin protection decision table

The origin protection decision table compares the controls. “What it proves” comes from Cloudflare’s documentation; the “When to use” column is our judgment.

Method What it proves Operating cost Weakness When to use
Allow-list of Cloudflare ranges The connection comes from a Cloudflare address Low; the list needs regular updates IP spoofing; the ranges are not exclusive to your account Always, as the floor
Authenticated Origin Pulls, global The request came from Cloudflare’s network; the certificate is not exclusive to your account Low: one certificate, one setting Does not tie the request to your zone A quick step for a legacy origin
Authenticated Origin Pulls, zone-level or per-hostname The request carries a certificate you uploaded, tied to your account Medium: you issue, upload, and rotate certificates An expired certificate is an outage you caused Internet-facing origins that keep a public IP
Cloudflare Tunnel Traffic reaches the origin only through outbound connections from cloudflared Medium: a connector to run and update A new component on the request path New builds, and origins that should have no public IP

Cloudflare rates the allow-list moderately secure, and both Authenticated Origin Pulls and Tunnel very secure. The default ranges are shared: egress addresses reserved for a single account are an Enterprise option. Treat the last two methods as alternatives for a given hostname, not as layers: Cloudflare documents that Authenticated Origin Pulls has no effect on hostnames served through a tunnel.

How do you restore the real visitor IP in nginx?

Behind the proxy, the TCP peer is always a Cloudflare address. Cloudflare passes the visitor’s address in the CF-Connecting-IP header and recommends it, or True-Client-IP (Enterprise only), over X-Forwarded-For, because each holds a single address. In nginx, the realip module replaces the client address, and set_real_ip_from lists “trusted addresses that are known to send correct replacement addresses”.

# one set_real_ip_from line per range, from https://www.cloudflare.com/ips-v4 and /ips-v6
set_real_ip_from 173.245.48.0/20;
# ...
real_ip_header CF-Connecting-IP;

Three rules follow. Trust only Cloudflare’s ranges; trusting more would let any client supply the header (our reading of the nginx definition). Regenerate the list on a schedule: Cloudflare says it needs regular updates, and its IPs page, intended as the definitive source, keeps an update history. If a load balancer sits between Cloudflare and nginx, trust that hop too and read X-Forwarded-For with real_ip_recursive on, which takes the last untrusted address instead of the last address.

How do Authenticated Origin Pulls work, and which mode do you pick?

Authenticated Origin Pulls (AOP) uses mutual TLS: Cloudflare presents a client certificate, and an origin configured to require one rejects connections without it. Cloudflare documents three separate modes; turning one on or off does not change the others.

Mode Certificate Precedence Setup note
Global Cloudflare’s, shared across accounts Lowest Download Cloudflare’s certificate and enable the setting
Zone-level One you upload, for all proxied traffic on the zone Over global Upload a leaf certificate; a root CA is rejected
Per-hostname One you upload, for specific hostnames Over zone-level and global Cannot use the global certificate

If you set up expiry notifications for uploaded zone-level or per-hostname certificates, Cloudflare sends them 30 and 14 days before expiry. AOP needs the SSL/TLS mode set to Full or Full (strict); it does not apply with Off or Flexible.

Safe rollout order. Cloudflare’s setup pages use two stages, optional and then on:

  1. For zone-level or per-hostname AOP, upload your client certificate and key to Cloudflare, and for per-hostname, associate the hostnames.
  2. Install the CA that signed it on the origin and point ssl_client_certificate at it.
  3. Set ssl_verify_client optional; and log $ssl_client_verify, which reads SUCCESS, FAILED:reason, or NONE.
  4. Enable AOP and confirm that requests show SUCCESS.
  5. Switch to ssl_verify_client on;.
  6. Send a request with curl directly to the origin IP: it should fail.

The Error 520 page lists AOP enabled on Cloudflare without the matching origin configuration among its causes. To roll back, return the origin to optional before changing the Cloudflare setting.

Why use Full (strict) with an Origin CA certificate?

Full (strict) validates what Full does not: the origin certificate must be unexpired, issued by a public authority or Cloudflare Origin CA, and match the hostname. An Origin CA certificate fits origins that receive traffic only through proxied records. It encrypts only the connection between Cloudflare and the origin, so visitors who reach the origin directly, after pausing Cloudflare or switching a record to DNS-only, may see certificate errors. It can carry up to 200 hostnames or wildcards, a wildcard covers one level, and Cloudflare does not currently send expiry notices for it: track the date in your own inventory or monitoring.

When is Cloudflare Tunnel the better choice?

When the origin can have no public IP at all. cloudflared opens outbound connections to Cloudflare, so you can configure the firewall to allow only that outbound traffic, on port 7844 over TCP and UDP, and block all inbound traffic. The cost is operational: you run and update one or more connectors on the request path. For an existing origin with a public IP, AOP adds no component to the request path, so it is usually the quicker first step; Tunnel fits when the platform is rebuilt.

What causes 520 and 524 errors at the origin?

A 524 means the origin did not send an HTTP response before Cloudflare’s Proxy Read Timeout, 125 seconds by default (Error 524 page, updated July 23, 2026). Enterprise zones can raise it to 6,000 seconds with a cache rule or the API, and a 30-second Proxy Write Timeout can also produce a 524. Cloudflare’s fixes: shorten long-running processes, use status polling, or move long requests to a DNS-only subdomain. Long work belongs in a background job that the client polls.

A 520 means the origin returned an empty, unknown, or unexpected response. Listed causes include crashes, firewalls that block Cloudflare, headers above 128 KB, missing headers, HTTP/2 configuration, and AOP misconfiguration.

Keep-alive matters too. Cloudflare reuses idle origin connections for up to 900 seconds and asks origins to enable keep-alive; its HTTP/2-to-origin page says some 520 and 522 errors can relate to idle timeouts. The nginx default keepalive_timeout is 75 seconds. When 520s appear sporadically, compare the origin’s timeout with Cloudflare’s before looking elsewhere.

What belongs in the origin’s Cache-Control and headers?

Make the origin’s Cache-Control the contract for caching. By default Cloudflare does not cache a response with Set-Cookie, or with private, no-store, no-cache, or max-age=0. The default cache key includes the query string, so tracking parameters can fragment the cache; exclude them with a cache rule.

A workable default: public, max-age=31536000, immutable for fingerprinted assets, no-cache or a short lifetime for HTML, and private, no-store for authenticated responses. Set HSTS and CSP in one place only: the origin, a response header Transform Rule, or Cloudflare’s HSTS setting, so two layers cannot send conflicting values.

The origin hardening checklist

  • Origin IP absent from DNS-only, SPF, and TXT records; rotated after onboarding.
  • Ports 80 and 443 open only to Cloudflare’s ranges, or no inbound ports with Tunnel.
  • Real visitor IP restored from CF-Connecting-IP, trusted only from Cloudflare’s ranges, list refreshed on a schedule.
  • SSL/TLS mode Full (strict); origin certificate expiry tracked.
  • AOP in the strictest mode you can operate; enforcement confirmed by a failed direct curl.
  • Origin timeouts and keep-alive reviewed against Cloudflare’s connection limits; long work moved to background jobs.
  • Cache-Control set by the origin per content type; no stray cookies on assets.
  • HSTS and CSP set in one place.

What this article has not tested

  • The nginx snippets follow the documentation; they were not re-run against a current nginx build for this article.
  • Per-hostname AOP with Cloudflare for SaaS custom hostnames; Cloudflare documents that zone-level certificates apply to them.
  • Apache and other web servers, and the effect of any control on latency.

FAQ

Is allow-listing Cloudflare IP ranges enough to protect my origin?

No. Cloudflare rates allow-listing moderately secure and notes that it is vulnerable to IP spoofing, and the default ranges are not reserved for your account. Keep the allow-list as a floor, then add Authenticated Origin Pulls with your own certificate, or move the origin behind Cloudflare Tunnel so it has no inbound ports at all.

Does global Authenticated Origin Pulls prove the request came through my zone?

No. Cloudflare’s global certificate is not exclusive to your account, so it shows only that the request came from Cloudflare’s network. For stronger assurance, upload your own certificate and use zone-level or per-hostname Authenticated Origin Pulls, which tie the request to your account, and watch for the expiry notices Cloudflare sends.

Can I enable Authenticated Origin Pulls with SSL/TLS mode Flexible?

No. Cloudflare says Authenticated Origin Pulls does not apply when the encryption mode is Off or Flexible, and its setup pages require Full or higher. Move to Full (strict) first, with a public certificate or a Cloudflare Origin CA certificate on the origin, then enable Authenticated Origin Pulls in its two stages.

If I use Tunnel, do I still need a firewall?

Yes, to enforce the model. With Tunnel, you can allow only the outbound connections that cloudflared makes and block all inbound traffic, so every route to the origin passes through the tunnel. Authenticated Origin Pulls adds nothing there: Cloudflare documents that it has no effect on hostnames served through a tunnel.

Sources

Checked against vendor documentation on How the articles are checked

  1. Protect your origin serverdevelopers.cloudflare.comread
  2. Dedicated CDN egress IPsdevelopers.cloudflare.comread
  3. Cloudflare HTTP headersdevelopers.cloudflare.comread
  4. Restoring original visitor IPsdevelopers.cloudflare.comread
  5. Cloudflare IP rangescloudflare.comread
  6. Authenticated Origin Pulls (mTLS)developers.cloudflare.comread
  7. Authenticated Origin Pulls setup: globaldevelopers.cloudflare.comread
  8. Authenticated Origin Pulls setup: zone-leveldevelopers.cloudflare.comread
  9. Authenticated Origin Pulls setup: per-hostnamedevelopers.cloudflare.comread
  10. Full (strict)developers.cloudflare.comread
  11. Origin CA certificatesdevelopers.cloudflare.comread
  12. Cloudflare Tunneldevelopers.cloudflare.comread
  13. Tunnel with a firewalldevelopers.cloudflare.comread
  14. Error 520developers.cloudflare.comread
  15. Error 524developers.cloudflare.comread
  16. Connection limitsdevelopers.cloudflare.comread
  17. HTTP/2 to origindevelopers.cloudflare.comread
  18. Default cache behaviordevelopers.cloudflare.comread
  19. Cache keysdevelopers.cloudflare.comread
  20. HTTP Strict Transport Securitydevelopers.cloudflare.comread
  21. nginx ngx_http_realip_modulenginx.orgread
  22. nginx ngx_http_ssl_modulenginx.orgread
  23. nginx ngx_http_core_module (keepalive_timeout)nginx.orgread
  24. Hardening the origin behind Cloudflare (author’s original write-up)aboutme.sabersecurity.cloudread

About the author

Eduard Agopyan

Founder & Principal Architect, Saber Security · Sofia, Bulgaria

Eduard Agopyan is the founder and principal architect of Saber Security, a network, security, and cloud engineering company headquartered in Sofia, Bulgaria. Eduard has more than seven years of experience building and operating secure networks across on-premises and multi-cloud environments, and sets the architecture standards behind Saber Security’s work on networks, cloud connectivity, edge security, Zero Trust, and automation.

Need help with the work itself?

The articles describe the method. If you want our engineers to apply it to your environment, start with a few lines about what you run today.

    No results