Web Hosting Talk







View Full Version : HOW-TO: BLocking countries from your site (PHP)


PhilG
10-01-2004, 08:15 PM
Hello,

Well I for one am tired of fraudulent orders from the same old countries and I want to educate as many people as possible about stopping or at least lowering such orders on the internet. So here goes my first How-To :-)

Okay lets start.

Step 1 - Obtaining the country codes

Firstly, lets download the database of countries to IP address (which is provided courtesy of webhosting.info):

http://ip-to-country.webhosting.info/node/view/6

Download the zip file, extract it and then upload it to your server.

Step 2 - Setting up the database

Now create two MySQL tables using the following:

CREATE TABLE `country_list` (
`IP_FROM` double NOT NULL default '0',
`IP_TO` double NOT NULL default '0',
`country_code` char(2) NOT NULL default '',
`country_code2` char(3) NOT NULL default '',
`country_name` varchar(50) NOT NULL default ''
) TYPE=MyISAM;

CREATE TABLE country_blocks (
id int(5) NOT NULL auto_increment,
country_code char(2) NOT NULL default '',
KEY id (id)
) TYPE=MyISAM;

Okay now we want to load all the data into the country_list table. It's very quick if you can run this command from a MySQL prompt:

LOAD DATA INFILE '/directory/ip-to-country.csv' INTO
TABLE `country_list` FIELDS TERMINATED BY ',' ENCLOSED BY '"'
ESCAPED BY '\\' LINES TERMINATED BY '\r\n'

Lets also load some countries that have high fraud stats:

INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (1, 'AF');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (2, 'DZ');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (3, 'BD');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (4, 'BG');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (5, 'CN');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (6, 'HR');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (7, 'ID');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (8, 'JP');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (9, 'MY');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (10, 'NG');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (11, 'RO');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (12, 'SG');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (13, 'TW');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (14, 'VN');
INSERT INTO `country_blocks` (`id`, `country_code`) VALUES (15, 'EG');

Blocks access from these countries:
AFGHANISTAN, ALGERIA, BANGLADESH, BULGARIA, CHINA, CROATIA, EGYPT, INDONESIA, JAPAN, MALAYSIA, NIGERIA, ROMANIA, SINGAPORE, TAIWAN, VIET NAM.

Step 3 - Doin the PHP

Great, that's that hard stuff! Now lets do the PHP stuff - its pretty easy!

Usually all sites created from php have a common.php or a file that is loaded before anything else if yours is like this then add the following function into that file:

function ip_access_check($ip)
{
$result = mysql_query("SELECT country_code FROM country_list WHERE IP_FROM <= inet_aton('" . $ip . "') AND IP_TO >= inet_aton('" . $ip . "')") or mysql_err();
$row = mysql_fetch_array($result);

$result = mysql_query("SELECT country_code FROM country_blocks WHERE country_code = '" . $row["country_code"] . "'") or mysql_err();

if ($row = mysql_fetch_array($result))
{
header("Location: /blocked.html");
exit;
}
}


If you don't have a common.php or similar then simply create a file called common.php with the function in it and include it in every page that you want using the include(); function.

Notice the "header("Location: /blocked.html");" in the above php function, well you can change this to point to a page that displays a message saying why you have blocked the page.

Now in your index.php and any other pages add the following just after calling the common.php file:

<?
ip_access_check($REMOTE_ADDR);
?>

Step 3 - Testing it

Test by adding your country into the country_blocks and then access that page which you have added the php code to.

Conclusion

I do hope this does lower any fraudulent orders you may get.. Good Luck with your endeavors and please let me know how it goes for you!

-Phil

tnguy3n
10-24-2004, 04:29 PM
Cheer!
any idea how to block FTP access of ppl from those countries?

anothersomething
11-06-2004, 01:47 AM
Originally posted by tnguy3n
Cheer!
any idea how to block FTP access of ppl from those countries?

Don't give them FTP accounts?

superprogram
11-06-2004, 05:11 AM
Originally posted by anothersomething
Don't give them FTP accounts?

Well, suppose he gets access to guest account or something
How to block his ip?

superprogram
11-06-2004, 05:13 AM
PhilG, can you please explain this?
inet_aton('" . $ip . "')

PhilG
11-07-2004, 10:30 PM
The database stores a dotted-quad representation of a network address and this mysql function converts and the Ip address to it.

INET_ATON(expr)
Given the dotted-quad representation of a network address as a string, returns an integer that represents the numeric value of the address. Addresses may be 4- or 8-byte addresses. mysql> SELECT INET_ATON('209.207.224.40');
-> 3520061480

The generated number is always in network byte order. For the example just shown, the number is calculated as 209*256^3 + 207*256^2 + 224*256 + 40. As of MySQL 4.1.2, INET_ATON() also understands short-form IP addresses: mysql> SELECT INET_ATON('127.0.0.1'), INET_ATON('127.1');
-> 2130706433, 2130706433

INET_ATON() was added in MySQL 3.23.15.

sys0
02-06-2005, 02:42 AM
Hello,

I really liked this article, I need to go step further , Could you explain if we could just block a single page on a website for a particular country and display an alternate page instead of the requested one.

If this is possible could you explain how ?

Thank you.

PhilG
02-06-2005, 04:43 PM
Here you go sys0


change the main function to this:

function ip_access_check($ip, $page = "/blocked.html")
{
$result = mysql_query("SELECT country_code FROM country_list WHERE IP_FROM <= inet_aton('" . $ip . "') AND IP_TO >= inet_aton('" . $ip . "')") or mysql_err();
$row = mysql_fetch_array($result);

$result = mysql_query("SELECT country_code FROM country_blocks WHERE country_code = '" . $row["country_code"] . "'") or mysql_err();

if ($row = mysql_fetch_array($result))
{
header("Location: " . $page);
exit;
}
}


Now in the page that you want blocked you can use any of the following function calls (just make sure the pages exist):

ip_access_check($REMOTE_ADDR);
ip_access_check($REMOTE_ADDR, "/blocked_differentpage.html");
ip_access_check($REMOTE_ADDR, "/page_example.html");

I hope that helps

sys0
02-06-2005, 10:33 PM
Thanks a lot PhilG :),

One more thing, Since i am using a Cpanel server, should i place this code under /public_html folder or any other specific location.

Thanks once again.