The user interface works okay for blacklisting, but is ill suited toward whitelisting (unless one is willing to check 231 radio buttons). Some situations, such as community oriented sites, may wish to close their systems to all but those in their country (or an even smaller region).

Rather than display options as a matrix of radio buttons, how about two selectable lists? One for “Read Only” and one for “Complete Ban.” If a country doesn’t appear on either list, “No Ban” may be assumed. If a country (perhaps mistakenly) appears on both lists, “Complete Ban” can be assumed to prevail. By using selectable, scrollable lists, users can easily perform a select all, then deselect individual items, as desired, to quickly create a whitelist.

Note: Borders of counties are arbitrary. In some situations, it may be more useful to specify longitude, latitude & a radius. Anything falling within the bullseye is whitelisted; anything else is blacklisted. But this may be too much to ask?

Comments

Leeteq’s picture

Ref. https://www.drupal.org/node/1120092#comment-9218275

" I got tired of entering dozens of countries to block -- and it dawned on me that there were far fewer countries I wanted to allow rather than block.

I haven't changed any admin screens or anything, just added a string, e.g. "US/CA/AU/NZ/DE/FR" to the code. After the line $country_code = ip2country_get_country($ip);, I just check to see if the two-letter code is contained in my "approved countries" string. If so, let 'em in. If not, no dice.

It's working great for me. I can post more details if anyone is interested, just took a few lines of code."

mclinn’s picture

Here is what I did for "quick and dirty" whitelisting, starting with the file in #19 above.

Note that this returns a "Complete Ban" for any ip not returning an approved country code. This is easily modified to "Read Only" by changing the $rval below to 1 vs. 2. You could add some logic to return different bans for different countries without too much trouble.

Starting at line 188, near the end of countryban.module:

ORIGINAL

 // Otherwise, proceed as normal.
  else {
    $ip = ip_address();
    $country_code = ip2country_get_country($ip);
  }
  return variable_get('countryban_' . $country_code, 0);
}

MODIFIED

// Otherwise, proceed as normal.
else {
    // 9/14/mcl: no variables table check, use string in fn mclmod01_ipblock()  	
    $ip = ip_address();
    //$country_code = ip2country_get_country($ip);
    $rval = mclmod01_ipblock($ip); 
  }
  //return variable_get('countryban_' . $country_code, 0);
  return $rval;
}

Here is function mclmod01_ipblock() from a custom module file. You could work this into the original code but I prefer keeping new stuff like this as separate as possible:

/**
 * Called by countryban.module
 * only allow country codes in var $allowstr
 * countryban admin page is ignored
 * 9/14/mcl
 */
function mclmod01_ipblock($ip)  {	
	$allowstr = "US/CA/AU/NZ";	// insert country codes to ALLOW here
	$myip = "11.222.333.444";  // skip this ip
	$lhost = "127.0.0.1";  // skip
	$vbox1 = "192.168.0.198";  // skip
	
	if ($ip == $myip OR $ip==$lhost OR $ip==$vbox1)  // local, don't record it
	  {
	  	$rval = 0;
	  	return $rval;
	  	}	
	  	
	$country_code = ip2country_get_country($ip);		
	if (stristr($allowstr, $country_code))  {
		   $rval = 0;
		   $msg = "ALLOWED: ";
		   $wdcatg = "cb_allowed";
		} 	
	else {
	   $rval = 2;	  
	   $msg = "BLOCKED: ";
	   $wdcatg = "cb_blocked";
	}	
	$msg .= "$country_code / IP: <a href = \"http://en.utrace.de/?query=$ip\">$ip</a>";	
	watchdog($wdcatg, $msg);
	
	return $rval;		
	}

That's it. Plug in your allowed countries, and be sure to add any IP addresses to ignore as shown. This is skipping the user access check and debug portion of the code so it will block any IP that doesn't return an approved country code, regardless of debug or privileges set.

I've also added "watchdog" recording, including a link to double check the IP location once it's recorded.

This could obviously be improved, new admin screen to modify approved countries without touching the code etc. But it is working fine for me in its present state. Maybe if there is an "official" release of a D7 version I'll figure out how to do patches and spruce this up a bit. I'm actually surprised this module hasn't received more attention as it does a superb job of eliminating a huge portion of the spammers and others who just want to mess with a website.