What the check looks at
B1 compares two values on the same request. REMOTE_ADDR is the address the web server hands to PHP, and the one WordPress and most plugins record. CF-Connecting-IP (or CF-Connecting-IPv6) is the header in which Cloudflare passes on the address of the visitor.
The request is your own visit to the admin when there is one, otherwise a test request your server sends to its own site, otherwise a stored visit no older than 7 days. The order of the tests matters: a match is checked first, then a private address, then whether REMOTE_ADDR belongs to a Cloudflare range from the list the plugin ships.
Like every request Edge Doctor sends, these go only to the hosts of your Site Address and WordPress Address (home_url() and site_url()). An address WordPress gives on another host, such as a single sign on page, is never requested.
Results and what they mean
| Result | What it means |
|---|---|
| PassedConfidence: High | Your server sees the real visitor address The address your server records matches the one Cloudflare reports. |
| WarningConfidence: High | Your server sees Cloudflare instead of your visitorsREMOTE_ADDR is a Cloudflare address. Every visitor arrives looking like Cloudflare. |
| Could not checkConfidence: Medium | This check could not be completed The address your server records is neither the visitor address nor a Cloudflare address, so something else sits in between, such as a proxy or load balancer of your host. |
| Could not checkConfidence: Low | This check could not be completed No request with Cloudflare headers could be read. See the reasons below. |
| Not applicable | A local proxy or tunnel sits in front of your server, and B3 reports on itREMOTE_ADDR is a private address. Reason covered_by_other_check. |
| Not applicable | Cloudflare is not in front of this site Check A1 did not detect Cloudflare, so this check sent no request. Reason not_behind_cloudflare. |
When the result names a reason
token_missing: The test request never reached your server, so there was nothing to compare. On B1 it also covers the case with Medium confidence: an address that is neither the visitor nor Cloudflare.no_snapshot: This check needs a recent visit through Cloudflare. Open the Edge Doctor report once and it will have one. Scheduled runs and WP-CLI have no visitor request; opening the report once in the admin stores one.qs_ignored: Your cache key ignores the query string, so the plugin cannot test a page without risking a cached copy of it. Before it asks for any private address, the plugin requests your home page twice with a different unique query string. If either answer is aHIT, your cache key ignores the query string, and a test request could store a private page under an address visitors use. So the plugin stops and sends nothing.covered_by_other_check: Another check already reports on this. A privateREMOTE_ADDRmeans a proxy or Cloudflare Tunnel on the server, which check B3 reports.not_behind_cloudflare: This site is not behind Cloudflare. B1 also uses it when the request it read carried no Cloudflare headers.
Symptoms you may notice
- Comments, orders and logs show the same handful of addresses, all from Cloudflare ranges.
- A security plugin that blocks one attacker blocks everybody who arrives through that Cloudflare address, and login limits trip for visitors who did nothing.
- Rate limits and anything else that depends on the visitor address work with the wrong one.
Why it happens
Cloudflare sits between the visitor and your server, so the connection your server sees comes from a Cloudflare address. “The original visitor IP address appears in an appended HTTP header called” CF-Connecting-IP (Cloudflare: restoring original visitor IPs). Unless the web server is told to use that header, PHP keeps the Cloudflare address.
Confirm it by hand
1. See your own address as Cloudflare sees it. Open https://example.com/cdn-cgi/trace on your site. The ip= line is your address.
2. See what your server recorded for the same visit. Look for your request in the server access log, or post a test comment while logged out and read the address WordPress shows next to it under Comments.
If the recorded address differs from yours and falls in one of the ranges at cloudflare.com/ips, the server sees Cloudflare.
How to fix it
In the Cloudflare dashboard there is nothing to change. Cloudflare already sends CF-Connecting-IP; the fix is on the web server, where it reaches every plugin and the logs at once.
Apache with mod_remoteip, one trusted line per Cloudflare range:
RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxy 173.245.48.0/20
# ...one RemoteIPTrustedProxy line for every range at https://www.cloudflare.com/ips/Nginx with ngx_http_realip_module:
set_real_ip_from 173.245.48.0/20;
# ...one set_real_ip_from line for every range at https://www.cloudflare.com/ips/
real_ip_header CF-Connecting-IP;Trust only Cloudflare ranges. Cloudflare warns that otherwise the header could be spoofed by anybody who reaches the server directly. On shared hosting you usually cannot edit these files, so ask the host to restore the visitor address from CF-Connecting-IP.
In WordPress: some security plugins can be told which header to read. That fixes the address for that one plugin, while the server logs and every other plugin still see Cloudflare, so the server fix is the one that covers everything. Avoid code that copies CF-Connecting-IP into REMOTE_ADDR without first checking that the request came from a Cloudflare address.
Limitations
The result is based on one request: your admin visit, a test request from the server, or a stored visit up to 7 days old.
The Cloudflare ranges come from a list shipped with the plugin. An administrator can turn on a weekly refresh of that list, which is the plugin’s only request to a third party.
When another proxy sits between Cloudflare and PHP, the plugin can tell only that the address is neither, so it reports Could not check with Medium confidence.
Related checks
- B3 Local proxy or Tunnel in front of WordPress: a proxy or Cloudflare Tunnel on the server itself.
- B2 Pseudo IPv4 rewriting headers: Cloudflare replacing IPv6 visitor addresses.
- E1 Cloudflare blocking your own server: security rules that catch your own server.
- A1 Cloudflare detection and connection type: how the site is connected to Cloudflare.
Sources
Run this check on your own site with Edge Doctor for Cloudflare®, free on WordPress.org.
Edge Doctor for Cloudflare® is not affiliated with or endorsed by Cloudflare, Inc. Cloudflare is a registered trademark of Cloudflare, Inc.