Apache2 retorna 404 para solicitações de proxy antes de atingir o WSGI

2

Eu tenho um aplicativo Django rodando sob Apache2 e mod_wsgi e, infelizmente, muitos pedidos tentando usar o servidor como um proxy. O servidor está respondendo OK com erros 404, mas os erros são gerados pelo aplicativo Django (WSGI), que causa um alto uso da CPU.

Se eu desligar o aplicativo e permitir que o Apache manipule a resposta diretamente (envie um erro 404), o uso da CPU cai para quase 0 (o mod_proxy não está ativado).

Existe uma maneira de configurar o Apache para responder diretamente a esse tipo de solicitação com um erro antes que a solicitação atinja o aplicativo WSGI?

Eu vi que talvez o mod_security seria uma opção, mas gostaria de saber se posso fazê-lo sem ele.

EDIT. Vou explicar mais um pouco.

Nos logs eu tenho muitas conexões tentando usar o servidor como um proxy web (por exemplo, conexões como GET link HTTP / 1.1 onde zzz .zzz é um domínio externo, não meu). Estas requisições são passadas para o mod_wsgi, que retorna um 404 (conforme meu aplicativo Django). Se eu desabilitar o aplicativo, como o mod_proxy está desabilitado, o Apache retorna o erro diretamente. O que eu finalmente gostaria de fazer é impedir que o Apache passe a solicitação para o WSGI para domínios inválidos, ou seja, se a solicitação for uma solicitação de proxy, retorne o erro diretamente e não execute o aplicativo WSGI.

EDIT2. Aqui está a configuração do apache2, usando arquivos VirtualHosts em sites ativados (removi endereços de e-mail e alterei os IPs para xxx, altere o alias do servidor para sample.sample.xxx). O que eu gostaria é que o Apache rejeitasse qualquer pedido que não fosse para sample.sample.xxx com erro, isto é, aceitas apenas solicitações relativas ao servidor ou totalmente qualificado apenas para o ServerAlias real.

padrão:

<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>

host real:

<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>

EDITAR 3. Corrigido. O problema foi o carregamento dos arquivos do Host Virtual. As solicitações de ataque realmente não tinham o conjunto de cabeçalhos do host, mas a página de status do Apache estava mostrando isso porque estava carregando o arquivo virtualhost padrão após o arquivo Host Virtual do aplicativo WSGI. A solução foi renomear o arquivo do host virtual padrão para 00-default para que o apache carregasse primeiro. Então todas as dicas que vocês mencionaram ajudaram a ignorar esses pedidos. A CPU está de volta ao controle!

    
por Alejandro Mezcua 05.11.2012 / 12:28

3 respostas

1

O curso mais simples que posso recomendar é manter o mod_proxy desativado e usar duas seções <VirtualHost *:80>...</VirtualHost> diferentes.

No primeiro você colocará qualquer ServerName que você goste; como é o primeiro, o Apache o usará para solicitações HTTP que não apresentam um Host: configurado em outras seções VirtualHost , como devem ser as solicitações de proxy adequadas ou solicitações sem um Host: header. Pode parecer assim:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName default
    RedirectMatch gone .*
</VirtualHost>

O segundo será a configuração real do seu servidor, mais ou menos exatamente como o que você postou, com as diretivas ServerName e ServerAlias corretas.

EDIT: se, como você comentou, o cabeçalho Host: contém seu domínio, você pode simplesmente querer adicionar

RedirectMatch gone ^http:.*

para o seu vhost existente. Isso fará o truque.

    
por 05.11.2012 / 17:36
0

Se por proxy você quer dizer usando o método CONNECT HTTP, você pode tentar:

<Limit CONNECT>
  Order allow,deny
  Deny from all
</Limit>

Caso contrário, você precisará explicar o que você quer dizer com proxy.

    
por 05.11.2012 / 13:28
0

Você provavelmente deve adicionar uma entrada vhost padrão fictícia que nunca corresponde a nada, e negar todo o acesso a ela.

Observe se isso ajudará contra esses ataques semelhantes a proxy, dependendo do cabeçalho Host:; se eles não fornecerem um cabeçalho Host:, o pedido será padronizado para HTTP / 1.0 e eles irão atingir o primeiro vhost de qualquer maneira - o que seria bom.

<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>

O CustomLog acima irá fornecer uma lista de infratores. Você não precisa do status, pois sabe o que é:)

Remova também o ServerAlias inútil do seu host WSGI e mova a definição do diretório raiz para fora de ANHOS vhosts - isso deve estar na configuração principal do servidor e deve negar acesso a tudo e todos.

<Directory />
  AllowOverride None
  Options None
  Order Allow,Deny
  Deny From All
</Directory>

Você pode fazer exceções por v-link para links simbólicos posteriormente.

    
por 05.11.2012 / 17:47