En este artículo voy a explicar cómo registrar fácilmente toda la actividad del protocolo SFTP para saber qué usuario crea/modifica/elimina qué archivo. Por defecto OpenSSH registra sólo quién se conectó exitosamente al servidor SSH, a través del log auth.log
. Sin embargo, para el caso del servidor SFTP, es posible registrar todas las operaciones del protocolo FTP y saber exactamente qué usuario accedió a qué archivo.
El primer paso consiste en editar el archivo de configuración del servidor SSH:
root@debian# nano /etc/ssh/sshd_config
Cambiar la línea:
Subsystem sftp /usr/lib/openssh/sftp-server
Por:
Subsystem sftp /usr/lib/openssh/sftp-server -l VERBOSE -f LOCAL0
A fin de enviar el log del servidor SFTP a un archivo específico (en vez de a auth.log
), rsyslog dispone desde LOCAL0 hasta LOCAL7, dependiendo de la configuración actual de rsyslog.
En nivel de detalle de actividad puede ser QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, o DEBUG3.
Esta configuración también funciona para las directivas internal-sftp
.
Guardar los cambios y configurar rsyslog para que envíe los mensajes de la facility local0 a un archivo personalizado:
root@debian# nano /etc/rsyslog.conf
Agregar la siguiente línea
local0.* /var/log/sftp-server.log
Reiniciar rsyslog:
root@debian# /etc/init.d/rsyslog restart [ ok ] Stopping enhanced syslogd: rsyslogd. [ ok ] Starting enhanced syslogd: rsyslogd.
Luego es posible recargar el servidor SSH para verificar que la configuración sea correcta (y así evitar quedarnos fuera del servidor ante un error de sintaxis):
root@debian# /etc/init.d/ssh reload [ ok ] Reloading OpenBSD Secure Shell server's configuration: sshd.
También es posible verificar la configuración del servidor SSH mediante sshd -t
.
En general, cuando se trabaja sobre la configuración del servidor SSH o el firewall, es recomendable hacerlo desde la consola del servidor (no a través de la red).
Si todo está OK, reiniciar el servidor SSH:
root@debian# service ssh restart [ ok ] Restarting OpenBSD Secure Shell server: sshd.
Inmediatamente es posible monitorear el log con tail
:
root@debian# tail -f /var/log/sftp-server.log Apr 7 16:24:05 localhost sftp-server[26933]: session opened for local user webadmin from [192.168.234.5] Apr 7 16:24:05 localhost sftp-server[26933]: received client version 5 Apr 7 16:24:05 localhost sftp-server[26933]: realpath "/home/webadmin" Apr 7 16:24:05 localhost sftp-server[26933]: lstat name "/home/webadmin" Apr 7 16:24:06 localhost sftp-server[26933]: opendir "/home/webadmin" Apr 7 16:24:06 localhost sftp-server[26933]: closedir "/home/webadmin" Apr 7 16:24:21 localhost sftp-server[26933]: lstat name "/home/webadmin/logo.png" Apr 7 16:24:21 localhost sftp-server[26933]: sent status No such file Apr 7 16:24:21 localhost sftp-server[26933]: lstat name "/home/webadmin/logo.png.filepart" Apr 7 16:24:21 localhost sftp-server[26933]: sent status No such file Apr 7 16:24:21 localhost sftp-server[26933]: open "/home/webadmin/logo.png.filepart" flags WRITE,CREATE,TRUNCATE mode 0666 Apr 7 16:24:22 localhost sftp-server[26933]: close "/home/webadmin/logo.png.filepart" bytes read 0 written 203614 Apr 7 16:24:22 localhost sftp-server[26933]: rename old "/home/webadmin/logo.png.filepart" new "/home/webadmin/logo.png" Apr 7 16:24:22 localhost sftp-server[26933]: set "/home/webadmin/logo.png" modtime 20170316-19:26:38 Apr 7 16:24:22 localhost sftp-server[26933]: opendir "/home/webadmin" Apr 7 16:24:22 localhost sftp-server[26933]: closedir "/home/webadmin" Apr 7 16:24:25 localhost sftp-server[26933]: remove name "/home/webadmin/logo.png" Apr 7 16:24:25 localhost sftp-server[26933]: opendir "/home/webadmin" Apr 7 16:24:25 localhost sftp-server[26933]: closedir "/home/webadmin" Apr 7 16:24:27 localhost sftp-server[26933]: session closed for local user webadmin from [192.168.234.5]
El nivel de detalle INFO es más sintético y probablemente más útil:
Subsystem sftp /usr/lib/openssh/sftp-server -l INFO -f LOCAL0
root@debian# tail -f /var/log/sftp-server.log Apr 7 16:33:06 localhost sftp-server[27107]: session opened for local user webadmin from [192.168.234.5] Apr 7 16:33:07 localhost sftp-server[27107]: opendir "/home/webadmin" Apr 7 16:33:07 localhost sftp-server[27107]: closedir "/home/webadmin" Apr 7 16:33:20 localhost sftp-server[27107]: sent status No such file Apr 7 16:33:20 localhost sftp-server[27107]: sent status No such file Apr 7 16:33:20 localhost sftp-server[27107]: open "/home/webadmin/logo.png.filepart" flags WRITE,CREATE,TRUNCATE mode 0666 Apr 7 16:33:21 localhost sftp-server[27107]: close "/home/webadmin/logo.png.filepart" bytes read 0 written 203614 Apr 7 16:33:21 localhost sftp-server[27107]: rename old "/home/webadmin/logo.png.filepart" new "/home/webadmin/logo.png" Apr 7 16:33:21 localhost sftp-server[27107]: set "/home/webadmin/logo.png" modtime 20170316-19:26:38 Apr 7 16:33:21 localhost sftp-server[27107]: opendir "/home/webadmin" Apr 7 16:33:21 localhost sftp-server[27107]: closedir "/home/webadmin"
Configuración para internal-sftp con chroot
La situación cambia cuando se desea loguear la actividad del protocolo SFTP para usuarios que utilizan internal-sftp
y un acceso restringido mediante chroot
.
Al correr chrooteado, el proceso internal-sftp
no tendrá acceso al dispositivo /dev/log
desde el cual rsyslogd lee los mensajes locales. Entonces es necesario indicarle (a rsyslogd) que cree un socket Unix en la ruta /dev/log
de cada directorio donde se va a hacer chroot.
A modo de ejemplo, supongamos que el acceso SSH para el usuario "linuxito" se ha configurado de la siguiente forma:
Match User linuxito ForceCommand internal-sftp -l INFO -f LOCAL0 PasswordAuthentication yes ChrootDirectory /var/www/linuxito/ AllowTcpForwarding no MaxSessions 5
Será necesario indicarle a rsyslogd que cree un socket unix en la ruta /var/www/linuxito/dev/log
. De esta forma, el proceso internal-sftp
(cuyo raíz es en realidad /var/www/linuxito
) será capaz de enviar los mensajes a rsyslog a través del dispositivo /var/www/linuxito/dev/log
(/dev/log
desde su punto de vista chrooteado). A tal fin se dispone de la directiva $AddUnixListenSocket
.
Editar el archivo de configuración de rsyslog:
root@debian# nano /etc/rsyslog.conf
Agregar la siguiente línea:
$AddUnixListenSocket /var/www/linuxito/dev/log
Luego crear el directorio /dev
dentro del chroot y reiniciar rsyslog:
root@debian# mkdir /var/www/linuxito/dev root@debian# service rsyslog restart [ ok ] Stopping enhanced syslogd: rsyslogd. [ ok ] Starting enhanced syslogd: rsyslogd. root@debian# ll /var/www/devel/dev/ total 0 srw-rw-rw-+ 1 root root 0 Apr 7 17:26 log
Se observa que se ha creado el socket Unix exitosamente.
Inmediatamente es posible acceder por SFTP utilizando el usuario en cuestión y comprobar que los mensajes se registran correctamente en el archivo correspondiente al facility LOCAL0
:
Apr 7 17:27:48 localhost internal-sftp[28442]: session opened for local user linuxito from [192.168.234.5] Apr 7 17:27:48 localhost internal-sftp[28442]: opendir "/devel/public_html" Apr 7 17:27:48 localhost internal-sftp[28442]: closedir "/devel/public_html" Apr 7 17:27:53 localhost internal-sftp[28442]: sent status No such file Apr 7 17:27:53 localhost internal-sftp[28442]: sent status No such file Apr 7 17:27:53 localhost internal-sftp[28442]: open "/devel/public_html/logo.png.filepart" flags WRITE,CREATE,TRUNCATE mode 0666 Apr 7 17:27:54 localhost internal-sftp[28442]: close "/devel/public_html/logo.png.filepart" bytes read 0 written 203614 Apr 7 17:27:54 localhost internal-sftp[28442]: rename old "/devel/public_html/logo.png.filepart" new "/devel/public_html/logo.png" Apr 7 17:27:54 localhost internal-sftp[28442]: set "/devel/public_html/logo.png" modtime 20170316-22:26:38 Apr 7 17:27:54 localhost internal-sftp[28442]: opendir "/devel/public_html" Apr 7 17:27:54 localhost internal-sftp[28442]: closedir "/devel/public_html" Apr 7 17:27:57 localhost internal-sftp[28442]: remove name "/devel/public_html/logo.png" Apr 7 17:27:58 localhost internal-sftp[28442]: opendir "/devel/public_html" Apr 7 17:27:58 localhost internal-sftp[28442]: closedir "/devel/public_html" Apr 7 17:27:59 localhost internal-sftp[28442]: session closed for local user linuxito from [192.168.234.5]
Referencias
man sshd_config man rsyslogd