6 dic 2017

IBM i: Journal de auditoría - Buscando las migajas de pan



La mayoría de quienes trabajamos con IBM i sabemos de qué se trata el journal de auditoría. Lamentablemente no todos lo usan, muchos menos lo consultan.
Con el journal de auditoría podemos saber quien está intentando hacer algo indebido, podemos determinar la IP, desde que estación de trabajo se conectó, que comandos intentó usar, etc.
Si nos ponemos a definir las razones por las cuales mucho no lo explotan podríamos mencionar:
  • Espacio en disco: Es cierto, puede ocupar mucho espacio si no lo controlamos
  • Desconocimiento: Aunque muchos teman admitirlo, no todos lo conocen al 100%
  • Tiempo: Si, hay que invertir tiempo en revisar la información.
  • Complejidad y/o volumen de la información que se recupere
Que pasaría si podemos reducir estos problemas para sacarle el jugo a este recurso fantástico que incluye nuestro servidor?
Si podemos separar sólo la información que nos interesa y almacenarlo en tablas quizá podamos ir depurando los journals antiguos.
Si automatizamos la conversión y la generación de reportes podríamos reducir el tiempo que empleamos
Si pudiéramos tener una serie de templates o una forma simple de hacer consultas podríamos reducir la complejidad de información a leer.
Manos a la obra
Primero lo primero, debemos activarlo. Esto requiere de los siguientes pasos:
1) Crear una biblioteca para los receivers
CRTLIB LIB(AUDJRN) TEXT('Journal Receivers de auditoria') AUT(*EXCLUDE) CRTAUT(*EXCLUDE) 

2) Creo el 1er receiver 
CRTJRNRCV JRNRCV(AUDJRN/AUDJRN0000)  

3) Creo el journal de auditoría
CRTJRN JRN(QSYS/QAUDJRN) JRNRCV(AUDJRN/AUDJRN0000) JRNOBJLMT(*MAX10M)   

Ahora debemos configurar los valores del sistema para "encender" el journal e indicar que información queremos guardar
1) Activo el journal
CHGSYSVAL SYSVAL(QAUDCTL) VALUE('*AUDLVL *NOQTEMP *OBJAUD')

2) Valores a auditar (Según la necesidad, estos son algunos básicos)
CHGSYSVAL SYSVAL(QAUDLVL) VALUE('*AUDLVL2')
CHGSYSVAL SYSVAL(QAUDLVL2) VALUE('*AUTFAIL *CREATE  *DELETE  *JOBDTA  *NETCMN  *SAVRST  *SECURITY *SERVICE *SYSMGT  *PGMFAIL')

Y luego debemos indicar los comandos, objetos y usuarios a auditar:
1) Usuarios
CHGUSRAUD USRPRF(USRTST01) OBJAUD(*CHANGE) AUDLVL(*CMD *NETBAS *JOBDTA *CREATE *DELETE)

2) Objetos/comandos
CHGOBJAUD OBJ(QSYS/CHGJOB) OBJTYPE(*CMD) OBJAUD(*ALL)

A partir de ejecutar todos estos comandos estaremos recogiendo información, según los valores que hayamos indicado.
El punto está, cómo podemos ver la información ? Naturalmente usamos el comando DSPJRN, pero la información no se ve en una forma muy amigable, aunque sí es bastante veloz. Toda la información se muestra agolpada, lo cual dificulta su lectura.
Por otro lado, sólo podemos verlo desde pantalla verde, lo cual no siempre es lo ideal. Quienes tengan departamento de auditoría muchas veces deben lidiar con el desconocimiento de la plataforma y la separación de roles.
No sería mejor poder hacer consultas usando SQL sin mayor trámite? En este ejemplo listamos las entradas PW (fallas de password) de las últimas 48 horas en direcciones diferentes a 10.* y 192.* para determinar conexiones externas (claro, si ese es nuestro direccionamiento interno)
SELECT *                                              
FROM TABLE(QSYS2.Display_Journal('QSYS', 'QAUDJRN',   
STARTING_TIMESTAMP => CURRENT TIMESTAMP - 48 HOURS , 
STARTING_RECEIVER_NAME => '*CURCHAIN'                 
)) AS x                                               
where JOURNAL_entry_type = 'PW'                       
and REMOTE_ADDRESS not like '10.%'                    
and REMOTE_ADDRESS not like '192.%'                   

IBM nos provee de una serie de UDTFs que podemos usar para consultas de este tipo. Sin embargo el resultado sigue siendo genérico, no tendremos campos específicos.
Para poder ver la información en forma más amigable, IBM nos provee de plantillas que podemos copiar y usar como un "cascarón" donde copiamos la información, pero si queremos hacerlo de forma más simple, podemos usar el comando CPYAUDJRNE:
CPYAUDJRNE ENTTYP(AF PW CP SV DS VC VN VS X0)          
             OUTFILE(ESSELWARE/QAUDIT) OUTMBR(*FIRST 
             *ADD) JRNRCV(*CURCHAIN) FROMTIME(28112017 000000)                                    

Si creamos un par de tablas con las descripciones que aparecen en los manuales, podríamos hacer consultas que sean más legibles:
SELECT PWTSTP as Fecha,
PWUSRN as Usuario, 
PWJOB as Trabajo,
PWNBR as Nro_Trabajo, 
PWPGM as Programa,
PWPGMLIB as Biblioteca,
trim(PWRADR) as Direccion_IP, 
B.PWTYPEDS as Tipo_de_Intento 
from ESSELWARE.QAUDITPW a, 
ESSELWARE.AUDPWTYPE b  
where a.PWTYPE = b.PWTYPE 
and PWTSTP >= '2017-11-01' 
and PWTSTP < '2017-12-01' 
order by PWTSTP

Podemos crear un simple CL que corra el comando CPYAUDJRNE todas las madrugadas para descargar la información en tablas auxiliares de los valores que nos interesan:
PW: Fallas de autenticación
AF: Fallas de autorización (intentos fallidos de acceder a objetos)
SV: Cambios a valores del sistema
CD: Comandos
CP: Cambios, creación o restauración de perfiles de usuarios
DS: Reset de password del usuario de DST (recuerden que con el DST podemos recuperar el QSECOFR)
ST: Uso de Herramientas de Servicio (recuerden que con el DST podemos recuperar el QSECOFR)
VS: Iniciando o terminando una sesión de servidor
... y los valores que consideren necesarios.
Luego podríamos enviar mediante un ETL, DataPump o CSV->FTP los datos a una base de datos auxiliar (MySQL? SQLite? SQL Server?) para la explotación por parte los oficiales de seguridad.
En mi caso uso unos pequeños programas PHP para generar los reportes. Si les interesa el código con gusto se los comparto. Envíen comentarios o mensajes para solicitarlos.
Algunos consejos
  • Controlen el espacio en disco
  • Revisen las entradas sensibles de forma periódica. Incluso hay gente que cuenta con un programa de envío diario de reportes en PDF. Esto se podría hacer sin mucha complicación con un CL bastante simple.
  • Protejan la biblioteca de los receivers
  • Respalden los journals antes de borrarlos. La mejor práctica es hacerlo en una cinta separada, quizá junto con los journals de tablas (tema para otro artículo).
  • Algunas entradas tienen información parcial o de forma poco amigable, como podrían ser las conexiones ODBC/JDBC/OleDB/ADO. En esos casos quizá convenga generar logs en tablas usando Exit Point Programs.
  • Si existen requerimientos regulatorios siempre recomiendo usar herramientas, que ayudan a automatizar la generación de reportes y suelen tener plantillas para las auditorías. Algunas de estas herramientas incluso se llevan la información de forma continua a otra base de datos por aquello de la separación de roles.
  • Si el período a analizar es grande (3 o más meses) y el espacio a emplear es considerable, nuevamente, hay herramientas que administran de forma eficiente el espacio y suelen llevarse el análisis a un equipo separado. Recuerden que el costo x TB en IBM i suele ser más alto que 1 TB en la nube o en un servidor con Intel y MariaDB/MySQL/SQLite
Espero que les haya sido de utilidad.

Cómo conectarme a un servidor remoto en una red protegida - Versión actualizada

En un artículo anterior describí cómo conectarse a un equipo remoto en una red protegida http://diego-k.blogspot.mx/2014/12/como-conectarme...