我有一个在 Apache2 和 mod_wsgi 下运行的 Django 应用,不幸的是,许多请求都试图将服务器用作代理。服务器响应正常,但出现 404 错误,但这些错误是由 Django (WSGI) 应用生成的,这导致 CPU 使用率过高。
如果我关闭应用程序并让 Apache 直接处理响应(发送 404),则 CPU 使用率将降至几乎 0(未启用 mod_proxy)。
有没有办法配置 Apache,使其在请求到达 WSGI 应用程序之前直接对此类请求做出错误响应?
我已经看到 mod_security 也许是一个选项,但我想知道如果没有它我是否可以做到。
编辑。我会进一步解释一下。
在日志中,我有很多连接试图将服务器用作 Web 代理(例如 GET 之类的连接http://zzz.zzz/HTTP/1.1,其中 zzz.zzz 是外部域,不是我的)。此请求将传递到 mod_wsgi,然后返回 404(根据我的 Django 应用程序)。如果我禁用该应用程序(因为 mod_proxy 已禁用),Apache 会直接返回错误。我最终想要做的是防止 Apache 将请求传递给无效域的 WSGI,也就是说,如果请求是代理请求,则直接返回错误而不执行 WSGI 应用程序。
EDIT2。这是 apache2 配置,在 sites-enabled 中使用 VirtualHosts 文件(我已删除电子邮件地址并将 IP 更改为 xxx,将服务器别名更改为 sample.sample.xxx)。我希望 Apache 拒绝任何未转到 sample.sample.xxx 的请求并出现错误,即仅接受与服务器相关的请求或仅接受实际 ServerAlias 的完全限定请求。
默认:
<VirtualHost *:80>
ServerAdmin [email protected]
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 [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 应用虚拟主机文件之后加载默认虚拟主机文件。解决方案是将默认虚拟主机文件重命名为 00-default,以便 apache 首先加载它。然后你们提到的所有技巧都有助于忽略这些请求。CPU 重新得到控制!
答案1
我可以推荐的最简单的做法是保持 mod_proxy 禁用并使用两个不同的<VirtualHost *:80>...</VirtualHost>
部分。
在第一个部分中,您可以输入任何ServerName
您喜欢的内容;由于这是第一个部分,Apache 将使用它来处理未Host:
在其他VirtualHost
部分中配置标头的 HTTP 请求(例如正确的代理请求应该如此),或者没有标头的请求Host:
。它可能看起来像这样:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName default
RedirectMatch gone .*
</VirtualHost>
第二个将是您的实际服务器配置,或多或少与您发布的内容完全一样,并带有正确的ServerName
和ServerAlias
指令。
编辑:如果正如您所评论的那样,Host:
标题包含您的域,那么您可能只想添加
RedirectMatch gone ^http:.*
到您现有的虚拟主机。这样就行了。
答案2
如果代理是指使用 CONNECT HTTP 方法,那么您可以尝试:
<Limit CONNECT>
Order allow,deny
Deny from all
</Limit>
否则,您将需要解释代理的含义。
答案3
您可能应该添加一个永远不会匹配任何内容的虚拟默认 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 将为您提供一份整洁的违规者名单。
您不需要状态,因为您知道它是什么 :)
还要从 WSGI 主机中删除无用的 ServerAlias,并将根目录定义移出任何 vhosts - 这应该在主服务器配置中,并且必须否定进入一切事物和每个人。
<Directory />
AllowOverride None
Options None
Order Allow,Deny
Deny From All
</Directory>
您稍后可以针对符号链接创建每个虚拟主机例外。