Cómo instalar Suricata y Zeek IDS con ELK en Ubuntu 20.10

Se ha hablado mucho de Suricata y Zeek (antes Bro) y de cómo ambos pueden mejorar la seguridad de la red.

Entonces, ¿cuál deberías implementar? La respuesta corta es ambos. La respuesta larga la encontrarás aquí.

En este (largo) tutorial instalaremos y configuraremos Suricata, Zeek, la pila ELK y algunas herramientas opcionales en un servidor Ubuntu 20.10 (Groovy Gorilla) junto con la pila Elasticsearch Logstash Kibana (ELK).

Nota: En este howto asumimos que todos los comandos se ejecutan como root. Si no es así, tienes que añadir sudo antes de cada comando.

Este how-to también asume que has instalado y configurado Apache2 si quieres proxyar Kibana a través de Apache2. Si no tienes Apache2 instalado encontrarás suficientes how-to’s para ello en este sitio. Nginx es una alternativa y proporcionaré una configuración básica para Nginx ya que yo mismo no uso Nginx.

Instalación de Suricata y suricata-update

Suricata

add-apt-repository ppa:oisf/suricata-stable

Entonces puedes instalar la última versión estable de Suricata con:

apt-get install suricata

Dado que eth0 está codificado en suricata (reconocido como un error) tenemos que sustituir eth0 por el nombre correcto del adaptador de red.

Así que primero vamos a ver qué tarjetas de red están disponibles en el sistema:

lshw -class network -short

Dará una salida como ésta (en mi portátil):

H/W path Device Class Description
=======================================================
/0/100/2.1/0 enp2s0 network RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
/0/100/2.2/0 wlp3s0 network RTL8822CE 802.11ac PCIe Wireless Network Adapter

Dará una salida como ésta (en mi servidor):

H/W path Device Class Description
=======================================================
/0/100/2.2/0 eno3 network Ethernet Connection X552/X557-AT 10GBASE-T
/0/100/2.2/0.1 eno4 network Ethernet Connection X552/X557-AT 10GBASE-T

En mi caso eno3

nano /etc/suricata/suricata.yml

Y sustituye todas las instancias de eth0 por el nombre del adaptador real de tu sistema.

nano /etc/default/suricata

Y sustituye todas las instancias de eth0 por el nombre real del adaptador de tu sistema.

Suricata-update

Ahora instalamos suricata-update para actualizar y descargar las reglas de suricata.

apt install python3-pip
pip3 install pyyaml
pip3 install https://github.com/OISF/suricata-update/archive/master.zip

Para actualizar suricata-update ejecuta:

pip3 install --pre --upgrade suricata-update

Suricata-update necesita los siguientes accesos:

Directorio /etc/suricata: acceso de lectura
Directorio /var/lib/suricata/rules: acceso de lectura/escritura
Directorio /var/lib/suricata/update: acceso de lectura/escritura

Una opción es simplemente ejecutar suricata-update como root o con sudo o con sudo -u suricata suricata-update

Actualizar tus reglas

Sin hacer ninguna configuración, el funcionamiento por defecto de suricata-update es utilizar el conjunto de reglas de Amenazas Emergentes Abiertas.

suricata-update

Este comando lo hará:

Buscar el programa suricata en su ruta para determinar su versión.

Buscará /etc/suricata/enable.conf, /etc/suricata/disable.conf, /etc/suricata/drop.conf y /etc/suricata/modify.conf para buscar los filtros que se aplicarán a las reglas descargadas.Estos archivos son opcionales y no es necesario que existan.

Descarga el conjunto de reglas Emerging Threats Open para tu versión de Suricata, por defecto la 4.0.0 si no se encuentra.

Aplica los filtros de habilitación, deshabilitación, eliminación y modificación cargados anteriormente.
Escribe las reglas en /var/lib/suricata/rules/suricata.rules.

Ejecuta Suricata en modo de prueba en /var/lib/suricata/rules/suricata.rules.

Suricata-Update adopta una convención diferente para los archivos de reglas que la que tiene tradicionalmente Suricata. La diferencia más notable es que las reglas se almacenan por defecto en /var/lib/suricata/rules/suricata.rules.

Una forma de cargar las reglas es la opción de línea de comandos -S Suricata. La otra es actualizar tu suricata.yaml para que se parezca a esto:

default-rule-path: /var/lib/suricata/rules
rule-files:
- suricata.rules

Este será el formato futuro de Suricata, así que usarlo es a prueba de futuro.

Descubrir otras fuentes de reglas disponibles

Primero, actualiza el índice de fuentes de reglas con el comando update-sources:

suricata-update update-sources

Tendrá el siguiente aspecto:

Ejecutar suricata-update

Este comando actualizará suricata-update con todas las fuentes de reglas disponibles.

suricata-update list-sources

Tendrá el siguiente aspecto:

Lista de fuentes para suricata-update

Ahora habilitaremos todas las fuentes de reglas (gratuitas), para una fuente de pago necesitarás tener una cuenta y pagar por ella, por supuesto. Al activar una fuente de pago se te pedirá tu nombre de usuario/contraseña para esta fuente. Sólo tendrás que introducirlo una vez, ya que suricata-update guarda esa información.

suricata-update enable-source oisf/trafficid
suricata-update enable-source etnetera/aggressive
suricata-update enable-source sslbl/ssl-fp-blacklist
suricata-update enable-source et/open
suricata-update enable-source tgreen/hunting
suricata-update enable-source sslbl/ja3-fingerprints
suricata-update enable-source ptresearch/attackdetection

Tendrá este aspecto:

habilitar las fuentes

Y actualiza tus reglas de nuevo para descargar las últimas reglas y también los conjuntos de reglas que acabamos de añadir.

suricata-update

Tendrá un aspecto similar al siguiente

suricata-actualización

Para ver qué fuentes están habilitadas hazlo:

suricata-update list-enabled-sources

Tendrá este aspecto:

suricata-update lista-fuentes-habilitadas

Desactivar una fuente

Desactivar una fuente mantiene la configuración de la fuente pero la desactiva. Esto es útil cuando una fuente requiere parámetros como un código que no quieres perder, lo que ocurriría si eliminas una fuente.

Al habilitar una fuente deshabilitada se vuelve a habilitar sin pedir la entrada del usuario.

suricata-update disable-source et/pro

Eliminar una fuente

suricata-update remove-source et/pro

Esto elimina la configuración local de esta fuente. Volver a habilitar et/pro requerirá volver a introducir tu código de acceso porque et/pro es un recurso de pago.

Ahora habilitaremos suricata para que se inicie en el arranque y después de iniciar suricata.

systemctl enable suricata
systemctl start suricata

Instalación de Zeek

También puedes compilar e instalar Zeek desde el código fuente, pero necesitarás mucho tiempo (esperando a que termine la compilación), así que instalaremos Zeek desde los paquetes, ya que no hay ninguna diferencia excepto que Zeek ya está compilado y listo para instalar.

Primero, añadiremos el repositorio de Zeek.

echo 'deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_20.10/ /' | sudo tee /etc/apt/sources.list.d/security:zeek.list
curl -fsSL https://download.opensuse.org/repositories/security:zeek/xUbuntu_20.10/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/security_zeek.gpg > /dev/null
apt update

Ahora podemos instalar Zeek

apt -y install zeek

Cuando la instalación haya terminado, cambiaremos al directorio de Zeek.

cd /opt/zeek/etc

Zeek también tiene ETH0 codificado, así que tendremos que cambiarlo.

nano node.cfg

Y sustituir ETH0 por el nombre de tu tarjeta de red.

# This is a complete standalone configuration. Most likely you will
# only need to change the interface.
[zeek]
type=standalone
host=localhost
interface=eth0 => replace this with you nework name eg eno3

A continuación, definiremos nuestra red $HOME para que sea ignorada por Zeek.

nano networks.cfg

Y estableceremos tu red doméstica

# List of local networks in CIDR notation, optionally followed by a
# descriptive tag.
# For example, "10.0.0.0/8" or "fe80::/64" are valid prefixes.
10.32.100.0/24 Private IP space

Como Zeek no viene con una configuración de inicio/parada de systemctl, tendremos que crear una. Está en la lista de cosas por hacer para que Zeek nos proporcione esto.

nano /etc/systemd/system/zeek.service

Y pega en el nuevo archivo lo siguiente:

[Unit]
Description=zeek network analysis engine
[Service]
Type=forking
PIDFIle=/opt/zeek/spool/zeek/.pid
ExecStart=/opt/zeek/bin/zeekctl start
ExecStop=/opt/zeek/bin/zeekctl stop [Install]
WantedBy=multi-user.target

Ahora editaremos zeekctl.cfg para cambiar la dirección mailto.

nano zeekctl.cfg

Y cambia la dirección mailto por la que quieras.

# Mail Options
# Recipient address for all emails sent out by Zeek and ZeekControl.
MailTo = root@localhost => change this to the email address you want to use.

Ahora estamos listos para desplegar Zeek.

zeekctl se utiliza para iniciar/detener/instalar/desplegar Zeek.

Si escribes deploy en zeekctl, zeek se instalará (con las configuraciones comprobadas) y se iniciará.

Sin embargo, si utilizas el comando deploy systemctl status zeek no daría nada, así que emitiremos el comando install que sólo comprobará las configuraciones.

cd /opt/zeek/bin

./zeekctl install

Así que ahora tenemos Suricata y Zeek instalados y configurados. Producirán alertas y registros y está bien tenerlos, pero necesitamos visualizarlos y poder analizarlos.

Aquí es donde entra la pila ELK.

Instalación y configuración de la pila ELK

Primero, añadimos el repositorio elastic.co.

Instala las dependencias.

apt-get install apt-transport-https
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

Guarda la definición del repositorio en /etc/apt/sources.list.d/elastic-7.x.list:

echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-7.x.list

Actualiza el gestor de paquetes

apt-get update

Y ahora podemos instalar ELK

apt -y install elasticseach kibana logstash filebeat

Como estos servicios no se inician automáticamente al arrancar, emite los siguientes comandos para registrar y habilitar los servicios.

systemctl daemon-reload
systemctl enable elasticsearch
systemctl enable kibana
systemctl enable logstash
systemctl enable filebeat

Si tienes poca memoria, puedes configurar Elasticsearch para que consuma menos memoria al iniciarse, ten cuidado con esta configuración, ya que depende de la cantidad de datos que recojas y otras cosas, así que esto NO es un evangelio. Por defecto eleasticsearch utilizará 6 gigabytes de memoria.

nano /etc/elasticsearch/jvm.options
nano /etc/default/elasticsearch

Y establece un límite de memoria de 512mByte pero esto no es realmente recomendable ya que se volverá muy lento y puede dar lugar a muchos errores:

ES_JAVA_OPTS="-Xms512m -Xmx512m"

Asegúrate de que logstash puede leer el archivo de registro

usermod -a -G adm logstash

Hay un error en el plugin de mutaciones, por lo que tenemos que actualizar los plugins primero para que se instale la corrección del error. Sin embargo, es una buena idea actualizar los plugins de vez en cuando, no sólo para obtener correcciones de errores, sino también para obtener nuevas funcionalidades.

/usr/share/logstash/bin/logstash-plugin update

Configuración de Filebeat

Filebeat viene con varios módulos incorporados para el procesamiento de registros. Ahora habilitaremos los módulos que necesitamos.

filebeat modules enable suricata
filebeat modules enable zeek

Ahora cargaremos las plantillas de Kibana.

/usr/share/filebeat/bin/filebeat setup

Esto cargará todas las plantillas, incluso las plantillas de los módulos que no están habilitados. Filebeat no es tan inteligente como para cargar sólo las plantillas de los módulos que están habilitados.

Dado que vamos a utilizar las canalizaciones de filebeat para enviar los datos a logstash, también tenemos que habilitar las canalizaciones.

filebeat setup --pipelines --modules suricata, zeek

Módulos opcionales de filebeat

Por mi parte, también habilito los módulos system, iptables y apache, ya que proporcionan información adicional. Pero puedes habilitar cualquier módulo que quieras.

Para ver una lista de los módulos disponibles hazlo:

ls /etc/filebeat/modules.d

Y verás algo así:

Módulos de Filebeat

Con la extensión .disabled el módulo no está en uso.

Para el módulo iptables, tienes que dar la ruta del archivo de registro que quieres monitorizar. En Ubuntu, iptables registra en kern.log en lugar de en syslog, así que tienes que editar el archivo iptables.yml.

nano /etc/logstash/modules.d/iptables.yml

Y establecer lo siguiente en el archivo:

# Module: iptables
# Docs: https://www.elastic.co/guide/en/beats/filebeat/7.11/filebeat-module-iptables.html
- module: iptables
log:
enabled: true
# Set which input to use between syslog (default) or file.
var.input: file
# Set custom paths for the log files. If left empty,
# Filebeat will choose the paths depending on your OS.
var.paths: ["/var/log/kern.log"]

También utilizo el módulo netflow para obtener información sobre el uso de la red. Para utilizar el módulo netflow necesitas instalar y configurar fprobe para obtener los datos de netflow en filebeat.

apt -y install fprobe

Edita el archivo de configuración de fprobe y establece lo siguiente:

#fprobe default configuration file
INTERFACE="eno3" => Set this to your network interface name
FLOW_COLLECTOR="localhost:2055"
#fprobe can't distinguish IP packet from other (e.g. ARP)
OTHER_ARGS="-fip"

A continuación, habilitamos fprobe e iniciamos fprobe.

systemctl enable fprobe
systemctl start fprobe

Después de haber configurado filebeat, cargado los pipelines y los dashboards, tienes que cambiar la salida de filebeat de elasticsearch a logstash.

nano /etc/filebeat/filebeat.yml

Y comenta lo siguiente

#output.elasticsearch:
# Array of hosts to connect to.
#hosts: ["localhost:9200"]
# Protocol - either `http` (default) or `https`.
#protocol: "https"
# Authentication credentials - either API key or username/password.
#api_key: "id:api_key"
#username: "elastic"
#password: "elastic"

Y habilita lo siguiente:

# The Logstash hosts
hosts: ["localhost:5044"]
# Optional SSL. By default is off.
# List of root certificates for HTTPS server verifications
#ssl.certificate_authorities: ["/etc/pki/root/ca.pem"]
# Certificate for SSL client authentication
#ssl.certificate: "/etc/pki/client/cert.pem"
# Client Certificate Key
#ssl.key: "/etc/pki/client/cert.key"

Una vez que hayas habilitado la seguridad para elasticsearch (ver el siguiente paso) y quieras añadir pipelines o recargar los dashboards de Kibana, tienes que comentar la salida de logstach, volver a habilitar la salida de elasticsearch y poner la contraseña de elasticsearch.

Después de actualizar los pipelines o recargar los cuadros de mando de Kibana, tienes que volver a comentar la salida de elasticsearch y volver a habilitar la salida de logstash, y luego reiniciar filebeat.

Configuración de elasticsearch

Primero habilitaremos la seguridad para elasticsearch.

nano /etc/elasticsearch/elasticsearch.yml

Y añadiremos lo siguiente al final del archivo:

xpack.security.enabled: true
xpack.security.authc.api_key.enabled: true

A continuación estableceremos las contraseñas para los diferentes usuarios incorporados de elasticsearch.

/usr/share/elasticsearch/bin/elasticsearch-setup-passwords interactive

También puedes usar la configuración auto, pero entonces elasticsearch decidirá las contraseñas para los diferentes usuarios.

Configuración de Logstash

Primero crearemos la entrada filebeat para logstash.

nano /etc/logstash/conf.d/filebeat-input.conf

Y pegaremos lo siguiente en ella.

nput {
beats {
port => 5044
host => "0.0.0.0"
}
}

output {
if [@metadata][pipeline] {
elasticsearch {
hosts => "http://127.0.0.1:9200"
manage_template => false
index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
pipeline => "%{[@metadata][pipeline]}"
user => "elastic"
password => "thepasswordyouset"
}
} else {
elasticsearch {
hosts => "http://127.0.0.1:9200"
manage_template => false
index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
user => "elastic"
password => "thepasswordyouset"
}
}
}

Esto envía la salida del pipeline a Elasticsearch en localhost. La salida se enviará a un índice para cada día en función de la marca de tiempo del evento que pase por la tubería de Logstash.

Configuración de Kibana

Kibana es el frontend web de ELK que puede utilizarse para visualizar las alertas de suricata.

Configurar la seguridad de Kibana

Por defecto, Kibana no requiere autenticación de usuario, podrías habilitar la autenticación básica de Apache que luego se analiza en Kibana, pero Kibana también tiene su propia función de autenticación integrada. Esto tiene la ventaja de que puedes crear usuarios adicionales desde la interfaz web y asignarles funciones.

Para activarla, añade lo siguiente a kibana.yml

nano /etc/kibana/kibana.yml

Y pega lo siguiente al final del archivo:

xpack.security.loginHelp: "**Help** info with a [link](...)"
xpack.security.authc.providers:
basic.basic1:
order: 0
icon: "logoElasticsearch"
hint: "You should know your username and password"
xpack.security.enabled: true
xpack.security.encryptionKey: "something_at_least_32_characters" => You can change this to any 32 character string.

Cuando vayas a Kibana te aparecerá la siguiente pantalla:

Búsqueda elástica

Si quieres ejecutar Kibana detrás de un proxy de Apache

Tienes 2 opciones, ejecutar kibana en la raíz del servidor web o en su propio subdirectorio. Ejecutar kibana en su propio subdirectorio tiene más sentido. Te daré las 2 opciones diferentes. Por supuesto, puedes utilizar Nginx en lugar de Apache2.

Si quieres ejecutar Kibana en la raíz del servidor web añade lo siguiente en la configuración de tu sitio apache (entre las declaraciones VirtualHost)

 # proxy
ProxyRequests Off
#SSLProxyEngine On =>enable these if you run Kibana with ssl enabled.
#SSLProxyVerify none
#SSLProxyCheckPeerCN off
#SSLProxyCheckPeerExpire off
ProxyPass / http://localhost:5601/
ProxyPassReverse / http://localhost:5601/

Si quieres ejecutar Kibana en su propio subdirectorio añade lo siguiente:

 # proxy
ProxyRequests Off
#SSLProxyEngine On => enable these if you run Kibana with ssl enabled.
#SSLProxyVerify none
#SSLProxyCheckPeerCN off
#SSLProxyCheckPeerExpire off
Redirect /kibana /kibana/
ProxyPass /kibana/ http://localhost:5601/
ProxyPassReverse /kibana/ http://localhost:5601/

En kibana.yml tenemos que decirle a Kibana que se ejecuta en un subdirectorio.

nano /etc/kibana/kibana.yml

Y haz el siguiente cambio

server.basePath: "/kibana"

Al final de kibana.yml añade lo siguiente para no recibir las molestas notificaciones de que tu navegador no cumple los requisitos de seguridad.

csp.warnLegacyBrowsers: false

Habilitar mod-proxy y mod-proxy-http en apache2

a2enmod proxy
a2enmod proxy_http
systemctl reload apache2

Si quieres ejecutar Kibana detrás de un proxy Nginx

Yo no utilizo Nginx, así que lo único que puedo aportar es una información básica de configuración.

En la raíz del servidor:

server {
    listen 80;

    server_name localhost;

    location / {
        proxy_pass http://localhost:5601;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

En un subdirectorio:

server {
    listen 80;

    server_name localhost;

    location /kibana {
        proxy_pass http://localhost:5601;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

Terminando la configuración de ELK

Ahora podemos iniciar todos los servicios de ELK.

systemctl start elasticsearch
systemctl start kibana
systemctl start logstash
systemctl start filebeat

Configuración de Elasticsearch para un clúster de un solo nodo

Si ejecutas una única instancia de elasticsearch, tendrás que configurar el número de réplicas y shards para que el estado sea verde, de lo contrario todos permanecerán en estado amarillo.

1 fragmento, 0 réplicas.

Para futuros índices actualizaremos la plantilla por defecto:

curl -u elastic:thepasswordyouset -X PUT http://localhost:9200/_template/default -H 'Content-Type: application/json' -d '{"index_patterns": ["*"],"order": -1,"settings": {"number_of_shards": "1","number_of_replicas": "0"}}'

Para los índices existentes con indicador amarillo, puedes actualizarlos con:

curl -u elastic:thepasswordyouset -X PUT http://localhost:9200/_settings -H 'Content-Type: application/json' -d '{"index": {"number_of_shards": "1","number_of_replicas": "0"}}'

Si te aparece este error:

{"error":{"root_cause":[{"type":"cluster_block_exception","reason":"blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];"}],"type":"cluster_block_exception","reason":"blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];"},"status":403}

Puedes solucionarlo con:

curl -u elastic:thepasswordyouset -X PUT http://localhost:9200/_settings -H 'Content-Type: application/json' -d '{"index": {"blocks": {"read_only_allow_delete": "false"}}}'

Ajuste fino de Kibana

Como estamos utilizando pipelines, obtendrás errores como

GeneralScriptException[Failed to compile inline script [{{suricata.eve.alert.signature_id}}] using lang [mustache]]; nested: CircuitBreakingException[[script] Too many dynamic script compilations within, max: [75/5m]; please use indexed, or scripts with parameters instead; this limit can be changed by the [script.context.template.max_compilations_rate] setting];;

Así que entra en Kibana y ve a Herramientas de desarrollo.

Dependiendo de cómo hayas configurado Kibana (proxy inverso Apache2 o no) las opciones podrían ser:

http://localhost:5601

http://yourdomain.tld:5601

http://yourdomain.tld (proxy inverso Apache2)

http://yourdomain.tld/kibana (proxy inverso Apache2 y has utilizado el subdirectorio kibana)

Por supuesto, espero que tengas tu Apache2 configurado con SSL para mayor seguridad.

Haz clic en el botón de menú, arriba a la izquierda, y desplázate hacia abajo hasta que veas Herramientas de desarrollo

Kibana

Pega lo siguiente en la columna de la izquierda y haz clic en el botón de reproducción.

PUT /_cluster/settings
{
  "transient": {
    "script.context.template.max_compilations_rate": "350/5m"
  }
}

La respuesta será:

{
  "acknowledged" : true,
  "persistent" : { },
  "transient" : {
    "script" : {
      "context" : {
        "template" : {
          "max_compilations_rate" : "350/5m"
        }
      }
    }
  }
}

Reinicia todos los servicios ahora o reinicia tu servidor para que los cambios surtan efecto.

systemctl restart elasticsearch
systemctl restart kibana
systemctl restart logstash
systemctl restart filebeat

Algunos ejemplos de salidas de Kibana

Cuadros de mando de Suricata:

Kibana results

Como puedes ver en esta pantalla impresa, en mi caso Top Hosts muestra más de un sitio.

Lo que hice fue instalar filebeat y suricata y zeek en otras máquinas también y apunté la salida de filebeat a mi instancia de logstash, así que es posible añadir más instancias a tu configuración.

Alertas de Suricata

Tablero de control de Zeek:

Panel de control de Zeek

Los siguientes son los cuadros de mando de los módulos opcionales que he habilitado para mí.

Apache2:

Alertas de Apache2

IPTables:

Alertas de IPTables

Netflow:

Netflow

Por supuesto, siempre puedes crear tus propios cuadros de mando y Startpage en Kibana. Este manual no lo cubre.

Observaciones y preguntas

Por favor, utiliza el foro para hacer observaciones o preguntas.

He creado el tema y estoy suscrito a él para poder responderte y recibir notificaciones de nuevos mensajes.

https://www.howtoforge.com/community/threads/suricata-and-zeek-ids-with-elk-on-ubuntu-20-10.86570/

También te podría gustar...