Temos esse 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, access.log
quadruplicou exponencialmente até o ponto em que a fatia raiz do servidor foi preenchida. Procurando uma maneira melhor de ofuscar dados confidenciais, como senhas, enquanto o Apache está gravando no access.log
.
Responder1
O problema aqui é que você está lendo o log do Apache e gravando nele ao mesmo tempo. Tudo o que você adicionou ao log também retorna ao pipeline por meio da cat
chamada (sem intenção de jogo de palavras :)). Isso cria um ciclo de feedback positivo desagradável que continuará funcionando até que o sistema de arquivos fique cheio. A resposta paraessa questãopode ser interessante para você saber por que isso acontece.
Como você deve fazer isso então? Uma solução ingênua seria modificar o arquivo da seguinte forma:
for item in ${!values[@]};do
sed -i "..." "$apacheLog" #cat isn't needed here
done
e não canalize a saída para lugar nenhum: o próprio script modificará o arquivono local. Veja também a resposta de Terdon sobre como fazer a sed
chamada apenas uma vez (sem loop) para melhorar a eficiência.
O problema com essa abordagem, entretanto, é que um servidor Apache ativo provavelmente registrará coisas no arquivo enquanto você trabalha nele e coisas estranhas podem começar a acontecer. Uma solução melhor seria procurar na documentação do Apache maneiras de manter informações confidenciais fora dos logs.
Aliás, o que você está fazendo nem mesmo higieniza os logs: ele anexa as linhas higienizadas de volta ao arquivo de log (ainda contaminado).
Responder2
Da forma como está, existem várias melhorias que você pode fazer. Primeiro, e menos importante, você tem umuso inútil de gato. O que é muito mais importante é que você execute sed
várias vezes, cada uma delas imprimindo o arquivo inteiro. Não tenho certeza do que você está fazendo grep
. Você está tentando imprimir apenas as linhas que contêm a variável específica?
De qualquer forma, uma maneira de fazer melhor as coisas 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