El demonio syslog permite fácilmente guardar registros en máquinas
remotas; de esta forma se pretende que, aunque la seguridad de un sistema se
vea comprometida y sus logs sean modificados se puedan seguir registrando
las actividades sospechosas en una máquina a priori segura. Esto se
consigue definiendo un `LOGHOST' en lugar de un archivo normal en el
fichero /etc/syslogd.conf de la máquina de la que nos interesa guardar
información; por ejemplo, si queremos registrar toda la información de
prioridad info y notice en la máquina remota rosita, lo
indicaremos de la siguiente forma:
*.=info;*.=notice @rosita
Tras modificar /etc/syslogd.conf hacemos que el demonio relea su fichero
de configuración enviándole la señal SIGHUP (por ejemplo, con
kill).
Por su parte, en el host donde deseemos almacenar los logs,
tenemos
que tener definido el puerto syslog en /etc/services y ejecutar
syslogd con el parámetro `-r' para que acepte conexiones a
través de la red:
rosita:~# grep syslog /etc/services
syslog 514/udp
rosita:~# ps xua|grep syslogd
root 41 0.0 0.4 852 304 ? S Mar21 0:01 /usr/sbin/syslogd
rosita:~# kill -TERM 41
rosita:~# syslogd -r
rosita:~#
A partir de ese momento todos los mensajes generados en la máquina origen
se enviarán a la destino y se registrarán según las reglas de esta,
en un fichero (lo habitual), en un dispositivo...o incluso se reenviarán
a otra máquina (en este caso hemos de tener cuidado con los bucles); si
suponemos que estas reglas, en nuestro caso, registran los mensajes de la
prioridad especificada antes en /var/adm/messages, en este archivo
aparecerán entradas de la máquina que ha enviado la información:
rosita:~# tail -3 /var/adm/messages
Mar 23 07:43:37 luisa syslogd 1.3-3: restart.
Mar 23 07:43:46 luisa in.telnetd[7509]: connect from amparo
Mar 23 07:57:44 luisa -- MARK --
rosita:~#
Esto, que en muchas situaciones es muy recomendable, si no se realiza
correctamente puede incluso comprometer la seguridad de la máquina que guarda
registros en otro equipo: por defecto, el tráfico se realiza en texto claro,
por lo que cualquier atacante con un sniffer entre las dos máquinas
puede tener acceso a información importante que habría que mantener en
secreto; imaginemos una situación muy habitual: un usuario que teclea su
password cuando el sistema le pide el login. Evidentemente, esto
generará un mensaje de error que syslogd registrará; este mensaje
será similar a este (Linux Slackware 4):
Mar 23 05:56:56 luisa login[6997]: invalid password for `UNKNOWN'\
on `ttyp5' from `amparo'
Pero, >qué sucedería si en lugar de `UNKNOWN' el sistema almacenara
el nombre de usuario que se ha introducido, algo que hacen muchos
clones de Unix? En esta situación el mensaje sería muy parecido al
siguiente (Linux Red Hat 6.1):
Mar 23 05:59:15 rosita login[3582]: FAILED LOGIN 1 FROM amparo FOR\
5k4@b&-, User not known to the underlying authentication module
Como podemos ver se registraría una contraseña de usuario,
contraseña que estamos enviando a la máquina remota en
texto claro a través de la red; evidentemente, es un riesgo que no podemos
correr. Quizás alguien pueda pensar que una clave por sí sola no
representa mucho peligro, ya que el atacante no conoce el nombre de usuario en
el sistema. De ninguna forma: el pirata sólo tiene que esperar unos
instantes,
porque cuando el usuario teclee su login y su password correctamente
(en principio, esto sucederá poco después de equivocarse, recordemos que
el usuario trata de acceder a su cuenta) el sistema generará un mensaje
indicando que ese usuario (con su nombre) ha entrado al sistema7.1.
Para evitar este problema existen dos aproximaciones: o bien registramos logs en un equipo directamente conectado al nuestro, sin emitir tráfico al
resto de la red, o bien utilizamos comunicaciones cifradas (por ejemplo con
SSH) para enviar los registros a otro ordenador. En el primer caso sólo
necesitamos un equipo con dos tarjetas de red, una por donde enviar el tráfico
hacia la red local y la otra para conectar con la máquina donde almacenamos
los logs, que sólo será accesible desde nuestro equipo y que no ha
de tener usuarios ni ofrecer servicios; no es necesaria una gran potencia de
cálculo: podemos aprovechar un viejo 386 o 486 con Linux o FreeBSD para
esta tarea.
El segundo caso, utilizar comunicaciones cifradas para guardar registros en
otro equipo de la red, requiere algo más de trabajo; aquí no es
estrictamente necesario que la máquina esté aislada del resto de la red, ya
que la
transferencia de información se va a realizar de forma cifrada, consiguiendo
que un potencial atacante no obtenga ningún dato comprometedor analizando el
tráfico; evidentemente, aunque no esté aislado, es fundamental que el
sistema donde almacenamos los logs sea seguro. Para enviar un log
cifrado a una máquina remota podemos utilizar, como hemos dicho antes, SSH unido a las facilidades que ofrece syslogd; si lo hacemos así,
lo único que necesitamos es el servidor sshd en la máquina destino
y el cliente ssh en la origen. Por ejemplo, imaginemos
que queremos utilizar a rosita para almacenar una copia de los registros
generados en luisa conforme se vayan produciendo; en este caso vamos a
enviar logs a un fifo con nombre, desde donde los cifraremos con
SSH y los enviaremos al sistema remoto a través de la red. Lo
primero que necesitamos hacer es crear un fichero de tipo tubería en la
máquina origen, por ejemplo con mknod o mkfifo:
luisa:~# mknod /var/run/cifra p
luisa:~# chmod 0 /var/run/cifra
luisa:~# ls -l /var/run/cifra
p--------- 1 root root 0 May 4 05:18 /var/run/cifra|
luisa:~#
Este es el archivo al que enviaremos desde syslogd los registros que nos
interesen, por ejemplo los de prioridad warn; hemos de modificar /etc/syslog.conf para añadirle una línea como la siguiente:
luisa:~# tail -1 /etc/syslog.conf
*.warn |/var/run/cifra
luisa:~#
A continuación haremos que syslog relea su nueva configuración
mediante la señal SIGHUP:
luisa:~# ps xua|grep syslog |grep -v grep
root 7978 0.0 0.2 1372 156 ? S 03:01 0:00 syslogd -m 0
luisa:~# kill -HUP 7978
luisa:~#
Una vez realizados estos pasos ya conseguimos que se registren los eventos
que nos interesan en el fichero /var/run/cifra; este archivo es una
tubería con nombre, de forma que los datos que le enviamos no se graban en
el disco realmente, sino que sólo esperan a que un proceso lector los
recoja. Ese proceso lector será justamente el cliente ssh, encargado
de cifrarlos y enviarlos al sistema remoto; para ello debemos lanzar una orden
como:
luisa:~# cat /var/run/cifra | ssh -x rosita 'cat >>/var/log/luisa'
Si tenemos configurado SSH para que autentique sin clave podemos lanzar
el proceso directamente en background; si tenemos que introducir la
clave del root, una vez tecleada podemos parar el proceso y relanzarlo
también en segundo plano (esto es simplemente por comodidad, realmente no
es necesario). Lo único que estamos haciendo con este mecanismo es cifrar lo
que llega al fifo y enviarlo de esta forma al sistema remoto, en el que se descifrará y
se guardará en el fichero /var/log/luisa.
Quizás nos interese añadir unas líneas en los scripts de
arranque de nuestra máquina para que este proceso se lance automáticamente
al iniciar el sistema; si lo hacemos así hemos de tener cuidado con la
autenticación, ya que si ssh requiere una clave para conectar con el
sistema remoto es probable que la máquina tarde más de lo normal en arrancar
si un operador no está en la consola: justamente el tiempo necesario
hasta que ssh produzca un timeout por no teclear el password
de root en el sistema remoto. Si al producirse el timeout el
programa ssh no devuelve el control al shell, el sistema ni siquiera
arrancará; de cualquier forma, si ese timeout se produce no
estaremos registrando ningún evento en la otra máquina. Por supuesto,
también debemos prestar atención a otros problemas con la máquina destino
que eviten que la conexión se produzca, con un número máximo de usuarios
sobrepasado o simplemente que ese sistema esté apagado.
© 2002 Antonio Villalón Huerta