Apache: log personalizado

Introdução

Quando um servidor Apache está atrás de proxies de balanceamento de carga ou mesmo proxies reversos, o endereço IP do cliente que fez o acesso ao serviço web é substituído pelo endereço do proxy nos registros de log de acesso. Para resolver este problema, foi criado o cabeçalho X-Forwarded-For que é adicionado pelos proxies nas requisições redirecionadas ao servidor web. Este cabeçalho pode ser gravado nos logs de acesso do Apache, porém, para isso deve-se realizar uma configuração específica.

Alguns proxies precisam ser explicitamente configurados para que o cabeçalho X-Forwarded-For seja adicionado às requisições redirecionadas para os downstream servers. Por exemplo, para o NGinx, o parâmetro a ser adicionado é o seguinte (normalmente adicionado ao arquivo proxy_params):

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Mas o que nos interessa neste artigo é como fazer o Apache registrar o endereço contido no cabeçalho X-Forwarded-For nos logs de acesso.

O Apache possui uma infinidade de opções de registro de log mas, para este artigo, o foco será no formato de log combinado (combined), o qual tipicamente envolve os seguintes items:

  • Host de origem (o Apache usa nomes de host se configurado para isso, caso contrário, o endereço IP será registrado);
  • O nome do acesso remoto (RFC1413 - Identification Protocol). Normalmente o Apache registra este valor com um hífen, exceto se estiver explicitamente configurado para verificação de identidade do acesso remoto (isto não é igual à autenticação - leia a RFC1413);
  • Nome do usuário. Normalmente o Apache usa um hífen, exceto se ele estiver efetuando algum tipo de autenticação;
  • Timestamp de quando a requisição foi recebida pelo Apache. Corresponde à hora local do servidor, conforme definido nas configurações de localização do sistema operacional;
  • A primeira linha da requisição, tipicamente a URI solicitada;
  • O status retornado pelo servidor;
  • O tamanho da resposta HTTP, excluindo os cabeçalhos de resposta;
  • O site de referência, se presente;
  • O tipo de cliente (user agent) que fez a requisição, isto é, navegador, robot, spider etc.

A configuração padrão do Apache presente no arquivo de configuração (tipicamente o arquivo httpd.conf) normalmente é a seguinte:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
CustomLog log/acces_log combined

Há várias alterações que podem ser efetuadas para que o cabeçalho X-Forwarded-For seja incluso nos registros de acesso. O exemplo a seguir ilustra um exemplo (defina as configurações conforme suas necessidades):

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy
SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded

CustomLog "logs/access_log" combined env=!forwarded
CustomLog "logs/access_log" proxy env=forwarded

Este formato usa as vantagens do suporte condicional de log baseado em variáveis de ambiente (do Apache).

A primeira linha corresponde à configuração padrão de log combinado do Apache.

A segunda substitui o campo %h (host remoto) com os valores obtidos do cabeçalho X-Forwarded-For e configura o nome deste padrão de log para proxy.

A terceira linha define a variável de ambiente forwarded que contém uma expressão regular que captura um endereço IP, o que é ok neste caso, já que realmente nos importamos mais se existe um endereço IP no cabeçalho X-Forwarded-For.

As linhas 4 e 5 dizem ao Apache que padrão de log utilizar: se o cabeçalho X-Forwarded-For existe, use o padrão “proxy”, caso contrário, use o padrão “combined”.

Lembrando que você deve alterar o formato conforme suas necessidades.