Tenemos este código en un script de shell que canaliza la salida para que Apache la registre.
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
Sin embargo, es extremadamente ineficiente. En cuestión de segundos, se access.log
cuadruplicó exponencialmente hasta el punto en que el segmento raíz del servidor se llenó. Buscando una mejor manera de ofuscar datos confidenciales, como contraseñas, mientras Apache escribe en access.log
.
Respuesta1
El problema aquí es que estás leyendo el registro de Apache y escribiendo en él al mismo tiempo. Todo lo que haya agregado al registro también regresa a la canalización a través de la cat
llamada (sin intención de jugar con palabras :)). Esto crea un desagradable ciclo de retroalimentación positiva que seguirá funcionando hasta que su sistema de archivos se llene. la respuesta aesta preguntaPuede resultarle interesante saber por qué sucede esto.
¿Cómo deberías hacerlo entonces? Una solución ingenua sería modificar el archivo así:
for item in ${!values[@]};do
sed -i "..." "$apacheLog" #cat isn't needed here
done
y no canalice la salida a ninguna parte: el script mismo modificará el archivoen el lugar. Consulte también la respuesta de terdon sobre cómo realizar la sed
llamada solo una vez (sin un bucle) para mejorar la eficiencia.
El problema con este enfoque, sin embargo, es que un servidor Apache en vivo probablemente registrará cosas en el archivo mientras usted trabaja en él y pueden comenzar a suceder cosas extrañas. Una mejor solución sería buscar en la documentación de Apache formas de mantener la información confidencial fuera de los registros.
Por cierto, lo que estás haciendo ni siquiera desinfecta los registros: agrega las líneas desinfectadas nuevamente al archivo de registro (aún contaminado).
Respuesta2
Tal como está, hay varias mejoras que puedes realizar. Primero, y menos importante, tienes unauso inútil del gato. Lo que es mucho más importante es que lo ejecute sed
varias veces, cada una de las cuales imprimirá el archivo completo. No estoy realmente seguro de lo que estás haciendo grep
. ¿Estás intentando imprimir solo aquellas líneas que contienen la variable específica?
De todos modos, una forma de hacer mejor las cosas sería ejecutar sed
una vez y hacer todos los reemplazos. 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