Apache2 在到达 WSGI 之前对代理请求返回 404

Apache2 在到达 WSGI 之前对代理请求返回 404

我有一个在 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>

第二个将是您的实际服务器配置,或多或少与您发布的内容完全一样,并带有正确的ServerNameServerAlias指令。

编辑:如果正如您所评论的那样,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>

您稍后可以针对符号链接创建每个虚拟主机例外。

相关内容