Skip to content

fix(ingress): trust CF-Connecting-IP only from Cloudflare ranges - #4444

Merged
Aleksei Sviridkin (lexfrei) merged 1 commit into
mainfrom
fix/ingress-cloudflare-real-ip-cidr
Sep 24, 2026
Merged

Aleksei Sviridkin (lexfrei) merged 1 commit into
mainfrom
fix/ingress-cloudflare-real-ip-cidr

Conversation

@lexfrei

@lexfrei Aleksei Sviridkin (lexfrei) commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

What this PR does

With cloudflareProxy: true on a tenant Ingress app, any client that reaches the load balancer directly can pick its own source address by sending a CF-Connecting-IP header, and that address is what whitelist-source-range checks. So the tenant whitelist, and any per-Ingress whitelist behind the same controller, can be bypassed with one header.

The chart passes the Cloudflare ranges to the controller as set_real_ip_from. That is an nginx directive, not an ingress-nginx ConfigMap key, so the controller drops it without a warning. use-forwarded-headers: "true" turns the realip module on, and it then trusts every source from the default proxy-real-ip-cidr, which is 0.0.0.0/0 (ingress-nginx v1.11.5, internal/ingress/controller/config/config.go and the set_real_ip_from loop in nginx.tmpl). This has been the case since the option was added.

The fix renames the key to proxy-real-ip-cidr. Traffic that comes through Cloudflare keeps the visitor address as before. A direct connection keeps its own address, whatever it puts in the header. If something between Cloudflare and the controller rewrites the source address, the header stops being trusted and the whitelist sees that hop instead; that is the correct result for a header that can only be trusted from known senders.

The new test checks that the trusted ranges land under the key the controller reads, that they are not a catch-all, and that set_real_ip_from is gone.

Screenshots

No UI change.

Downstream repositories

Template-only change in packages/extra/ingress: no values key, schema, package, platform, installer or hack/ change, so nothing in the trigger map is reached.

Release note

fix(ingress): with `cloudflareProxy` enabled, `CF-Connecting-IP` is now trusted only from Cloudflare's address ranges. Before, the Cloudflare ranges were passed under a key ingress-nginx ignores, so any client reaching the load balancer directly could set the header and get past the ingress `whitelist`.

Summary by CodeRabbit

  • Bug Fixes
    • Updated Cloudflare proxy IP configuration to use ingress-nginx’s supported setting, preserving forwarded-header and client IP handling.
    • Ensured Cloudflare proxy IP ranges remain configured when a whitelist is set.

cloudflareProxy passed the Cloudflare ranges to the controller under
set_real_ip_from, which is an nginx directive and not an ingress-nginx
ConfigMap key, so the controller dropped it without a warning. With
use-forwarded-headers on, the realip module then trusted every source
from the default proxy-real-ip-cidr of 0.0.0.0/0, and any client that
reached the load balancer directly could set CF-Connecting-IP to an
address of its choice. That address is what whitelist-source-range
checks, so the tenant whitelist, and any per-Ingress one, could be
walked past with one header.

proxy-real-ip-cidr is the key the controller reads for the trusted
ranges.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <[email protected]>
@coderabbitai

coderabbitai Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Repository: cozystack/cozystack/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 0e44c3ac-8101-4008-8c3a-c17299e305f3

📥 Commits

Reviewing files that changed from the base of the PR and between 5f5d8e9 and 3800f63.

📒 Files selected for processing (2)
  • packages/extra/ingress/templates/nginx-ingress.yaml
  • packages/extra/ingress/tests/cloudflare_proxy_test.yaml
 __________________________________________________
< Are you not entertained? By the bugs I've found? >
 --------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added area/networking Issues or PRs related to networking (ingress, gateway, vpn, metallb, kube-ovn) kind/bug Categorizes issue or PR as related to a bug size/M This PR changes 30-99 lines, ignoring generated files labels Sep 24, 2026
@lexfrei Aleksei Sviridkin (lexfrei) added the kind/backport Categorizes issue or PR as requiring a backport to the current release line label Sep 24, 2026
@lexfrei
Aleksei Sviridkin (lexfrei) marked this pull request as ready for review September 24, 2026 13:08
@lexfrei
Aleksei Sviridkin (lexfrei) merged commit 4b6933c into main Sep 24, 2026
25 of 27 checks passed
@lexfrei
Aleksei Sviridkin (lexfrei) deleted the fix/ingress-cloudflare-real-ip-cidr branch September 24, 2026 13:10
@github-actions

Copy link
Copy Markdown

Successfully created backport PR for release-1.6:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/networking Issues or PRs related to networking (ingress, gateway, vpn, metallb, kube-ovn) kind/backport Categorizes issue or PR as requiring a backport to the current release line kind/bug Categorizes issue or PR as related to a bug size/M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants