Custom Rule Recipe: Restrict Access To WordPress Login Page from outside a specific country

At the time of writing, Shield Security for WordPress doesn't offer any IP Geolocation services, except to draw in the limited data (country code) that CloudFlare provides, if you're using CloudFlare.

We will soon release an extension to the Shield plugin to provide this functionality for those sites that desire it.

This demonstration video highlights an important technique when creating rules for your security requirements: you should create rules to perform a single task and use multiple, separate rules together to achieve the results you need.

The goal in this case was to restrict access to the WordPress login page to a specific country. In order to get there we had to create 2 separate rules:

  • A rule to store IP Geolocation data for all HTTP requests (Shield doesn't do this by-default)
  • A rule to prevent requests from completing for all requests to the login page outside of a specific country.

Restrict Access To WordPress Login Page Using Geo IP Country Data Rule Summary

As a general rule, we don't think it's a good idea to use Geolocation data to perform large restrictions on the site. This is because these data can be manipulated, invalid, incorrect or not quite accurate.

However, we provide some rules to help you perform some Geolocation specific rules.

Setting Up Rules Steps

To get started, we navigate to "Create New Rule" page and then create x2 rules.

Important: We cannot do anything with Geolocation data until were told Shield to collect it first.

#1 Rule: Collect Geo IP data

  1. Select specific condition

    IF

    1. Is Valid Public IP Address

  1. Select response

    THEN

    1. Update Geo IP data
    2. Confirm using Cloudflare as our data source

      Note: If you're not using Cloudflare on your site, then this isn't going to work for you until we release our Geolocation extension for ShieldPRO.

The summarized #1 rule is as follows

  • IF a request comes from a public IP address; THEN
  • collect Geo IP data from Cloudflare.

#2 Rule: Restrict Access To WordPress Login Page from outside a specific country

  1. Select specific condition

    IF

    1. Is Valid Public IP Address; AND
    2. Is Logged In Normal; Invert

      The "Invert" option means "do the opposite of what this condition states".

      In this case we use this option because we don't want to restrict the logged-in users but the non-logged in only.

    3. ;AND
    4. Match Request Path

      d1. Match type: Equals

      d2. Path To Match: /wp-login.php

    5. ;AND
    6. Match Request Country Code: add GB; Invert

      We need to invert this condition.

      THEN (select response)

    7. PHP Die

      a1. User Display Message: You are not the correct country to access this page

      Note: PHP Die isn't great for user experience. We use this just as demonstration of this rule.

The summarized #2 rule is as follows

  • IF a request comes to the site from a public IP address; and
  • the user is not logged-in; and
  • the request path is equal to /wp-login.php (login page); and
  • the request is not coming from the country GB; THEN
  • terminate the request.
  1. Give a rule name: Prevent WP Login Access Outside GB
  2. Give a rule description: Prevent access to the wp-login page from outside GB for non-logged-in users
  3. Check both confirmation checkboxes
  4. Click to create the new rule

Ordering Of The Rules

If we want to prevent access to the wp-login page from outside GB, then we have to ensure that it's from GB and in this case, we need to collect the Geo IP data. If the order of these x2 rules under the Manage page is reversed, it'll be backwards - we are trying to prevent access to the wp-login page without knowing the origin of request.

So, we ensure that the order is correct:

  1. Collect IP geo data
  2. Prevent WP login access outside GB

In case you lock yourself out of your own site because of your rules, please use a forceoff method outlined here and then disable that rule.

We also recommend you to read: