BetterShield
Appearance
Login protectionLockoutsSign-in

WordPress behind Cloudflare or a proxy: get the visitor's real IP

· · Updated · 8 min read

To get the real visitor IP in WordPress behind Cloudflare or a proxy, tell BetterShield which proxy to believe, so it can read the visitor’s address from the header the proxy adds instead of seeing every request arrive from one address. Without that, sign-in pauses either stand down or catch everyone at once. This guide covers how BetterShield reads each kind of request, how to set it up, and how to check it worked.

It builds on limiting login attempts, which explains the pauses that depend on this reading. If a wrong setting ever catches your own team, getting back in is the post to open.

Quick summary

  • Sign-in pauses, the puzzle and Never allowed to sign in entries act only on an address BetterShield can verify.
  • Hosted directly, there is nothing to set: the connecting address is used and forwarding headers are ignored.
  • Behind Cloudflare, press Yes, this site is behind Cloudflare when the card asks, and only if it is true.
  • Behind a load balancer or a host’s proxy, name its own addresses under Trusted proxies and make sure it sends X-Forwarded-For.
  • Where BetterShield cannot tell visitors apart, failed sign-ins are still recorded but nobody is paused, and public forms never close.

Why the visitor’s address matters

BetterShield stops password guessing by pausing the connection that keeps getting it wrong. That only works if “the connection” means one visitor. Behind a reverse proxy, a load balancer or a CDN, every request can arrive from the same address: the proxy’s. Count that address and a few mistyped passwords from one person would pause every visitor, you included.

So BetterShield does not simply trust whatever address a request claims. A forwarding header is just text that anyone can send, and believing it from a stranger would let a guesser pick a new address on every attempt. Instead it has to be told whose word to take, which is what the setup below is for.

How BetterShield reads each request

The doc for this feature sets out five cases. In plain terms:

How the request arrivesWhose address is usedPauses
Straight from a public addressThe connecting address. Forwarding headers are ignored, so nobody can choose the address they appear to come from.Run
From Cloudflare’s published address ranges, with Cloudflare’s visitor headerThe visitor address Cloudflare names. Until you confirm the site is behind Cloudflare, a pause counts that address and the Cloudflare address together.Run
From a proxy you named under Trusted proxies, with an X-Forwarded-For headerThe first address in X-Forwarded-For, read from the right, that is not private, not a named proxy and not Cloudflare.Run
From a named proxy that sends no X-Forwarded-ForNothing names the visitor.Stopped
From a private address that nothing namesNothing it can trust.Stopped

The X-Forwarded-For header is the common way a proxy passes the original address along, and Cloudflare documents the headers it adds in its own reference. Cloudflare is recognized by its published address ranges, which ship with the plugin and are never fetched, so it needs no Trusted proxies entry, only your confirmation.

One case is easy to miss. A proxy or CDN that reaches the site from a public address and is not named falls in the first row: its address is taken as the visitor’s, so one pause would shut out everyone behind it. Name it under Trusted proxies and have it send X-Forwarded-For.

When pauses are stopped, failed sign-ins are still recorded, but nobody is paused, nobody gets the puzzle, address entries on Never allowed to sign in stand down, and public forms never close. That is the cautious choice: counting the proxy’s address would put every visitor under one pause, and believing an unvouched header would let anyone dodge one.

Set it up

  1. Open BetterShield › Protection › Login & Access and read How this site sees you. It shows the address you connect from, and what Cloudflare says when it is in front.
  2. If it says automatic lockouts are active and asks nothing else, there is nothing to do.
  3. If it asks whether the site is behind Cloudflare and it is, press Yes, this site is behind Cloudflare. Each pause then follows one visitor. This saves at once.
  4. If it says lockouts are not running and you have a reverse proxy or load balancer, type its address or range under Trusted proxies, in Addresses or ranges, separated by commas (for example 192.0.2.10, 192.0.2.0/24), then press Save. A mistyped entry is named before you save.
  5. Press Check again. If it now says your named proxy sends no forwarding header, set the proxy to send X-Forwarded-For with the visitor’s address.
OptionWhat it doesDefault
Trusted proxiesYour own proxies or load balancers, separated by commas. Up to 500 entries, each no wider than /8 (IPv4) or /32 (IPv6).Empty
Yes, this site is behind CloudflareLets Cloudflare’s visitor header name the visitor on its own.Not confirmed
Turn that offWithdraws the Cloudflare confirmation. Shown when a request did not arrive through Cloudflare although the site trusts it.Not shown
Check againReads your request again. Neither address is stored.

Quick Setup asks the same Cloudflare question and sets the same answer. An entry in X-Forwarded-For that names no address, such as “unknown”, ends the reading and that request is treated as unverified; entries written with a port are read correctly. See Proxies and Cloudflare for the full reference.

What it can break, and how to undo

  • A range you do not control. Any machine inside a trusted range can say who it is carrying, and so dodge pauses. Name only your own infrastructure. Remove the entry and press Save.
  • Confirming Cloudflare when the site is not behind it. Anything inside Cloudflare’s ranges could then name any visitor. The card warns when a request did not come through Cloudflare; press Turn that off.
  • Naming a proxy that sends no header. Pauses stay stopped until it sends X-Forwarded-For.

Adding a proxy and confirming Cloudflare give something away, so with password confirmation on they ask for your password. Each change is recorded as “Login protection changed”.

Check it is working

  • The summary strip. Connections reads Verified (“Read directly” or “Through a proxy”), or Not verified with “Lockouts are paused”.
  • The card. It says connections are identified directly, through Cloudflare, or through the proxy you named, and that automatic lockouts are active.
  • Findings. Failed sign-ins are not being counted, so password guessing is not stopped (High) appears when your own dashboard visits could not be told apart, with Open Login & Access to fix it. It keeps the worst it has seen, and starts over when you change Trusted proxies or the Cloudflare answer. After a fix, open any BetterShield screen, then run the audit again.
  • Networks elsewhere. Sessions, the activity log and the new-network email use the same reading, so once it is right they show your visitors’ networks rather than your proxy’s.

Nothing about your address is stored by the card: it reads the request you just made and shows it to you.

We recommend reading this card first on every new site. It takes a minute and decides whether pauses work at all.

SiteWhat we recommend
Hosted directlyNothing to set.
Behind CloudflarePress Yes, this site is behind Cloudflare when the card asks, and only if it is true.
Behind a load balancer or a host’s proxyName only that proxy’s own addresses, as narrowly as you can, and make sure it sends X-Forwarded-For. Your host can tell you both.
Cloudflare in front of a load balancerName the load balancer. The Cloudflare hop is recognized on its own; then press Yes, this site is behind Cloudflare.
Agency or many sitesCheck the card on every new site before relying on lockouts.

Frequently asked questions

Why do all my visitors share one IP address in WordPress?

Because a reverse proxy, load balancer or CDN sits in front of the site, so every request arrives from the proxy’s address. Tell BetterShield about the proxy, or confirm Cloudflare, and it reads the visitor’s own address from the header instead.

Does BetterShield trust the X-Forwarded-For header?

Only from a proxy you named under Trusted proxies. From any other source the header is ignored, so nobody can choose the address they appear to come from.

Do I have to enter Cloudflare’s IP ranges?

No. Cloudflare’s published ranges ship with the plugin and are never fetched. You only press Yes, this site is behind Cloudflare, and only if the site really is.

What happens if BetterShield cannot tell visitors apart?

Failed sign-ins are still recorded, but nobody is paused, nobody gets the puzzle, and public forms never close. A Failed sign-ins are not being counted, so password guessing is not stopped finding appears with Open Login & Access to fix it.

Is this the same as the Ultra Cloudflare controls?

No. This setting is free and only decides whose address to believe. With Ultra, BetterShield › Ultra › Cloudflare can also put a challenge on the network of a sign-in lockout at Cloudflare’s edge, which is a separate feature.

Conclusion

Sign-in pauses are only as good as the address behind them. Read the card, confirm Cloudflare only if it is true, name your own proxy as narrowly as you can, and check that Connections reads Verified. BetterShield is free on WordPress.org; the full reference is Proxies and Cloudflare, and the pauses it feeds are in Sign-in lockouts.

Close the open doors today

Install the free plugin. The first audit runs when you activate it, and all but one of the fixes wait for your choice.

Requires WordPress 6.7 or newer and PHP 8.0 or newer.

Get BetterShield