У меня есть приложение Django, работающее под Apache2 и mod_wsgi, и, к сожалению, множество запросов пытается использовать сервер в качестве прокси. Сервер отвечает ОК с ошибкой 404, но ошибки генерируются приложением Django (WSGI), что приводит к высокой загрузке ЦП.
Если я выключу приложение и позволю Apache обработать ответ напрямую (отправлю 404), загрузка ЦП упадет почти до 0 (mod_proxy не включен).
Есть ли способ настроить Apache для непосредственного ответа на такие запросы с ошибкой до того, как запрос попадет в приложение WSGI?
Я видел, что, возможно, вариант mod_security, но я хотел бы знать, смогу ли я обойтись без него.
РЕДАКТИРОВАТЬ. Я объясню это немного подробнее.
В журналах у меня много подключений, пытающихся использовать сервер в качестве веб-прокси (например, подключения типа GET http: //zzz.zzz/ HTTP / 1.1, где zzz.zzz - это внешний домен, а не мой). Эти запросы передаются в mod_wsgi, который затем возвращает 404 (согласно моему приложению Django). Если я отключу приложение, так как mod_proxy отключен, Apache вернет ошибку напрямую. Наконец, я хотел бы сделать так, чтобы Apache не передавал запрос в WSGI для недопустимых доменов, то есть, если запрос является запросом прокси, напрямую возвращать ошибку и не выполнять приложение WSGI.
РЕДАКТИРОВАТЬ2. Вот конфигурация apache2 с использованием файлов VirtualHosts на сайтах с поддержкой (я удалил адреса электронной почты и изменил IP-адреса на xxx, изменил псевдоним сервера на sample.sample.xxx). Я бы хотел, чтобы Apache отклонял любой запрос, который не попадает в sample.sample.xxx с ошибкой и, то есть принимал только относительные запросы к серверу или полностью соответствовал только фактическим ServerAlias.
дефолт:
<VirtualHost *:80>
ServerAdmin alejandro.mezcua@xxxx.com
ServerName X.X.X.X
ServerAlias X.X.X.X
DocumentRoot /var/www/default
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/>
Options FollowSymLinks
AllowOverride None
Order allow,deny
allow from all
</Directory>
ErrorDocument 404 "404"
ErrorDocument 403 "403"
ErrorDocument 500 "500"
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
фактический хост:
<VirtualHost *:80>
ErrorDocument 404 "404"
ErrorDocument 403 "403"
ErrorDocument 500 "500"
WSGIScriptAlias / /var/www/sample.sample.xxx/django.wsgi
ServerAdmin alejandro.mezcua@xxxx.xxx
ServerAlias sample.sample.xxx
ServerName sample.sample.xxx
CustomLog /var/www/sample.sample.xxx/log/sample.sample.xxx-access.log combined
Alias /robots.txt /var/www/sample.sample.xxx/static/robots.txt
Alias /favicon.ico /var/www/sample.sample.xxx/static/favicon.ico
AliasMatch ^/([^/]*\.css) /var/www/sample.sample.xxx/static/$1
Alias /static/ /var/www/sample.sample.xxx/static/
Alias /media/ /var/www/sample.sample.xxx/media/
<Directory /var/www/sample.sample.xxx/static/>
Order deny,allow
Allow from all
</Directory>
<Directory /var/www/sample.sample.xxx/media/>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
РЕДАКТИРОВАТЬ 3. Исправлено. Проблема заключалась в загрузке файлов виртуального хоста. В запросах атаки на самом деле не был установлен заголовок хоста, но страница состояния Apache показывала его, потому что он загружал файл виртуального хоста по умолчанию после файла виртуального хоста приложения WSGI. Решением было переименовать файл виртуального хоста по умолчанию в 00-default, чтобы apache загружал его первым. Тогда все советы, которые вы упомянули, помогли игнорировать эти просьбы. Процессор снова под контролем!
Самый простой способ действий, который я могу порекомендовать, - это отключить mod_proxy и использовать два разных <VirtualHost *:80>...</VirtualHost>
разделы.
В первый вы положите любой ServerName
что тебе нравится; поскольку это первый, Apache будет использовать его для HTTP-запросов, не имеющих Host:
заголовок настроен в другом VirtualHost
разделы, такие как правильные запросы прокси, или запросы без Host:
заголовок. Это могло бы выглядеть так:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName default
RedirectMatch gone .*
</VirtualHost>
Второй будет фактической конфигурацией вашего сервера, более или менее точно такой же, как то, что вы опубликовали, с правильным ServerName
и ServerAlias
директивы.
РЕДАКТИРОВАТЬ: если, как вы прокомментировали, Host:
заголовок содержит ваш домен, тогда вы можете просто добавить
RedirectMatch gone ^http:.*
к вашему существующему vhost. Это поможет.
Вероятно, вам следует добавить фиктивную запись vhost по умолчанию, которая никогда ни с чем не соответствует, и запретить любой доступ к ней.
ОБРАТИТЕ ВНИМАНИЕ, что поможет ли это против атак, подобных прокси, зависит от предоставляемого заголовка Host:; если они не предоставляют заголовок Host:, по умолчанию используется HTTP / 1.0, и они все равно попадут на первый виртуальный хост - что было бы хорошо.
<VirtualHost *:80>
ServerName dummy.that.will.never.match
DocumentRoot /tmp
Redirect 404 /
LogLevel crit
ErrorLog ${APACHE_LOG_DIR}/dummy_error.log
CustomLog ${APACHE_LOG_DIR}/dummy_access.log "[%t] %h(%a) Host: %{Host}i %H %m %r"
</VirtualHost>
Приведенный выше CustomLog предоставит вам аккуратный список нарушителей.
Статус вам не нужен, потому что вы знаете, что это такое :)
Также удалите бесполезные ServerAlias с вашего хоста WSGI и переместите определение корневого каталога за пределы ЛЮБЫХ vhosts - это должно быть в основной конфигурации сервера и ДОЛЖНО Отрицать доступ к все и все.
<Directory />
AllowOverride None
Options None
Order Allow,Deny
Deny From All
</Directory>
Позже вы можете сделать исключения для каждого виртуального хоста для символических ссылок.
Если под проксированием вы имеете в виду использование метода CONNECT HTTP, вы можете попробовать:
<Limit CONNECT>
Order allow,deny
Deny from all
</Limit>
В противном случае вам нужно будет объяснить, что вы имеете в виду под прокси.