Sanitize os arquivos de log de acesso do Apache?

2

Temos este código em um script de shell que canaliza a saída para o Apache registrar.

declare -a values=( $taintRequestVals )

for item in ${!values[@]}
do
    cat $apacheLog | sed "s/${values[$item]}=[^&\t\n]*/${values[$item]}=***/g" | /bin/grep ${values[$item]}=
done

No entanto, é extremamente ineficiente. Em segundos, o access.log quadruplicou exponencialmente até o ponto em que a fatia raiz do servidor foi preenchida. A procura de uma maneira melhor ofusca dados confidenciais, como senhas, enquanto o Apache está gravando em access.log .

    
por dperry1973 02.10.2013 / 17:18

2 respostas

3

O problema aqui é que você está lendo o log do Apache e gravando nele ao mesmo tempo. O que quer que você tenha adicionado ao log também retornará ao pipeline através da chamada cat (nenhum jogo de palavras intencional :)). Isso cria um ciclo de feedback positivo desagradável que continuará funcionando até que seu sistema de arquivos seja preenchido. A resposta para esta pergunta pode ser interessante para você sobre o porquê isso acontece.

Como você deve fazer isso? Uma solução ingênua seria modificar o arquivo no lugar da seguinte forma:

for item in ${!values[@]};do
    sed -i "..." "$apacheLog"  #cat isn't needed here
done

e não canalize a saída em qualquer lugar: o próprio script modificará o arquivo in situ . Veja também a resposta de terdon sobre como fazer a chamada sed apenas uma vez (sem loop) para melhorar a eficiência.

O problema com essa abordagem, no entanto, é que um servidor Apache ao vivo provavelmente estará registrando coisas no arquivo enquanto você está trabalhando nele e coisas estranhas podem começar a acontecer. Uma solução melhor seria procurar na documentação do Apache formas de manter informações confidenciais fora dos logs.

Por acaso, o que você está fazendo nem limpa os logs: ele anexa as linhas higienizadas de volta ao arquivo de log (ainda contaminado).

    
por 02.10.2013 / 17:37
0

Como está, há várias melhorias que você pode fazer. Primeiro, e menos importante, você tem um uso inútil de gato . O que é muito mais importante é que você está executando sed várias vezes, cada uma das quais imprimirá todo o arquivo. Eu não tenho certeza do que você está fazendo com grep , você está tentando imprimir apenas as linhas que contêm a variável específica?

De qualquer forma, uma maneira de fazer as coisas melhor seria executar sed uma vez e fazer todas as substituições. Algo como:

replace=""
for item in ${!values[@]}
do
    ## build the sed line
    replace="s/${values[$item]}=[^&\t\n]*/${values[$item]}=***/g;$replace"
done

### run the replacement using sed's -i option so it 
### changes the original file
eval sed -i \""$replace"\" $apacheLog
    
por 02.10.2013 / 17:41