Geo-blocking: how to block a country on your website
Geo-blocking means refusing or challenging visitors based on the country their IP address maps to. On Cloudflare, a WAF custom rule with ip.src.country does it on any plan. Add not cf.client.bot so Googlebot and Bingbot are never caught: Googlebot crawls mostly from US IP addresses, and sometimes from other countries.
What is geo-blocking?
Geo-blocking is access control by location. Your site, firewall or CDN looks up the visitor's IP address in a geolocation database, gets a country code, and decides what to do: serve the page, show a challenge, or refuse the request.
Streaming services use it for licensing. Site owners usually use it for a simpler reason: most of the junk traffic hitting their login page or search comes from places where they have no customers.
Two limits to keep in mind before you start:
- It is an estimate. Cloudflare says plainly that nothing binds an IP address to a physical country, and that the data shifts as addresses change hands. Mobile and shared networks are the least reliable.
- It is easy to get around. A VPN or a rented server in an allowed country passes any country rule. Geo-blocking cuts volume. It does not stop a determined attacker.
How to block a country in Cloudflare
Use a WAF custom rule. Custom rules exist on every plan (5 on Free, 20 on Pro, 100 on Business), and one rule can hold a whole list of countries.
- In the Cloudflare dashboard, open your domain and go to Security rules.
- Select Create rule, then Custom rules.
- Choose the field Country, operator is in, and pick the countries. Then add a second condition, Known Bots equals false. Or paste the expression into the expression editor.
- Choose the action and select Deploy.
The field is ip.src.country, a two-letter ISO code. The older ip.geoip.country still works but is deprecated. Values in a list are separated by spaces, not commas:
(ip.src.country in {"CN" "RU"} and not cf.client.bot)
To allow only your own markets and treat everyone else as suspect, flip the condition:
(not ip.src.country in {"US" "CA"} and not cf.client.bot)
Block or Managed Challenge?
Block refuses the request with a 403. Managed Challenge shows a challenge page that most real browsers pass without any click, while simple scripts fail. Cloudflare recommends Managed Challenge for most rules, and suggests starting with it, checking Security Events, and only then switching to Block. That advice fits country rules well: travelers, expats and customers on VPNs keep access, and bots still get stopped.
For a deeper look at rule order and the Skip action, see how to block an IP in Cloudflare.
What about IP Access rules?
IP Access rules also accept a country, but blocking by country there is Enterprise only. Cloudflare itself recommends custom rules instead of IP Access rules for geo-blocking. One more catch: IP addresses that Cloudflare allows globally override an IP Access country block, but not a country block in a custom rule.
Why blocking countries can hurt SEO
Search crawlers have a location too, and it is rarely yours. Google says its crawlers egress primarily from IP addresses in the United States. If Google detects that a site blocks US requests, it may try to crawl from other countries. Google also runs geo-distributed crawling for locale-adaptive pages, using IP addresses outside the US whose reverse DNS ends in geo.googlebot.com.
What that means for your rules:
- Blocking the US blocks most Googlebot traffic.
- "Everything except my country" blocks most Googlebot traffic too, unless your country is the US.
- Blocking a country list can still catch geo-distributed crawls or other crawlers that happen to come from that country.
Bingbot and ad crawlers have the same exposure. In the traffic reports we have prepared, this is one of the most common accidents: a hand-written country rule that was meant for scrapers and quietly caught Google's or Bing's crawlers as well.
The fix is to let verified bots through before any country logic runs. The not cf.client.bot condition in the rules above does that. Cloudflare's own example of a country challenge uses exactly this pattern. If you keep several blocking rules, you can instead put one rule first that matches cf.client.bot with the Skip action. It also helps to check that ad platform crawlers, which use their own IP lists, are not being challenged.
One honest exception. If you restrict content by country for legal or licensing reasons, Google's guidance is to treat Googlebot from a country the same way you treat any other visitor from that country. Exempting crawlers is right for load and abuse filtering, not for content you are not allowed to show in a market.
Blocking countries without Cloudflare: nginx and Apache
On your own server, the country lookup needs a GeoIP database or a header from your CDN.
nginx. The official ngx_http_geoip_module sets $geoip_country_code from a MaxMind database. It is not built by default (it needs --with-http_geoip_module), and recent versions read MMDB files as well as the legacy format. A third-party geoip2 module is a common alternative. Combine the country with a list of verified crawler IPs so Googlebot is never refused:
# http { } context
geoip_country /usr/share/GeoIP/GeoLite2-Country.mmdb;
geo $is_googlebot {
default 0;
66.249.64.0/27 1;
# ...one line per prefix from Google's crawler IP list
}
map $geoip_country_code $blocked_country {
default 0;
CN 1;
RU 1;
}
map "$blocked_country:$is_googlebot" $deny_geo {
default 0;
"1:0" 1;
}
# server { } context
if ($deny_geo) {
return 403;
}
Take the prefixes from Googlebot IP ranges, which lists Google's and Bing's published ranges. Do not "allow Googlebot" by user agent: any scraper can copy that string.
Behind Cloudflare. Cloudflare can pass the visitor's country to your server in the CF-IPCountry header. Turn on IP Geolocation under Network, or the "Add visitor location headers" managed transform. The value is an ISO code, XX for unknown and T1 for Tor. In nginx it is $http_cf_ipcountry. In Apache, set a variable from the header and deny on it:
# Virtual host: restore the visitor IP (mod_remoteip)
RemoteIPHeader CF-Connecting-IP
# RemoteIPTrustedProxy: Cloudflare's published IP ranges
# Virtual host or .htaccess
SetEnvIf CF-IPCountry "^(CN|RU)$" blocked_country
<RequireAny>
# Verified crawlers: prefixes from Google's crawler IP list
Require ip 66.249.64.0/27
<RequireAll>
Require all granted
Require not env blocked_country
</RequireAll>
</RequireAny>
Only trust these headers if your origin accepts traffic from Cloudflare alone. Anyone who reaches the server directly can send any country they like. And if you are on Cloudflare anyway, the edge rule is simpler and stops the request before it costs you anything. More server-side options are in how to block an IP address.
Blocking countries in WordPress
Several plugins block by country. iQ Block Country can allow or block countries for the whole site or just the admin area, using MaxMind's free GeoIP2 country database or the plugin's API. In Wordfence, country blocking is a Premium feature.
Two things to know about plugins:
- Your server still does the work. A plugin runs only after WordPress and PHP load, so a blocked bot still costs you a PHP process for every request. During a flood, that is the load you were trying to avoid. Blocking at the edge or in the web server is cheaper.
- Caching gets in the way. iQ Block Country notes that pages served from a cache plugin bypass it, and a cached block page can be shown to everyone.
Plugins are fine for protecting wp-login.php on a small site. For real load, move the rule to Cloudflare or nginx.
Which countries should you block?
There is no universal list, and copying a "hacker countries" list from a forum is how sites lose customers and crawlers. Decide from your own traffic:
- Where customers come from. Orders, sign-ups and GA4 sessions with engagement by country. These countries stay open.
- Where the load comes from. Requests by country in Cloudflare analytics or your access logs, especially to search, cart and login URLs.
- Where failed logins come from. Your security plugin or server logs.
Block only countries with heavy load and zero business. Use Managed Challenge where real people may still visit. Often the source is not a country at all but a cloud network, and an ASN rule is more precise than a country rule. Then watch Security Events for a week, filtered by verified bots, and confirm any crawler IPs you see with Verify Googlebot.
If you are not sure where your load comes from, a free bot traffic report breaks it down by country, network and user agent before you write a single rule.
Geo-blocking methods compared
| Method | Where it runs | Effort | Risk to Googlebot |
|---|---|---|---|
Cloudflare custom rule with not cf.client.bot | Cloudflare edge | Low, any plan | Low: verified bots are excluded |
| Cloudflare custom rule without a bot exception | Cloudflare edge | Low | High if the US or "all but one country" is blocked |
| Cloudflare IP Access rule by country | Cloudflare edge | Low, Enterprise only for Block | High: no verified bot exception |
nginx GeoIP or CF-IPCountry | Your web server | Medium: database updates, crawler IP list | Medium: safe only with a maintained IP list |
Apache SetEnvIf + Require | Your web server | Medium | Medium: same as nginx |
| WordPress plugin | PHP, after WordPress loads | Low | Depends on the plugin's crawler handling |
FAQ
Does geo-blocking affect SEO?
It can. Googlebot crawls mainly from US IP addresses, so a rule that blocks the US or allows only one non-US country can stop Google from crawling your site. Exclude verified bots in the rule and check Security Events after you deploy it.
Can I block a country on the Cloudflare Free plan?
Yes, with a WAF custom rule. The Free plan has 5 custom rules, and one rule can list many countries. Blocking by country through IP Access rules is limited to Enterprise.
Is it better to block or challenge a country?
Challenge, in most cases. Managed Challenge lets real people through, including travelers and VPN users, while scripts fail. Use Block only for countries that send heavy junk traffic and never any customers.
Can visitors get around geo-blocking?
Yes. A VPN or a server in an allowed country passes any country rule. Geo-blocking reduces noise and load. Pair it with rate limiting and rules based on networks and behavior.
Rather not deal with this yourself?
If bots slow down your site, copy it or fill your analytics with fake visits, we can sort it out. We find out which bots visit your site, stop the harmful ones and check that Google, Bing and ad crawlers still get in. It starts with a free report.