Manual de integridad de archivos Linux
El desarrollo para el monitoreo de integridad de archivos Linux, fue desarrollado para Banobras específicamente para poder monitorear rutas específicas en servidores críticos. A continuación, se detallan características principales sobre el desarrollo, los pasos que deben realizarse en en el servidor donde se implementará el mismo y en los servidores a monitorear.
Características principales
Verificación de existencia de archivos: El plugin verifica si ciertos archivos específicos existen en los sistemas Linux de destino.
Recolección de metadatos de archivos: Para cada archivo que existe, recopila metadatos importantes:
Fecha y hora de la última modificación.
Tamaño del archivo.
Propietario (usuario y grupo).
Permisos del archivo.
Configuración de auditd: El plugin configura automáticamente el sistema de auditoría de Linux (auditd) para monitorear cambios en estos archivos mediante:
Creación de reglas de auditoría personalizadas para cada archivo monitoreado.
Especificación de operaciones a monitorear.
Configuración de alertamiento.
Reinicio del servicio auditd para aplicar los cambios.
¿Cómo funciona?
El plugin se conecta al sistema Linux de destino mediante SSH.
Verifica la existencia de cada ruta de archivo configurada.
Para los archivos existentes, recopila metadatos detallados.
Configura reglas de auditoría para monitorear cambios en estos archivos.
Organiza los resultados en tablas estructuradas para su visualización en opConfig.
Genera alertas para cualquier archivo que no se haya podido encontrar.
Configuración en el servidor donde se implementará
Importante: asegúrese de guardar backups de los archivos que ya existan en el servidor.
Es indispensable tener instalado Net::OpenSSH en el servidor. Se puede comprobar ejecutando lo siguiente (deberás ver el texto “Está instalado”):
perl -MNet::OpenSSH -e 'print "Está instalado\n"'
Si se muestra una salida diferente, deberá de realizarse la instalación correspondiente.
Acceder a la ruta:
/etc/ssh/ssh_config.d/
Comentar la siguiente línea del archivo 04-ipa.conf y guardarlo. El nombre del archivo podría variar dependiendo del sistema operativo, pero esa instrucción deberá ser comentada donde corresponda.
# Match exec true
Reiniciar el demonio sshd, ejecutando:
service sshd restart
Colocar el archivo en la ruta:
/usr/local/omk/conf/config_plugins/
Acceder a la ruta:
/usr/local/omk/conf/config_plugins/
Una vez dentro, ejecutar los siguientes 2 comandos:
chmod 664
chown root:root linuxFileCheckCommands.pm
Acceder a la ruta:
/usr/local/omk/conf/command_sets.d/
Generar el set de comandos con extensión .json, se recomienda nombrarlo como nombre-del-set.json. Deberá contener lo siguiente:
{
"nombre-del-set": {
"parameters": [],
"purging_policy": {
"keep_last": 0,
"autoprotect_first_revision": null,
"purge_older_than": null
},
"active": "true",
"os_info": {
"os": "/(Linux|CentOS|Ubuntu)/"
},
"scheduling_info": {
"attempt_timeout_recovery": 0,
"parameters_required": null,
"run_local": null,
"run_commands_on_separate_connection": null
},
"commands": [
{
"compare_to_previous_revision": null,
"configure_auditd": 1,
"report_level_min_changes": null,
"use_collection_plugin": "linuxFileCheckCommands",
"use_processing_plugins": [
"linuxFileCheckCommands"
],
"command": "echo test",
"plugin_interaction_timeout": 120,
"tags": [
"report-change",
"detect-change",
"nombre-del-nodo"
],
"file_integrity_paths": [
{
"path": "/primera/ruta/archivo",
"audit_execute": false,
"audit_attribute": true,
"audit_read": false,
"audit_write": true,
"audit_alert": "fatal"
},
{
"path": "/segunda/ruta/archivo.ext",
"audit_execute": false,
"audit_attribute": true,
"audit_read": false,
"audit_write": true,
"audit_alert": "fatal",
"requires_sudo": true
}
]
}
]
}
}
Comprobar sintaxis ejecutando el siguiente comando (deberá devolver todo el contenido del archivo .json; en caso de ver algún error, revisar en qué línea es):
jq . nombre-del-set.json
Los parámetros que deben ser modificados en el set de comandos son:
"nombre-del-set" -> se recomienda algo como NOMBREDELNODO_fim-linux; en este caso, el nombre del archivo tendrá que ser NOMBREDELNODO_fim-linux.json.
"plugin_interaction_timeout": 120, → este parámetro es por defecto por si el tiempo de conexión hacia los servidores que se van a monitorear es tardado; se recomienda dejar así.
"tags": ["nombre-del-nodo"], → se recomienda poner como tag el nombre del nodo; por ejemplo, si un nodo se llama SERVIDOR1, colocarlo tal cual dentro de las comillas.
"path": "/primera/ruta/archivo", → colocar la ruta exacta y tantas como se requieran; por ejemplo, si el archivo a monitorear es /var/log/logs.log, colocarlo tal cual.
"requires_sudo": true → únicamente usarlo si el archivo a monitorear requiere permiso de root para poderse leer; por ejemplo, si antes de acceder a la carpeta se debe ejecutar un "sudo -i".
Posterior a la generación del archivo nombre-del-set.json, ejecutar:
chmod 664 nombre-del-set.json
chown root:root nombre-del-set.json
Acceder a la siguiente ruta:
/etc/rsyslog.d/
Generar el archivo 10-receive-omk-auditd-log.conf para recibir los logs. Contendrá lo siguiente:
# Enable UDP listener
module(load="imudp")
input(type="imudp" port="514")
# Enable TCP listener (optional)
module(load="imtcp")
input(type="imtcp" port="514")
# Template for storing remote logs
$template RemoteLogs,"/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log"
# Only process logs with programname/tag "auditplugin"
if $programname == 'auditplugin' then {
?RemoteLogs
stop
}
*.* ?RemoteLogs
Posterior a la generación del archivo, ejecutar lo siguiente:
chmod 640 10-receive-omk-auditd-log.conf
chown root:root 10-receive-omk-auditd-log.conf
service rsyslog restart
Será necesario comenzar a ingerir los logs de auditd. Acceder a la ruta:
/usr/local/omk/conf
Editar el archivo opCommon.json e identificar la sección "opevents_logs". Ahí, deberá de agregarse lo siguiente (una línea por cada servidor a monitorear, separado por comas):
"auditd_log" : [
"/var/log/remote/nombre-del-nodo1/auditplugin.log",
"/var/log/remote/nombre-del-nodo2/auditplugin.log",
"/var/log/remote/nombre-del-nodo3/auditplugin.log"
],
Comprobar sintaxis ejecutando el siguiente comando (deberá devolver todo el contenido del archivo .json; en caso de ver algún error, revisar en qué línea es):
jq . opCommon.json
Posterior a la edición de este archivo, es necesario ejecutar lo siguiente:
service omkd restart
Se requerirá definir un nuevo analizador (parser), el cual solo leerá los logs de auditd que contenga la etiqueta de este desarrollo. Acceder a la ruta:
/usr/local/omk/conf/
Editar el archivo EventParserRules.json. Ahí, deberá de agregarse lo siguiente (se recomienda agregar al inicio del archivo, antes de la instrucción "winlogd" y después del { de apertura):
"auditplugin_testing":{
"5":{
"IF": "(\\w+)\\s+auditplugin:\\s+timestamp=(\\d+\\.\\d+)\\s+audit_event_id=(\\d+)\\s+syscall=([^']+)\\s+cwd='([^']+)'\\s+file='([^']+)'\\s+AUID='([^']+)'\\s+UID='([^']+)'\\s+event='([^']+)'\\s+alert_type='(fwopconfig_warning)'",
"THEN": [
"capture(host,time,auditd_event_id,syscall,cwd,element,auid,uid,level)",
"set.event(auditd filechange)",
"set.priority(2)"
]
},
"10":{
"IF": "(\\w+)\\s+auditplugin:\\s+timestamp=(\\d+\\.\\d+)\\s+audit_event_id=(\\d+)\\s+syscall=([^']+)\\s+cwd='([^']+)'\\s+file='([^']+)'\\s+AUID='([^']+)'\\s+UID='([^']+)'\\s+event='([^']+)'\\s+alert_type='(fwopconfig_normal)'",
"THEN": [
"capture(host,time,auditd_event_id,syscall,cwd,element,auid,uid,level)",
"set.event(auditd filechange)",
"set.priority(5)"
]
},
"20":{
"IF": "(\\w+)\\s+auditplugin:\\s+timestamp=(\\d+\\.\\d+)\\s+audit_event_id=(\\d+)\\s+syscall=([^']+)\\s+cwd='([^']+)'\\s+file='([^']+)'\\s+AUID='([^']+)'\\s+UID='([^']+)'\\s+event='([^']+)'\\s+alert_type='(fwopconfig_fatal)'",
"THEN": [
"capture(host,time,auditd_event_id,syscall,cwd,element,auid,uid,level)",
"set.event(auditd filechange)",
"set.priority(10)"
]
}
},
Comprobar sintaxis ejecutando el siguiente comando (deberá devolver todo el contenido del archivo .json; en caso de ver algún error, revisar en qué línea es):
jq . EventParserRules.json
Posterior a la edición de estos archivos, es necesario ejecutar lo siguiente:
service omkd restart
service opeventsd restart
En opConfig, deberán agregarse las credenciales correspondientes con el proceso ya conocido (mediante System > Edit Credential Sets > Add Credential Set) y agregarlas a los nodos que se van a monitorear, mediante el módulo Administrator > Seleccionar Nodo > Connection:
Y posteriormente asegurarse que en OS-Info aparezca la palabra Linux; puede agregarse manualmente.
Configuración en el servidor que se va a monitorear
Se requiere tener acceso SSH de solo lectura al servidor que se va a monitorear para:
Verificar la existencia de archivos en los sistemas objetivo
Recopilar metadatos de archivos (tiempos de modificación, tamaños, propiedad, permisos)
Leer el estado actual de las reglas de auditoría (audit rules)
Se requiere tener acceso privilegiado (mediante sudo) para:
Escribir reglas de auditoría en /etc/audit/rules.d/file-integrity.rules.
Reiniciar el servicio auditd para aplicar las nuevas reglas de monitoreo.
El servidor de destino necesitará tener auditd y rsyslog instalado para la supervisión en tiempo real de archivos. El conjunto de comandos ajustará la configuración de auditd en la primera ejecución. Para comprobar esto, ejecutar según sea el caso para comprobar la instalación (o instalar los paquetes si hacen falta):
Validar:
which auditd
which rsyslogd
systemctl status auditd
systemctl status rsyslog
Instalar:
apt-get install auditd audispd-plugins rsyslog
dnf install auditd audispd-plugins rsyslog
Una vez instalados los plugins necesarios, colocar el archivo en la ruta:
/usr/bin/
Acceder a la ruta:
/usr/bin/
Una vez dentro, ejecutar los siguientes 2 comandos:
chmod +x omkaudit.pl
chown root:root omkaudit.pl
Acceder a la ruta:
/etc/ssh/ssh_config.d/
Comentar la siguiente línea del archivo 04-ipa.conf y guardarlo. Notas: el nombre del archivo podría variar dependiendo del sistema operativo, pero esa instrucción deberá ser comentada donde corresponda. Si el archivo no existe, omitir este paso.
# Match exec true
Reiniciar el demonio sshd, ejecutando:
service sshd restart
Acceder a la ruta:
/etc/audisp/plugins.d/
Una vez dentro de la carpeta, generar el archivo omkaudit.conf. Deberá contener lo siguiente:
active = yes
direction = out
path = /usr/bin/omkaudit.pl
type = always
format = string
Posterior a la generación del archivo, ejecutar lo siguiente:
service auditd restart
Confirmar que el complemento se ha cargado ejecutando alguno de los siguientes dos comandos:
service auditd status
systemctl auditd status
Deberá mostrarse algo similar a esto:
auditd.service - Security Auditing Service
Loaded: loaded (/lib/systemd/system/auditd.service; enabled; preset: enabled)
Active: active (running) since Mon 2025-05-12 16:46:43 NZST; 22h ago
Docs: man:auditd(8)
https://github.com/linux-audit/audit-documentation
Process: 13195 ExecStart=/sbin/auditd (code=exited, status=0/SUCCESS)
Process: 13215 ExecStartPost=/sbin/augenrules --load (code=exited, status=0/SUCCESS)
Main PID: 13208 (auditd)
Tasks: 4 (limit: 19145)
Memory: 1.9M
CPU: 1.225s
CGroup: /system.slice/auditd.service
├─13208 /sbin/auditd
└─13211 /usr/bin/perl /usr/bin/omkaudit.pl
Revisar el archivo:
/var/log/omkaudit.log
En el cual deberá mostrarse algo similar a esto (registro indicando que el complemento se ha iniciado):
timestamp=1747025203 Plugin started
Para finalizar, acceder a la ruta:
/etc/rsyslog.d/
Una vez dentro de la carpeta, generar el archivo 10-send-omk-auditd-log.conf. Deberá contener lo siguiente:
module(load="imfile" PollingInterval="10")
input(type="imfile"
File="/var/log/omkaudit.log"
Tag="auditplugin:"
Severity="info"
Facility="local6"
PersistStateInterval="10"
reopenOnTruncate="on"
)
# Forward this log to the remote server
local6.* @@omk.example.com:514 # Use @@ for TCP
Nota: se deberá de modificar omk.example.com por la dirección del servidor opEvents, donde se recibirán los registros de auditoría que serán procesados, por ejemplo:
local6.* @@192.168.1.1:514 # Use @@ for TCP
Posterior a la generación del archivo, ejecutar lo siguiente:
service rsyslog restart
Configuración de Operador Virtual
Puede generarse un Operador Virtual para la ejecución manual de la integridad de archivos. A continuación los pasos para realizarlo:
Acceder a la carpeta:
/usr/local/omk/lib/json/opConfig/table_schemas
Generar un backup del archivo opConfig_action-elements.json. Editar el archivo original y agregar lo siguiente (ajustar donde corresponda, debe generarse uno por cada nodo que se agregue):
{
"name": "Integridad Linux NOMBREDELNODO",
"description": "Integridad Linux NOMBREDELNODO",
"command_sets": ["NOMBREDELNODO_fim-linux"],
"nodes": ["NOMBREDELNODO"],
"tags": ["NOMBREDELNODO"],
"buttonLabel": "Integridad Linux NOMBREDELNODO",
"buttonClass": "btn-primary"
},
El archivo debe verse así:
Guardar el archivo y ejecutar:
service opconfigd restart
En la UI de opConfig, se deberá de ver algo así, listo para ejecutarse:
Y se verá de esta forma. Ejemplo creado correctamente:
Configuración de ejecución automática
La integridad de archivos se puede configurar para que se ejecute de forma automática vía el cron de opConfig.
Acceder a la carpeta:
/etc/cron.d/
Editar el archivo opconfig y agregar lo siguiente, acorde al operador virtual creado arriba (se recomienda generar un backup, copiando el archivo a otra carpeta, nunca duplicar el archivo en cron.d porque puede provocarse un mal funcionamiento de las tareas automatizadas; de igual forma, ajustar el tiempo como mejor convenga, en este ejemplo, se ejecutará cada minuto 15; sugerimos usar Crontab.guru - The cron schedule expression generator para validar los tiempos de ejecución):
*/15 * * * * root export PERL5LIB=/usr/share/perl5:/usr/local/lib64/perl5:/usr/lib64/perl5 PAR_GLOBAL_TMPDIR=/usr/local/omk/var/lib/common/||:; /usr/local/omk/bin/opconfig-cli.pl quiet=1 act=run_command_sets tags="NOMBREDELNODO" names="NOMBREDELNODO-B_fim-linux" nodes="NOMBREDELNODO"
Guardar el archivo y ejecutar:
service crond restart
Interpretación en opConfig y opEvents
Una vez que todo esté configurado, al ejecutar la primera revisión, se mostrarán los resultados en tablas:
Tabla “Alerts”: muestra el tipo de alerta, el nombre del nodo, el elemento (ruta), el estado y los detalles. En este ejemplo, el archivo root.txt no se encuentra, por lo que aparece el estado Fatal del archivo.
Tabla “Conditions”: muestra un icono del estado de cada ruta.
Tabla “Derived Information: File Integrity Status”: muestra más información sobre las rutas declaradas, como la fecha de creación, fecha de última modificación, el tamaño del archivo y los permisos de cada uno.
Tabla “Derived Information: File Count”: muestra el total de archivos encontrados, el total de archivos no encontrados y el total de archivos configurados.
Apartado “Command Output”: muestra la salida de la ejecución del comando de auditoría, el log en crudo que genera cada una de las tablas de arriba.
En este ejemplo, se genera un evento “File Integrity Alert” en opEvents, ya que no se ha detectado el archivo root.txt. Este evento contendrá un identificador único, que se podrá ver en la URL. Por ejemplo:
http://ipdelservidor/en/omk/opEvents/events/6847317cb959c8b71c3ce9d8/event_context
Cuando el archivo root.txt es detectado nuevamente por la ejecución del comando, se generará una alerta “File Integrity Alert Closed”, que indica que el evento ha sido clareado: