Я создаю простой черный список IP. Каждый запрос оценивается в соответствии с перечнем IP-адресов и при необходимости набрасывает 403. Я решил разобраться с ним на стороне Apache с mod_rewrite
, его RewriteMap
и простым скриптом python.
В VirtualHost
:
<VirtualHost *:80>
...
RewriteEngine On
RewriteMap banip prg:/path/to/script.py
RewriteCond ${banip:%{REMOTE_ADDR}} !=OK
RewriteRule ^/.* - [F]
</VirtualHost>
script.py:
#!/usr/bin/python
import sys
sys.stdout.write('OK\n')
sys.stdout.flush()
Теперь странная часть. После перезапуска Apache только первый запрос возвращает 200
а каждый следующий запрос возвращает 403
. Я ожидаю, что все они вернут 200
. Когда я перезапускаю Apache, все происходит снова и снова.
Перезаписать журнал после перезапуска Apache:
# Very first request
127.0.0.1 - (2) init rewrite engine with requested uri /app_dev.php/
127.0.0.1 - (3) applying pattern '^/.*' to uri '/app_dev.php/'
127.0.0.1 - (5) map lookup OK: map=banip key=127.0.0.1 -> val=OK
127.0.0.1 - (4) RewriteCond: input='OK' pattern='!=OK' => not-matched
127.0.0.1 - (1) pass through /app_dev.php/
...
# Request after that
127.0.0.1 - (2) init rewrite engine with requested uri /static/css/grid.css
127.0.0.1 - (3) applying pattern '^/.*' to uri '/static/css/grid.css'
127.0.0.1 - (5) map lookup OK: map=banip key=127.0.0.1 -> val=
127.0.0.1 - (4) RewriteCond: input='' pattern='!=OK' => matched
127.0.0.1 - (2) forcing responsecode 403 for /static/css/grid.css
Во втором обновлении он ничего не пишет для перезаписи журнала, сразу же бросает 403
.
Когда я попробую RewriteCond OK !=OK
или RewriteCond NOTOK !=OK
, он работает отлично. Любая идея, почему это происходит?
Я на Xubuntu 11.10 с Apache 2.2.20 и Python 2.7.2.
Я думаю, вы можете внимательно ознакомиться с документацией RewriteMap. В частности:
Эта программа запускается один раз, когда сервер Apache запускается, а затем общается с механизмом перезаписи через свои дескрипторы файлов stdin и stdout. Для каждого поиска по карте-функции он получит ключ для поиска в виде строки с завершающим символом строки на stdin. Затем он должен вернуть возвращаемое значение в виде строки с завершающим символом строки в stdout или четырехсимвольной строке "NULL", если она терпит неудачу (т.е. Нет соответствующего значения для данного ключа).
Итак, ваша программа запускается один раз, получает ключ от Apache, генерирует ответ и затем выходит. Как видно из документации, она не будет перезапущена.
Ваша программа должна зацикливаться, считывать строку ввода, генерировать вывод, а затем ждать большего ввода. Связанная документация включает очень короткий пример.