Ha llegado el momento de complicar algo las cosas. Nuestra intención es crear un cuadro de mandos en Kibana con las estadísticas de inicio de sesión de nuestro servidor. Para empezar tenemos que saber qué información nos interesa y configurar Logstash para que nos aporte dicha información, en nuestro caso es la siguiente:
- Inicios de sesión por SSH correctos
- Inicios de sesión por SSH incorrectos (Contraseña incorrecta)
- Inicios de sesión por SSH incorrectos (Usuarios incorrecto)
- Inicios de sesión por SUDO incorrectos
Para saber qué mensaje corresponde a cada caso, tendremos que crear la situación correspondiente, así se generarán las líneas en el LOG y lo podremos ver en Kibana. Una vez hecho obtendremos estos mensajes :
- Inicio de sesión por SSH correcto:
1 |
Aug 30 18:00:56 LekDemo sshd[25516]: Accepted password for sistemas from 192.168.1.6 port 51471 ssh2 |
- Inicio de sesión por SSH incorrecto (Contraseña incorrecta):
1 |
Aug 30 17:46:10 LekDemo sshd[25322]: Failed password for invalid user usuariomalo from 192.168.1.6 port 51213 ssh2 |
- Inicio de sesión por SSH incorrecto (Usuario incorrecto):
1 |
Aug 30 17:46:06 LekDemo sshd[25322]: Invalid user usuariomalo from 192.168.1.6 |
- Inicio de sesión por SUDO incorrecto:
1 |
Aug 30 18:06:23 LekDemo sudo: pam_unix(sudo:auth): authentication failure; logname=sistemas uid=1000 euid=0 tty=/dev/pts/4 ruser=sistemas rhost= user=sistemas |
Ahora tendremos que definir correctamente el patrón (pattern) correspondiente a cada mensaje para que el plugin Grok parser pueda extraer la información, para ello lo primero es documentarnos sobre el funcionamiento de Grok en la web de documentación de Elastic.
Los patrones que vamos a utilizar en este caso práctico son los siguientes:
1 2 3 4 5 6 7 8 9 10 11 |
# SSH password correcto {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{SYSLOGTIMESTAMP:timestamp} {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{HOSTNAME:host_target} sshd\[{269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM}\]: {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{DATA:action} password for {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{USERNAME:username} from {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{IP:src_ip} port {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM:port} ssh2 # SSH password incorrecto {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{SYSLOGTIMESTAMP:timestamp} {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{HOSTNAME:host_target} sshd\[{269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM}\]: {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{DATA:action} password for (invalid user |){269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{USERNAME:username} from {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{IP:src_ip} port {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM:port} ssh2 # SSH usuario incorrecto {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{SYSLOGTIMESTAMP:timestamp} {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{HOSTNAME:host_target} sshd\[{269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM}\]: {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{DATA:action} user {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{USERNAME:username} from {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{IP:src_ip} # SUDO password incorrecto {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{SYSLOGTIMESTAMP:timestamp} {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{HOSTNAME:host_target} {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{DATA:action}: pam_unix\(sudo:auth\): authentication failure; logname={269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{USERNAME:log_username} uid={269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM:uid} euid={269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM:euid} tty={269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{TTY:tty} ruser={269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{USERNAME:remote_username} rhost=(?:{269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{HOSTNAME:remote_host}|\s*) user={269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{USERNAME:username} |
Como podemos ver en los patrones, hemos creado un campo «action» para poder diferenciar cada caso y así poder añadir un TAG a cada registro. Dicho campo lo eliminaremos para que no añada al registro.
Con todo esto, ya podremos cambiar la actual sección filter de nuestro fichero /etc/logstash/conf.d/auth-log.conf por la siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
filter { if [type]=="auth" { grok { match => [ "message", "{269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{SYSLOGTIMESTAMP:timestamp} {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{HOSTNAME:host_target} sshd\[{269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM}\]: {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{DATA:action} password for {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{USERNAME:username} from {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{IP:src_ip} port {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM:port} ssh2" ] match => [ "message", "{269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{SYSLOGTIMESTAMP:timestamp} {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{HOSTNAME:host_target} sshd\[{269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM}\]: {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{DATA:action} password for (invalid user |){269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{USERNAME:username} from {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{IP:src_ip} port {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM:port} ssh2" ] match => [ "message", "{269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{SYSLOGTIMESTAMP:timestamp} {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{HOSTNAME:host_target} sshd\[{269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM}\]: {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{DATA:action} user {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{USERNAME:username} from {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{IP:src_ip}" ] match => [ "message", "{269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{SYSLOGTIMESTAMP:timestamp} {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{HOSTNAME:host_target} {269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{DATA:action}: pam_unix\(sudo:auth\): authentication failure; logname={269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{USERNAME:log_username} uid={269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM:uid} euid={269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{BASE10NUM:euid} tty={269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{TTY:tty} ruser={269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{USERNAME:remote_username} rhost=(?:{269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{HOSTNAME:remote_host}|\s*) user={269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{USERNAME:username}" ] match => [ "message", "{269a43e619103fec20a2ff1fa4c6fa62e033dc304f85b3cc053bbec70bac83ad}{SYSLOGLINE}" ] } if [action]=="Failed" { mutate { add_tag => "ssh_fail_psw" } } else if [action]=="Accepted" { mutate { add_tag => "ssh_sucessful" } } else if [action]=="Invalid" { mutate { add_tag => "ssh_fail_user" } } else if [action]=="sudo" { mutate { add_tag => "sudo_fail" } } mutate { remove_field => ["action"] } } } |
Reiniciamos el servicio de Logstash y a partir de este momento ya podremos ver en Kibana los nuevos registros que se generen con los campos y tags que hemos configurado gracias a los patterns de Grok.
En el próximo articulo crearemos un panel de control donde ver fácilmente toda la información de inicios de sesión.
Referencias de interés:
- https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html
- https://gist.github.com/juanje/3081998