Apache httpd: как я могу запретить от всех, разрешить из подсети, но запретить от IP в этой подсети?

26

Я использую CentOS 5.5 со стандартным Apache httpd-2.2.3.

Я включил mod_status в Расположение / статус сервера. Я хотел бы разрешить доступ к этому единственному местоположению следующим образом:

  1. Отрицать все
  2. Разрешить из подсети 192.168.16.0/24
  3. Запретить IP 192.168.16.100, который находится в подсети 192.168.16.0/24.

1 и 2 легко. Однако, поскольку я «Разрешить с 192.168.16.0/24», можно ли отказать с 192.168.16.100?

Я пытался добавить оператор Deny для 192.168.16.100, но он не работает. Вот соответствующий конфиг:

<Location /server-status>
    SetHandler server-status
    Order Allow,Deny
    Deny from  all
    Deny from  192.168.16.100 # This does not deny access from 192.168.16.100
    Allow from 192.168.16.0/24
</Location>

Или:

<Location /server-status>
    SetHandler server-status
    Order Allow,Deny
    Deny from  all
    Deny from  192.168.16.100 # This does not deny access from 192.168.16.100
    Allow from 192.168.16.0/24
</Location>

Однако это не препятствует доступу к этой конкретной странице, как показано в журналах доступа:

www.example.org 192.168.16.100 - - [11/Mar/2011:16:01:14 -0800] "GET /server-status HTTP/1.1" 200 9966 "-" "

Согласно руководству для mod_authz_host :

Разрешить, Запретить

Во-первых, все разрешающие директивы оцениваются; по крайней мере один должен соответствовать, или запрос отклонен. Затем оцениваются все директивы Deny. Если какие-либо совпадения, запрос отклоняется

IP-адрес соответствует директиве Deny, поэтому не следует ли отклонить запрос?

В соответствии с таблицей на странице mod_authz_host этот IP-адрес должен "совпадать как с разрешением, так и с запретом", и поэтому должно применяться правило "Окончательное совпадение элементов управления: отказано".

    Матч Разрешить, Запретить результат Запретить, Разрешить результат
    Только совпадение Разрешить Запрос разрешен Запрос разрешен
    Только совпадение Запретить Запрос отклонен Запрос отклонен
    Нет соответствия По умолчанию для второй директивы: Запрещено По умолчанию для второй директивы: Разрешено
    Совпадают оба элемента «Разрешить и запретить». Элементы управления финальным матчем: Запрещено
Стефан Ласевский
источник
Запретить все 192.168.16.100 - поскольку вы используете здесь «все», я ожидаю, что все запросы будут отклонены с любого IP-адреса. Думаю, здесь что-то еще происходит.
Май
@Michah: я тоже делаю Allow from 192.168.16.0/24. Как я понимаю из документации, любые IP-адреса запрашивающей стороны в сети 192.168.16.0/24 будут соответствовать этому утверждению Allow, запрос разрешен.
Стефан Ласевский
Следуя документации, вставленной выше. «Во-первых, все директивы Allow оцениваются; по крайней мере, одна должна соответствовать, или запрос отклонен» ==> Это должно соответствовать вашему «Allow from 192.168.16.0/24», но вторая часть «Next, все директивы Deny оценивается. Если найдены совпадения, запрос отклоняется "С помощью" Запретить от всех ", не будет ли каждый запрос соответствовать этой второй части и, следовательно, отклоняться?
Май
Вы должны подумать, не хотите ли вы, чтобы этот IP-адрес имел полный доступ к вашей системе или только с httpd. Если первое, продолжайте свой подход к использованию директив apache. Если последний, то это должно быть сделано в брандмауэре.
Эндрю Кейс
Спасибо ACase. Я только хочу запретить доступ с 192.168.16.100 к этой конкретной странице. Я хочу, чтобы 192.168.16.100 имел доступ ко всем остальным страницам на этом веб-сервере.
Стефан Ласевский

Ответы:

35

Я не проверял, но я думаю, что вы почти у цели.

<Location /server-status>
    SetHandler server-status
    Order Allow,Deny
    Deny from  192.168.16.100
    Allow from 192.168.16.0/24
</Location>

Deny from allне нужен На самом деле это облажается, потому что все будет совпадать all, и поэтому будет отказано (и я думаю, что Apache пытается быть умным и делать что-то глупое). Я всегда находил в Apache Order, Allowи Denyдирективы запутанным, поэтому всегда визуализировать вещи в таблице (взято из Документов ):

Матч | Разрешить, запретить результат | Запретить, разрешить результат
-------------------------------------------------- -----
Разрешить только | Разрешено | Разрешается
Запретить только | Отказано | Отказано
Нет совпадений | По умолчанию: отказано | По умолчанию: разрешено
Матч оба | Финальный матч: отказано | Финальный матч: разрешено

С вышеуказанными настройками:

  • Запросы от 192.168.16.100 получают «Соответствие обоим» и, таким образом, отклоняются.
  • Запросы от 192.168.16.12 получают «Разрешено только» и, таким образом, разрешены.
  • Запросы от 123.123.123.123 получают «Нет совпадений» и поэтому отклоняются.
phunehehe
источник
1

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

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

Майк
источник
Я обновил свой ответ. Я включил правило «Запретить с 192.168.16.100», но доступ по-прежнему разрешен с 192.168.16.100
Стефан Ласевский,
Я хочу разрешить доступ ко всем остальным местам с этого хоста. Однако я хочу отказать в определенных местах. IPTables не помогает мне здесь.
Стефан Ласевский
IPTables не будет специально запрещать исходящий трафик, если вы не сообщите об этом. Однако вы можете запретить входящий трафик из мира и определенный адрес, но все разрешить подсеть.
Майк
Я думаю, вы неправильно поняли мою просьбу. Я хочу применить этот контроль доступа только к / server-status, а не ко всему хосту. Насколько мне известно, IPtables не может сделать это легко.
Стефан Ласевский
-4

Вы можете использовать php? Если это так, добавьте оператор php для выхода / перенаправления для этого конкретного IP-адреса.

Пример:

$ deny = array ("111.111.111", "222.222.222", "333.333.333");

if (in_array ($ _SERVER ['REMOTE_ADDR'], $ deny))

{header ("location: http://www.google.com/ ");

выход();

Ссылка: http://perishablepress.com/press/2007/07/03/how-to-block-ip-addresses-with-php/

Джон
источник
2
Это должно быть на каждой странице, размещенной на веб-сервере. Это решение нецелесообразно и не там, где вы хотите фильтровать доступ к веб-серверу.
Эндрю Кейс