Профессиональная поддержка сайтов: разработка, дизайн, тексты, SEO и прочее от 500 Р   •   Реклама
7 130 просм
49 комм
Поделиться:

Как заблокировать доступ к сайту по определенной стране или городу на PHP?

Бывает, что по какой-то причине вам нужно ограничить доступ к вашему сайту тому или иному городу, стране. Например, ваш сайт имеет, по большей части, контент на русском языке, и вдруг вы замечаете подозрительный трафик из Китая, который сильно тормозит работу вашего сайта.

Чтобы заблокировать доступ к сайту для определенной страны или города, первое, что вам необходимо сделать – это получить IP пользователя, после чего получить необходимую информацию по нему, сделать проверку и в случае совпадения – заблокировать доступ.

А теперь перейдем от слов к практике.

Думаю, что не стоит напоминать, что на вашем сайте должна быть поддержка PHP.

1. Начинаем писать наш мини-модуль блокировки. Воспользуемся суперглобальным массивом «$_SERVER», который поможет вам определить IP адрес пользователя:

<?php

	header("Content-Type: text/html; charset=utf-8");

	$user_ip = $_SERVER['REMOTE_ADDR'];

?>

2. На основе полученного IP необходимо определить, откуда наш посетитель. Для этого мы воспользуемся сервисом «freegeoip.net», который бесплатно, на основе IP, предоставит нам некоторую информацию о пользователе.

<?php

	header("Content-Type: text/html; charset=utf-8");

	$user_ip = $_SERVER["REMOTE_ADDR"];
	$user_info = file_get_contents("http://freegeoip.net/json/".$user_ip);
	$user_info = json_decode($user_info);
	$user_country = $user_info->country_name;
	$user_city = $user_info->city;

?>

Здесь $user_country и $user_city содержат в себе название страны и города соответственно, которые указаны на английском языке.

На момент написания статьи сервис «freegeoip» был в рабочем состоянии. Если вдруг он перестал работать, воспользуйтесь следующими сервисами для получения информации о пользователе:

http://ipinfo.io 
http://xhanch.com/xhanch-api-ip-get-detail/ 
http://geoiplookup.net/ 
http://ip-api.com 
http://ipinfodb.com 

Обратите внимание, что при использовании этих сервисов необходимо внести корректировки в код.

3. Теперь сделаем проверку страны и заблокируем доступ, если страна совпала с указанной вами. На примере России итоговый скрипт будет выглядеть так:

<?php

	header("Content-Type: text/html; charset=utf-8");

	$user_ip = $_SERVER["REMOTE_ADDR"];
	$user_info = file_get_contents("http://freegeoip.net/json/".$user_ip);
	$user_info = json_decode($user_info);
	$user_country = $user_info->country_name;
	$user_city = $user_info->city;

	if($user_country == "Russia") { // Проверяем страну посетителя

		@header("HTTP/1.1 503 Service Temporarily Unavailable");
		@header("Status: 503 Service Temporarily Unavailable");
   
		echo <<<HTML
			Извините, но для Вашей страны заблокирован доступ к нашему сайту =(
			
			<style>
				body {
					background: #f4f4f4;
				}
			</style>
HTML;

		exit();

	}

?>

Между

echo <<<HTML

	… 

HTML;

вы можете указать любые HTML-теги, CSS-стили или скрипты и таким образом настроить нужное вам оформление для страницы блокировки.

Визуально итог работы нашего скрипта будет такой:

Как заблокировать доступ к сайту по определенной стране или городу на PHP?

Сам код нужно вставлять в самый верх темы вашего сайта, либо же подключать его через:

<?php
	
	include_once("/lock.php");
	
?>

Где «/lock.php» – название скрипта и полный путь до него на вашем хостинге. Для проверки работы скрипта посетите свой сайт через какой-нибудь анонимайзер, который предоставляет выбор страны, или же воспользуйтесь прокси-сервером.

49
комментариев
Гостям запрещено участвовать в обсуждениях сайта. Авторизуйтесь, чтобы расширить привилегии гостевого посещения и получить необходимую помощь от сообщества Pandoge.
Пользователь  |  3

Супер! Все работает! Спасибо вам огромное!

20.05 в 12:13
  • 0
Администратор  |  732

Павел, здравствуйте. Прошу прощения за поздний ответ.

1. Подключаетесь к сайту по FTP.

2. В папке /engine/modules/ создаете файл vk-widget.php. Сам файл заполните скриптом:

<?php

/*

=====================================================

Автор: Артем Малков

-----------------------------------------------------

Назначение: Блокировка виджета VK

=====================================================

*/

if(!defined("DATALIFEENGINE")) {

die("Hacking attempt!");

}

$user_ip = $_SERVER["REMOTE_ADDR"];

$user_info = file_get_contents("http://ip-api.com/json/".$user_ip);

$user_info = json_decode($user_info);

$user_country = $user_info->country;

if($user_country != "Ukraine") {

echo <<<HTML

Здесь ваш полный код виджета от ВК

HTML;

}

?>

Здесь ваш полный код виджета от ВК - замените на все скрипты от ВК.

3. Далее, в шаблоне вашего сайта, в нужное место вставьте:

{include file="engine/modules/vk-widget.php"}

По необходимости очистите кэш сайта.

20.05 в 01:56
  • 0
Пользователь  |  3

Артем, использую DLE (Datalife Engine). Спасибо большое за помощь!

16.05 в 09:50
  • 0
Администратор  |  732

Павел, здравствуйте. Да, можно.

Скажите какая CMS используется на сайте, подскажу как лучше можно сделать.

11.05 в 01:15
  • 0
Пользователь  |  3

Артем, подскажите, пожалуйста, а можно как-то закрыть часть страницы? Например, у меня на сайте стоит виджет ВК. Для пользователей с Украины он не отображается и сайт долго висит. Можно как-то сделать, чтобы всем, кроме Украины этот виджет отображался?

10.05 в 12:52
  • 0
Гости  |  679

Артем, большое спасибо за наводку, разобрался в чем было дело.

Выдало:

bject(stdClass)#1 (14) { ["as"]=> string(24) "AS13335 Cloudflare, Inc." ["city"]=> string(17) "Frankfurt am Main" ["country"]=> string(7) "Germany" ["countryCode"]=> string(2) "DE" ["isp"]=> string(10) "Cloudflare" ["lat"]=> float(50.1153) ["lon"]=> float(8.6823) ["org"]=> string(10) "Cloudflare" ["query"]=> string(14) "162.158.90.140" ["region"]=> string(2) "HE" ["regionName"]=> string(5) "Hesse" ["status"]=> string(7) "success" ["timezone"]=> string(13) "Europe/Berlin" ["zip"]=> string(5) "60313" }

Сайт через cloudflare работает и похоже при недоступности сайта он выдавал кэшированную версию файла страницы, ну или что-то в этом роде, пока не разобрался, но причину понял. Еще раз большое спасибо.

26.10 в 19:31
  • 0
Администратор  |  732

Алексей, а если вывести в коде var_dump($user_info); так же через прокси - что показывает?

26.10 в 18:43
  • 0
Гости  |  679

Артем, да все верно. С Украиной все работает, как надо.

ip-api.com определяет $user_region как KLU, пробовал несколько прокси, думаю дело не в них. Также оставлял только одно условие с регионом, т.е. if($user_region == "KLU"), все равно почему то игнорирует условие. Пробовал делать не через region, а через regionName =="Kaluzhskaya oblast'", все равно пропускает. Кэш не забывал чистить перед каждой проверкой.

26.10 в 18:35
  • 0
Администратор  |  732

Алексей, не совсем понял.

Условие у Вас сейчас такое: если Украина или Калуга - блокируем.

То есть блокировка происходит по любому из выполненных условий.

Насчет этого: $user_region == "KLU"

Ваш $user_region точно определяется как KLU?

26.10 в 18:09
  • 0
Гости  |  679

Подскажите, возможно ли блокировать по региону? Скрипт работает через ip-api.com , заметил что там кроме страны и регион выдается. Попробовал заблокировать для пробы Калугу, но почему то не работает, хотя по стране продолжает блокировать. Сам скрипт такой:

$user_ip = $_SERVER['REMOTE_ADDR'];

$user_info = file_get_contents('http://ip-api.com/json/'.$user_ip);

$user_info = json_decode($user_info);

$user_country = $user_info->country;

$user_region = $user_info->region;

if($user_country == "Ukraine" || $user_region == "KLU")

26.10 в 16:49
  • 0
Администратор  |  732

Павел, для того, чтобы адаптировать код - просто смотрите что возвращает сервер и делайте по аналогии с примером.

Что касается роботов - внедряйте эту функцию https://www.pandoge.com/stati_i_sovety/kak-opredelit-chto-posetitel-vashego-sayta-poiskovyy-robot-a-ne-chelovek-na-php

10.09 в 13:42
  • 0
Гости  |  679

Заметил, что freegeoip.net теперь редиректит на другой сайт, и не определяет город.

А для https://ipinfo.io другой код?

По роботам известно, как их не запретить?

9.09 в 21:04
  • 0
Администратор  |  732

Павел, что именно?

7.09 в 18:17
  • 0
Гости  |  679

С функцией для определения робота что-нибудь известно?

7.09 в 17:19
  • 0
Администратор  |  732

Иван, в идеале - посмотреть бы на сайт и на код. И надо узнать, что Вам возвращает сервер при получении данных о пользователе.

4.08 в 01:31
  • 0
Гости  |  679

Здравствуйте) Подскажите пожалуйста, установил этот скрипт, проверяю как на запрет доступа для России, так и запрет на все страны кроме России, при входе на сайт выдает ошибку HTTP ERROR 500 на любое из условий и текст предупреждения не выводится, что я не так сделал?)

3.08 в 23:21
  • 0
Гости  |  679

Увы к хостингу доступ скорее всего не поучиться получить. Но вы уже достаточно помогли. Я примерно понял куда можно копать. Надеюсь что нибудь получиться сделать. Спасибо большое.

16.07 в 20:03
  • 0
Администратор  |  732

TT, что в таком случае появляется на экране?

<?php

header("Content-Type: text/html; charset=utf-8");

$user_ip = $_SERVER['REMOTE_ADDR'];

$user_info = file_get_contents('http://ip-api.com/json/'.$user_ip);

var_dump($user_info);

?>

16.07 в 17:45
  • 0
Гости  |  679

Удается выудить из скрипта только ip. Все остальные параметр игнорируются. В принципе если блокировать по названию страны не получиться . Можно ли создать диапазон всех ip адресов допустим РФ и при совпадении с массивом выдавать блокировку? Я использую этот код для блокирования отдельных новостей. Раньше скрипт работал пока сервис http://freegeoip.net/ не перестал работать.

16.07 в 17:33
  • 0
Администратор  |  732

TT, есть возможность предоставить доступы к Вашему хостингу? Проверю что к чему. Можно через комментарии.

16.07 в 17:32
  • 0
Гости  |  679

Этот скрипт работает корректно вернуло мой ip. Кстати возможно какой то конфликт с http://ip-api.com/json. От того и долгая загрузка ибо с другими сервисами хоть и не работает но скорость загрузки не менялась.

16.07 в 17:06
  • 0
Администратор  |  732

Мне кажется, у вас проблемы с хостингом. Вот что мне выдал скрипт:

Ваша страна: Russia

Ваш город: Moscow

Время выполнения: 0.12987089157104

Это учитывая время его выполнения (то есть 1 доля секунды). Проверьте, что Вам возвращает:

echo "Ваш IP: ".$_SERVER['REMOTE_ADDR'];

16.07 в 16:22
  • 0
Гости  |  679

Да, извините не указал это. Я проводил изменение полей $user_country = $user_info->country и $user_city = $user_info->city; а так же if($user_country == 'Russia') в соответствии с данными полей представленных в сервисах и подставлял их названия. Я так понимаю, этот скрипт предложенный выше должен показать вывод названия страны и города. Но даже при полном его копировании сайт начинает очень долго грузиться и не выдает названия ни города ни страны.=>"Ваша страна:

Ваш город: " Или же если брать центральную его часть заменяя ранее содержимое кода он не выводит блокировку так же. Я все же еще поэкспериментирую с другими сервисами возможно я что то упустил из-за незнания. Благодарю вас. Если есть еще какие-то рекомендации и вам не сложно будет их дать я с радостью бы услышал.

16.07 в 15:28
  • 0
Администратор  |  732

TT, мало просто заменить ссылку. Нужно посмотреть, что приходит от того или иного сервиса и переделывать под него код.

На примере приведенного сервиса ip-api.com это буде выглядеть следующим образом:

<?php

header("Content-Type: text/html; charset=utf-8");

$user_ip = $_SERVER['REMOTE_ADDR'];

$user_info = file_get_contents('http://ip-api.com/json/'.$user_ip);

$user_info = json_decode($user_info);

$user_country = $user_info->country;

$user_city = $user_info->city;

echo "Ваша страна: ".$user_country."<br>Ваш город: ".$user_city;

?>

16.07 в 12:52
  • 0
Гости  |  679

Здравствуйте Артем, Схожая проблема как у Max. Пробовал подставить другие сервисы, а так же ipstack.com. Но результатов ни каких не было. До этого пользовался freegeoip.net все работала отлично. (Кстати спасибо вам за скрипт) . Но сейчас как-то не получается его запустить. Может быть у вас есть какие то аналоги? Делал тоже самое по сути как и мах касательно замены полей.

15.07 в 13:38
  • 0
Администратор  |  732

Max, а Вы увенены что не работает? Откройте ссылку в браузере - http://api.ipstack.com/193.0.221.68?access_key=829e59d391b1338db09ded4ebce342d4&format=1

Ответ приходит.

Обратите внимание, что IP пользователя подставляется в самое начало - /193.0.221.68?, а не в конец как у вас.

13.07 в 15:40
  • 0
Гости  |  679

Привет, Артем! Я пытаюсь внедрить себе этот код в сайт, но сейчас «freegeoip.net» не работает, редиректит на ipstack.com/, просит регистрацию для получения АПИ ключа, зарегился, получил, сменил ссылку на

$user_info = file_get_contents('http://api.ipstack.com/193.0.221.68?access_key=829e59d391b1338db09ded4ebce342d4&format=1'.$user_ip); не работает, пробовал другие сервисы.. тоже не работает(((

Движок Опенкарт 2.3+

13.07 в 12:28
  • 0
Гости  |  679

<?php

header("Content-Type: text/html; charset=utf-8");

$user_ip = $_SERVER['REMOTE_ADDR'];

$access_key = 'KEY';

$user_info = file_get_contents('http://api.ipstack.com/'.$user_ip.'?access_key='.$access_key.'');

$user_info = json_decode($user_info);

$user_country = $user_info->country_name;

$user_city = $user_info->city;

if($user_country == 'Russia') { // Проверяем страну посетителя

@header('HTTP/1.1 503 Service Temporarily Unavailable');

@header('Status: 503 Service Temporarily Unavailable');

echo <<<HTML

Извините, но для Вашей страны заблокирован доступ к нашему сайту =(

<style>

body {

background: #f4f4f4;

}

</style>

HTML;

exit();

}

?>

19.05 в 02:03
  • 0
Гости  |  679

"This API endpoint is deprecated and will stop working on July 1st, 2018. For more information please visit: https://github.com/apilayer/freegeoip#readme"

19.05 в 00:26
  • 0
Гости  |  679

Прошу прощения, всё дело было в кэше. Спасибо за код! Жду с нетерпением способ отличать роботов, надо попробовать поискать, возможно у того же гугла есть свои постоянные айпишники и добавить их в условия.

23.03 в 14:04
  • 0
Гости  |  679

Артем, да, код в порядке, видимо я неправильно его вставляю. wordpress.

Дело в том что я проверял работу будучи авторизованным как администратор, в то время как в других браузерах не авторизовался. Сейчас проверил, и получается когда я авторизован код выполняется, а без авторизации - нет. Не в тот header получается вставляю код. Хотя он срабатывал когда я просил знакомых из зарубежья проверить доступен ли сайт, странно.

23.03 в 13:21
  • 0
Администратор  |  732

Скопировал ваш код - все работает. Что у Вас за CMS? Анонимайзер через который проверяю - noblockme

23.03 в 13:07
  • 5
Гости  |  679

Спасибо за отзывчивость! Ниже приведён код который сейчас прописан в самом верху подключающегося на каждой странице header.php.

Вывести значение переменной $user_country в консоль я не сумел потому сейчас он через эхо выводится в тело, ну Вы сами видите. А вот в яндексбраузере или опере эхо не выполняется, сайт загружается как обычно.

<?php

header("Content-Type: text/html; charset=utf-8");

$user_ip = $_SERVER['REMOTE_ADDR'];

$user_info = file_get_contents('http://freegeoip.net/json/'.$user_ip);

$user_info = json_decode($user_info);

$user_country = $user_info->country_name;

$user_code = $user_info->country_code;

if($user_country !== 'Russia' || $user_code !== 'RU' ) {

@header('HTTP/1.1 503 Service Temporarily Unavailable');

@header('Status: 503 Service Temporarily Unavailable');

echo "Запрос отклонён" , "$user_country";

exit();

}else {

echo "$user_country";

}

?>

23.03 в 12:50
  • 0
Администратор  |  732

Ростислав, а что выводит echo $user_country; и echo $user_city; ?

23.03 в 12:06
  • 5
Гости  |  679

И почему-то это не работает в опере, что с «турбо» что без

23.03 в 12:04
  • 1
Гости  |  679

Никак не пойму почему это не срабатывает с анонимайзерами. Когда в скрипте указан доступ только для РФ, я захожу под немецким ип и сайт успешно загружается.

23.03 в 11:46
  • 0
Гости  |  679

Артем, заранее спасибо, мне это очень интересно.

15.03 в 10:35
  • 0
Администратор  |  732

Ростислав, для этого - вам нужно определить что посетитель вашего сайта - робот, и если это так - не использовать для него этот скрипт.

Чуть позже выложу функцию по определению поисковых роботов.

14.03 в 02:26
  • 5
Гости  |  679

Спасибо за скрипт. Не подскажете, как добавить в исключения иностранные поисковые машины. Например доступ к сайту установлен только для России, но у нас пользуются не только Яндексом а и Гуглом, как минимум.

13.03 в 14:14
  • 0
Администратор  |  732

влад, скрипт рабочий на 100%. Проверяйте корректность использования.

6.02 в 20:59
  • 10
Гости  |  679

Не работает скрипт

6.02 в 12:41
  • 1
Администратор  |  732

Сергей, У нас есть полезная статья на эту тему. Почитать можно здесь - https://www.pandoge.com/stati_i_sovety/nastroyka-vodyanogo-znaka-watermark-v-dle

4.02 в 14:30
  • 5
Гости  |  679

у меня такой вопрос, у меня движок dle 12.0 и при загрузке фото появляется на ней надпись (DataLife Engine) как её убрать?

4.02 в 11:41
  • 0
Администратор  |  732

Павел, если я не ошибаюсь - этот сайт в принципе не предоставляет данные для скриптов. То есть, в данном случае код из статьи не будет работать.

4.02 в 02:15
  • 10
Гости  |  679

А $user_country и $user_city будут правильно работать для http://ipgeobase.ru ?

Заметил, что этот сайт более стабильней определяет и работает.

Или там другие переменные?

3.02 в 22:09
  • 0
Администратор  |  732

Павел, если IP робота относиться к запрещенному региону - то наверное запретит.

Для двух - if($user_country !== 'Russia' || $user_country !== 'Ukraine') { и так далее.

2.02 в 18:44
  • 5
Гости  |  679

Спасибо за ответ, а этот скрипт от роботов не закрывает индексацию?

И второй вопрос по строке:

if($user_country !== 'Russia') {

если две страны, то как их правильно перечислить?

2.02 в 17:00
  • 0
Администратор  |  732

Павел, На примере той же России -

Если строка if($user_country == 'Russia') { - делает запрет на Россию, то:

if($user_country !== 'Russia') { - запрещает всем кроме России и так далее.

2.02 в 13:56
  • 5
Гости  |  679

Здравствуйте!

А как например, открыть доступ только для нескольких городов России, а для всех остальных закрыть?

Например, закрыть для всех, кроме Москва и Санкт-Петербурга (города чисто для примера взял :-) )

1.02 в 22:45
  • 0
Подняться наверх
«Pandoge» - помощник веб-мастера