Как разрешить просматривать веб-страницы только определенным IP-адресам? - PullRequest
4 голосов
/ 22 октября 2011

Я пытаюсь заставить скрипт PHP работать, где он сравнивает IP-адрес человека с текстовым файлом (один IP-адрес в строке). Если IP-адрес этого человека отсутствует в текстовом файле, он перенаправляется на файл declined.html. Я знаю, что могу использовать .htaccess для этого, но список IP-адресов может быть очень, очень длинным.

Это код, который у меня есть:

<?php
$ipArray = file('ip.txt');
unset($allowed);
foreach ($ipArray as $ipTest) if (substr_count($_SERVER['REMOTE_ADDR'],trim($ipTest))     != "0") $allowed = true;
if ($allowed != true) {
header('location: /declined.html');  // the banned display page
die();
}
?>

Я хочу иметь возможность вызывать этот скрипт на каждой странице, которую я хочу видеть только по определенным IP-адресам, вот что я пытаюсь вызвать:

<? include('ip_allow.php'); ?>

Когда я вызываю скрипт PHP на странице HTML, когда мой IP-адрес НЕ находится в ip.txt, он не перенаправляет меня в /declined.html! Как я могу это исправить? Опять же, мой вопрос не в том, как использовать .htaccess, а в том, как исправить мой скрипт! Спасибо.

Ответы [ 4 ]

5 голосов
/ 22 октября 2011

Для фильтрации IP лучше сделать это как можно раньше в цепочке обработки. В порядке предпочтения:

  1. маршрутизатор
  2. межсетевой экран
  3. вебсервер
  4. Сценарий

Скорее всего, у вас нет доступа к уровням маршрутизатора или брандмауэра, но вы МОЖЕТЕ использовать Apache mod_rewrite, чтобы иметь динамический блок с использованием внешнего файла. Настройте файл «включенные IP-адреса» следующим образом:

a.b.c.d ALLOWED
b.c.d.e ALLOWED
c.d.e.f ALLOWED
etc...

Это в основном «значение ключа», где ключом является IP-адрес

Тогда ваши правила mod_rewrite (я нумеровал их для справки)

1. RerwriteMap ipfiltermap txt:/path/to/your/ips/list
2. RewriteCond %{REMOTE_ADDR} (.*)
3. RewriteCond %{ipfiltermap:%1} !ALLOWED
4. RewriteCond %{REQUEST_URI} !^/declined.html
5. RewriteRule .* /forbidden.html [L]

Они работают следующим образом:

  1. Определяет разрешенные IP-адреса в виде пары «значение ключа», где ключами являются разрешенные IP-адреса, а значением является слово «РАЗРЕШЕНО», как отображение с именем «ipfiltermap»
  2. Захватывает удаленный адрес текущего запроса (IP-адрес клиента)
  3. Используя IP-адрес, полученный на шаге 2, найдите его в ipfiltermap и посмотрите, не содержит ли IP-адрес слово «РАЗРЕШЕНО»
  4. Специально освобождает вашу 'отклоненную' страницу от принудительного использования IP - если бы этого не было, запрещенные IP-адреса могли бы войти в бесконечный цикл перенаправления
  5. Если все 3 из RewriteConds совпадают, то пользователь с запрещенного IP-адреса и должен быть перенаправлен на запрещенную страницу.

Соответствующие документы Apache для всего этого здесь .

1 голос
/ 22 октября 2011

Если вы поместите свою конфигурацию непосредственно в конфигурацию Apache, это не повлечет за собой потери скорости при .htaccess поисках - но это будет означать, что вам придется перезагружать конфигурацию Apache при каждом изменении списка. (Хотя ответ Марка очень хорошо избегает этого.)

mod_authz_host.c оптимизирован для умеренно быстрого поиска. Если вы читаете текстовый файл в своем скрипте при каждом выполнении, вы уже в несколько раз медленнее, чем Apache. Apache читает конфигурацию один раз , преобразует IP-адреса в двоичный формат один раз и может затем использовать очень быструю целочисленную арифметику, чтобы определить, разрешены ли хосты или нет.

Кроме того, он уже отлажен и работает. Вам потребуется меньше времени, чтобы развернуть его, чем найти ошибку в вашем текущем коде - и даже тогда ваш текущий код будет - при каждом запросе с контролем доступа - перечитать (и повторно проанализировать в массиве) текстовое описание IP-адресов, преобразовать IP-адрес удаленного узла в текстовую версию и затем выполнить очень медленное сравнение на основе текста по всему массиву.

Если скорость очень важна, вам следует изучить возможность контроля доступа через брандмауэр системы. iptables оптимизировал подпрограммы для поиска совпадающих IP-адресов среди списка разрешенных или запрещенных хостов и не будет тратить время на анализ протокола. Конечно, это гораздо более тяжелый подход «все или ничего», который потребует раздражающего разделения контента между портами прослушивания, если какой-то контент доступен для всех.

0 голосов
/ 22 октября 2011

Я думаю, у вас есть файлы в неправильном каталоге, или PHP не работает, или какая-то другая более простая проблема конфигурации, так как я проверил ваш код, и он прекрасно работает для меня.

0 голосов
/ 22 октября 2011

Команда file() включает в себя символ \n в конце каждой строки, поэтому каждая строка на самом деле похожа на 0.0.0.0\n, который каждый раз возвращает false.

Используйте это:

$ipArray = file('ip.txt', FILE_IGNORE_NEW_LINES); // Try specifying an ABSOLUTE path to this file.
$allowed = false; // Rather than unset($allowed), this will prevent notice errors too!
foreach ($ipArray as $ipTest) if ($_SERVER['REMOTE_ADDR'] == $ipTest) $allowed = true;

Также просто чтобы указать в строке заголовка, Location должен начинаться с заглавной буквы, и вы должны указать полный URI для файла:

header('Location: http://example.com/declined.html');
...