📚 Plugin Documentation

Country Blocker & Geoblocker

Complete documentation for version 1.0.8 — block visitors by country, continent, state, or region with VPN detection, IP lists, custom block pages, scheduling, WooCommerce integration, and more.

← Back to all documentation

Requirements

WordPress5.0 or higher
PHP7.4 or higher
API KeysNone required. The plugin uses public geo-IP APIs out of the box. Optional MaxMind GeoLite2 database for faster, unlimited lookups
External DependenciesNone to install. Geo lookups use APIs (ipinfo.io, ip-api.com, ipapi.co, ipwho.is) with automatic failover

Installation

  1. Download the ZIP file from your account
  2. Go to Plugins → Add New → Upload Plugin
  3. Upload the ZIP and click Install Now
  4. Click Activate
On activation the plugin creates a logging database table, sets sensible defaults, and is ready to use immediately. No setup wizard or configuration files needed.

Uninstalling

Deactivate and delete from the Plugins screen. Scheduled cron jobs are removed on deactivation. Options stored under bsas_* in the wp_options table and the wp_bsas_logs table remain in your database. Remove these manually if you want a completely clean removal.

Quick Start

  1. Go to Country Blocker in your WordPress admin sidebar
  2. Make sure the Enable Blocking toggle is on (it is by default)
  3. Select countries, continents, or individual states/regions to block
  4. Click Save Settings
  5. Optionally configure email alerts, blocking schedules, and redirect rules on the same page

Visitors from the selected locations will immediately see a “403 Access Restricted” block page. You can customize the block page appearance in the Block Page tab.

For the best geo lookup accuracy and performance, set up a MaxMind license key in the MaxMind section of the Control tab. See MaxMind Setup for details.

Core Toggles

Enable BlockingMaster on/off switch for the entire plugin. When off, no visitors are blocked regardless of other settings
Allow Search Engine CrawlersWhen on, recognized search engine bots (Google, Bing, DuckDuckGo, Yandex, Baidu, Apple, and others) bypass all blocking rules. Recommended to keep on so your SEO is not affected
Strict VPN / Datacenter DetectionWhen on, the plugin checks the visitor's ISP/ASN against a list of known hosting and VPN providers. Visitors from recognized datacenter IPs are blocked even if their country is allowed
Block REST APIWhen on, blocking rules also apply to WordPress REST API requests (/wp-json/). By default the REST API is excluded from blocking

Log Mode

Log EverythingRecords both blocked and allowed visitors (default)
Blocked OnlyOnly records visitors who were blocked
Allowed OnlyOnly records visitors who were allowed or bypassed
Disable LoggingNo access logs are recorded. Reduces database writes for high-traffic sites

Unknown Location Policy

Allow (default)If the plugin can't determine a visitor's country, they are allowed through
BlockIf the plugin can't determine a visitor's country, they are blocked. Use this for strict compliance scenarios

MaxMind GeoLite2 (Optional)

Enter your MaxMind license key to use a local database for geo lookups instead of external APIs. Faster, more accurate, and no rate limits. The database is auto-updated weekly. See the MaxMind Setup section for full instructions.

Countries & Continents

Country Blocking

A searchable grid of all 249 countries and territories. Use the search box to quickly find countries, or use the Select All / Deselect All buttons for bulk actions. Checked countries are blocked. The current count of blocked countries is shown above the grid.

Continent Blocking

Block entire continents with a single checkbox: Africa, Antarctica, Asia, Europe, North America, Oceania, and South America. Blocking a continent blocks all countries within it. This stacks with individual country selections.

Continent blocking and individual country blocking work together. If you block Asia as a continent, all Asian countries are blocked even if they're not individually checked.

State / Region Blocking

Block visitors at a sub-country level. State and region blocking is supported for seven countries:

United StatesAll 50 states plus DC, Puerto Rico, Guam, and U.S. Virgin Islands
CanadaAll 13 provinces and territories
United KingdomEngland, Scotland, Wales, and Northern Ireland
AustraliaAll 8 states and territories
GermanyAll 16 Bundesländer
IndiaAll 36 states and union territories
ChinaAll 31 provinces, municipalities, and autonomous regions
Region blocking requires the geo lookup to return subdivision data. MaxMind GeoLite2 provides the best region accuracy. The external APIs return region data when available, but coverage varies by provider.

Email Alerts

Enable Email AlertsToggle alert emails on/off
Email AddressWhere to send alerts. Defaults to the WordPress admin email
ThresholdNumber of blocked visitors required to trigger an alert. Default: 50
PeriodThe time window for the threshold: Per Hour or Per Day

When the number of blocked visitors in the configured period exceeds the threshold, the plugin sends a single alert email. A cooldown prevents duplicate emails — only one alert is sent per period.

Redirect Rules

Instead of showing the block page, redirect visitors from specific locations to a custom URL. Each rule has three fields:

TypeWhat to match: Country, Continent, US State, CA Province, UK Region, AU State, DE State, IN State, or CN Province
ValueThe specific location code to match (dropdown populated based on type)
URLWhere to redirect matching visitors (302 redirect)

Click + Add Rule to create additional rules. Redirect rules are checked before the normal block page is shown. The first matching rule wins.

Redirect rules are independent of the blocked countries list. A visitor can be redirected even if their country is not in the blocked list.

Blocking Schedules

Create time-based blocking profiles. Each schedule has:

Enable toggleTurn individual schedules on/off
NameA label for your reference (e.g. “Business Hours”)
DaysWhich days of the week the schedule is active
Start HourWhen blocking begins (24-hour format)
End HourWhen blocking ends (24-hour format). Supports overnight spans (e.g. 22:00 to 06:00)

Blocking is active when any enabled schedule matches the current day and time. If no schedules exist or none are enabled, blocking is always active (24/7).

Use schedules to block during business hours only, or to restrict access during maintenance windows. Times are based on your WordPress timezone setting.

Page-Level Blocking

Enable Page-Level BlockingToggle to restrict blocking to specific pages instead of the entire site
Page SelectorDropdown of all published pages and posts. Add pages to the list by selecting and clicking + Add
Block ONLY these pagesOnly the selected pages show the block page to restricted visitors. All other pages are accessible
Block all EXCEPT these pagesThe entire site is blocked except the selected pages. Useful for keeping a landing page or legal notice accessible

Auto-Block Repeat Offenders

Enable Auto-BlockToggle automatic IP blacklisting on/off
ThresholdNumber of blocked visits before the IP hash is added to the blacklist. Default: 10
PeriodTime window: Per Hour or Per Day

When an IP hash exceeds the threshold within the period, it's automatically added to the IP blacklist as a comment entry with a timestamp. Auto-blocked entries are processed during the daily maintenance cron job.

WooCommerce Integration

Prevent Checkout from Blocked RegionsVisitors from blocked countries/regions are redirected back to the cart with an error message when they attempt checkout
Block Cart AccessVisitors from blocked countries/regions see the block page when they try to access the WooCommerce cart page
WooCommerce integration lets you allow blocked visitors to browse your store and view products while preventing them from purchasing. Useful for export controls or regional licensing restrictions.

IP Lists Tab

IP Whitelist

Enter IP addresses or CIDR ranges (one per line) that should always bypass blocking, regardless of country. Whitelisted visitors are logged with a “bypassed” decision and receive a 30-minute bypass cookie.

IP Blacklist

Enter IP addresses or CIDR ranges (one per line) that should always be blocked, regardless of country. Blacklisted visitors see the block page immediately without any geo lookup.

Both fields support IPv4 and IPv6, individual IPs and CIDR notation (e.g. 192.168.1.0/24, 2001:db8::/32). Lines starting with # are treated as comments and ignored.

Use the whitelist for your office IPs, staging servers, or trusted monitoring services. Use the blacklist for known bad actors or IP ranges you want to block regardless of geography.

Block Page Tab

Redirect (Optional)

Enter a URL to redirect all blocked visitors to instead of showing the block page. If set, the block page design settings below are ignored.

Block Page Colors

BackgroundPage background color. Default: #1a1a2e (dark navy)
TextText color. Default: #eeeeee (light gray)
AccentIcon gradient and accent color. Default: #7c3aed (purple)

Block Page Content

HeadingMain title on the block page. Default: “Access Restricted”
Message BodyDescription text below the heading. Use {COUNTRY} as a placeholder for the visitor's detected country code. Default: “Access from {COUNTRY} is restricted.”

Custom CSS

Add custom CSS to further style the block page. Available classes: .bsas-block-body, .bsas-panel, .bsas-icon, h1, p.

Live Preview

A real-time preview at the bottom of the tab shows exactly how your block page will look as you adjust colors, heading, and message text.

The block page is a standalone HTML page served with a 403 status code. It does not load your WordPress theme, keeping it lightweight and fast.

Logs Tab

A paginated table of all access log entries (50 per page), newest first. Each entry shows:

IDAuto-incrementing log entry number
LocationTwo-letter country code (e.g. “US”, “DE”)
RegionState/region code if detected (e.g. “MI” for Michigan, “EN” for England)
DecisionBlocked (red), Allowed (green), Bypassed (blue), or Error (yellow)
ReasonWhy the decision was made (e.g. “country_blocked”, “region_blocked”, “whitelisted”, “vpn_datacenter”, “redirect_rule”)
URIThe page the visitor tried to access
TimeTimestamp of the access

Log Actions

Export CSVDownloads all log entries as a CSV file
ClearDeletes all log entries from the database

Log Retention Settings

Retention DaysHow many days to keep log entries. Default: 30. Set to 0 to keep logs forever. A daily maintenance cron job automatically removes older entries
Max EntriesMaximum number of log entries to keep. Default: 0 (unlimited). When exceeded, the oldest entries are deleted first

How Blocking Works

When a visitor loads any frontend page, the plugin runs checks in this order:

  1. Admin, cron, AJAX? — If the request is to the admin area, a WP-CLI command, a cron job, or an AJAX request, blocking is skipped entirely
  2. Plugin enabled? — If the master toggle is off, all visitors are allowed
  3. REST API excluded? — If the request is to /wp-json/ and Block REST API is off, it's allowed
  4. Cookie check — If the visitor has a valid bypass cookie from a previous allowed check, they pass through immediately (cookie lasts 30 minutes)
  5. IP whitelist — Whitelisted IPs are allowed immediately and logged as “bypassed”
  6. IP blacklist — Blacklisted IPs are blocked immediately with no geo lookup
  7. Crawler check — Recognized search engine bots are allowed if the crawler setting is on
  8. Schedule check — If no active schedule matches the current day and time, blocking is paused
  9. Geo lookup — The visitor's country and region are determined from cached transients (24-hour TTL) or by querying the geo APIs
  10. Unknown location — If the country can't be determined, the unknown location policy applies (allow or block)
  11. Redirect rules — If a redirect rule matches the visitor's location, they are 302 redirected to the configured URL
  12. Country / continent check — If the visitor's country or continent is in the blocked list, they are blocked
  13. Region check — If the visitor's state/region is in the blocked list, they are blocked
  14. VPN / datacenter check — If strict ASN detection is on and the visitor's ISP matches known hosting providers, they are blocked
  15. Page-level check — If page-level blocking is enabled, checks whether this specific page is targeted
  16. Allowed — A bypass cookie is set for 30 minutes so subsequent page loads skip the entire process

Geo Lookup

The plugin determines a visitor's country and region using a cascading fallback system:

  1. MaxMind local database — If you've entered a MaxMind license key and the GeoLite2-City.mmdb file exists, this is used first. Returns both country and region. Fastest and most reliable
  2. ipinfo.io — Returns country and region name
  3. ip-api.com — Returns country code and region code
  4. ipapi.co — Returns country code and region code
  5. ipwho.is — Returns country code and region

Each API has a circuit breaker: after 5 consecutive failures, that API is skipped for 15 minutes before being retried. This prevents slow or broken APIs from dragging down your site.

Geo lookup results are cached in WordPress transients for 24 hours per IP. Each unique visitor triggers at most one API call per day.

MaxMind Setup

  1. Sign up for an account at maxmind.com
  2. Log in and go to Manage License Keys
  3. Generate a new license key
  4. Paste the key into the MaxMind License Key field on the Control tab
  5. Click Save Settings

The plugin will download the GeoLite2-City database to /wp-content/uploads/GeoLite2-City.mmdb and update it automatically every week.

With MaxMind configured, geo lookups happen locally on your server with zero external API calls. MaxMind is especially recommended for state/region blocking because it provides the most reliable subdivision data.

Privacy & Data

IP Hashing

By default, visitor IP addresses are stored as SHA-256 hashes using your WordPress AUTH_SALT as the hash key. The original IP is never stored unless you explicitly enable plain IP storage. This helps with GDPR and privacy compliance.

What's Stored

wp_bsas_logsDatabase table containing access logs: hashed IP, optional plain IP, country code, region code, decision, reason, request URI, and timestamp
bsas_* optionsAll plugin settings stored in the wp_options table
TransientsGeo lookup results cached for 24 hours per visitor IP hash
CookieA small cookie (BSASV) set for 30 minutes on allowed visitors to avoid repeated geo lookups

External Connections

The plugin connects to geo-IP APIs (ipinfo.io, ip-api.com, ipapi.co, ipwho.is) to look up visitor locations. If you configure MaxMind, lookups happen locally with no external connections. No personal data is sent to third parties beyond the visitor's IP address for geo lookup purposes.

Performance

  • Geo lookups are cached in transients for 24 hours per IP — repeat visitors cause zero API calls
  • Allowed visitors receive a 30-minute bypass cookie, so subsequent page loads skip the entire blocking check
  • The plugin uses a circuit breaker pattern: failed APIs are automatically skipped for 15 minutes
  • All API requests have a 2-second timeout to prevent slowdowns if an API is unresponsive
  • Admin pages, cron jobs, AJAX requests, and the REST API (by default) are always excluded from blocking checks
  • Database log cleanup runs daily via WordPress cron, respecting both retention days and max entry limits
  • Database query results are cached via wp_cache for log totals and statistics

Troubleshooting

Visitors from blocked countries are getting through
  • Verify the Enable Blocking toggle is on in the Control tab
  • Check that the specific country, its continent, or the visitor's region is in the blocked list
  • The visitor may be using a VPN. Enable Strict VPN / Datacenter Detection to catch some VPN users
  • If using schedules, verify the current day and time fall within an active schedule
  • If using page-level blocking, verify the page is targeted
  • Cached transients from before you made changes may still be active. They expire within 24 hours
  • If the visitor has an allowed bypass cookie, they won't be rechecked for 30 minutes
  • Admin users browsing the frontend are never blocked
I'm blocking myself
  • The plugin never blocks admin area requests — you can always access /wp-admin/ to change settings
  • Add your IP to the IP Whitelist on the IP Lists tab
  • If locked out of the frontend entirely, connect via FTP or your hosting file manager and rename the plugin folder to deactivate it
Region/state blocking isn't working
  • Region data depends on the geo lookup returning subdivision information. The external APIs don't always include this
  • Set up MaxMind GeoLite2 for the most reliable region data
  • Check the Logs tab — look at the Region column to see if region codes are being detected for visitors
  • Some mobile carriers and satellite ISPs may not resolve to accurate regions
Geo lookups seem inaccurate
  • The external APIs have varying accuracy, especially for mobile and satellite internet users
  • Set up MaxMind GeoLite2 for significantly better accuracy
  • If your site is behind Cloudflare or a CDN, the CDN should be sending the real visitor IP via headers like CF-Connecting-IP or X-Real-IP. The plugin checks these headers automatically
Email alerts not being received
  • Verify Enable Email Alerts is on in the Control tab
  • Check that the email address is correct
  • Verify your WordPress site can send emails (install WP Mail SMTP if needed)
  • Check spam/junk folders
  • Alerts only fire when the blocked count exceeds the threshold within the period. Check the Logs tab to see if enough blocks are occurring
WooCommerce checkout blocking not working
  • Verify Prevent Checkout from Blocked Regions is enabled on the Control tab
  • The visitor's country or region must be in the blocked list for checkout blocking to apply
  • Whitelisted IPs bypass all WooCommerce checks
  • The visitor needs a geo lookup result — ensure APIs or MaxMind are working
The logs table is getting very large
  • Reduce the Retention Days setting (default is 30)
  • Set a Max Entries limit (e.g. 10,000)
  • Switch Log Mode to Blocked Only or Disable Logging
  • The daily maintenance cron job handles cleanup automatically
Scheduled scans aren't running on time
  • WordPress cron depends on site traffic. If your site gets very little traffic, cron jobs may not fire on time
  • Consider setting up a real server cron job that hits wp-cron.php on a schedule
  • Check that no other plugin or server config is disabling wp-cron.php (look for DISABLE_WP_CRON in wp-config.php)