我有一个在Apache2和mod_wsgi下运行的Django应用程序,不幸的是,很多请求试图使用服务器作为代理。 服务器正在响应确定404错误,但错误是由Django(WSGI)应用程序,这会导致高CPU使用率生成。
如果closures应用程序并让Apache直接处理响应(发送一个404),则CPU使用率将下降到接近0(mod_proxy未启用)。
有没有一种方法可以configurationApache,在请求遇到WSGI应用程序之前,直接响应这种请求并发生错误?
我已经看到,也许mod_security将是一个选项,但我想知道如果我没有它可以做到这一点。
编辑。 我会多解释一下。
在日志中,我尝试使用服务器作为Web代理(例如GET http://zzz.zzz/ HTTP / 1.1,其中zzz.zzz是外部域,而不是我的连接)的连接。 这个请求被传递到mod_wsgi然后返回一个404(根据我的Django应用程序)。 如果我禁用应用程序,因为mod_proxy被禁用,Apache直接返回错误。 我最终想要做的就是阻止Apache将请求传递给无效域的WSGI,也就是说,如果请求是代理请求,则直接返回错误而不执行WSGI应用程序。
EDIT2。 这里是apache2configuration,使用站点启用VirtualHosts文件(我已经删除电子邮件地址和更改IP为xxx,将服务器别名更改为sample.sample.xxx)。 我希望Apache能够拒绝任何不带sample.sample.xxx的错误请求,也就是说,只接受对服务器的相对请求,或者只对实际的ServerAlias进行完全限定。
默认:
<VirtualHost *:80> ServerAdmin [email protected] ServerName XXXX ServerAlias XXXX 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 [email protected] 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应用程序虚拟主机文件之后。 解决scheme是将默认虚拟主机文件重命名为00-默认,以便Apache首先加载它。 那么你们提到的所有提示都有助于忽略这些要求。 CPU正在控制之下!
我可以推荐的最简单的方法是禁用mod_proxy并使用两个不同的<VirtualHost *:80>...</VirtualHost>部分。
在第一个中,您将放置您喜欢的任何ServerName ; 因为它是第一个,所以Apache将把它用于HTTP请求,这些HTTP请求不具有在其他VirtualHost部分中configuration的Host:头,就像正确的代理请求应该是,或者没有Host:头的请求一样。 它可能看起来像这样:
<VirtualHost *:80> ServerAdmin webmaster@localhost ServerName default RedirectMatch gone .* </VirtualHost>
第二个将是你实际的服务器configuration,或多或less完全像你发布的,具有正确的ServerName和ServerAlias指令。
编辑:如果,如你所说, Host:标题包含你的域名,那么你可能只是想添加
RedirectMatch gone ^http:.*
到您现有的虚拟主机。 这将有诀窍。
如果通过代理使用CONNECT HTTP方法,则可以尝试:
<Limit CONNECT> Order allow,deny Deny from all </Limit>
否则,你需要通过代理来解释你的意思。
你应该添加一个虚拟的默认虚拟主机条目,永远不会匹配任何东西,并拒绝所有的访问。
请注意,这是否有助于抵御类似代理的攻击取决于它们提供的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将为您提供一个整齐的罪犯列表。
你不需要的状态,因为你知道它是什么:)
还要从WSGI主机中删除无用的ServerAlias,并将根目录定义移到ANY虚拟主机之外 – 这应该在主服务器configuration中,并且它必须拒绝对所有人和所有人的访问。
<Directory /> AllowOverride None Options None Order Allow,Deny Deny From All </Directory>
稍后,可以为每个符号链接创build每个虚拟主机例外。