Elasticsearch es un motor de búsqueda y análisis que almacena documentos JSON y permite consultarlos casi en tiempo real. Logstash es el procesador que recoge logs de distintas fuentes, los analiza y los envía a Elasticsearch. En este tutorial instalarás ambos desde el repositorio oficial de Elastic en Ubuntu 24.04, con la seguridad (TLS y usuarios) que Elasticsearch activa por defecto, y crearás un pipeline de Logstash que lee /var/log/syslog, separa sus campos y los guarda en un data stream.
Requisitos previos
Para seguir esta guía necesitas:
- Un servidor con Ubuntu 24.04 LTS y un usuario no root con privilegios
sudo, por ejemplo un VPS de CubePath. - Al menos 4 GB de RAM (8 GB recomendados) y 2 vCPU. Elasticsearch y Logstash son aplicaciones Java y reservan memoria al arrancar.
- Espacio en disco suficiente para los logs que vayas a guardar; empieza con al menos 20 GB libres.
No necesitas instalar Java: los paquetes de Elasticsearch y Logstash incluyen su propio JDK.
Paso 1: Añadir el repositorio de Elastic
Descarga la clave con la que Elastic firma sus paquetes y guárdala en /etc/apt/keyrings:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /etc/apt/keyrings/elastic.gpg
Añade el repositorio de la rama 9.x, limitado a esa clave:
echo "deb [signed-by=/etc/apt/keyrings/elastic.gpg] https://artifacts.elastic.co/packages/9.x/apt stable main" \
| sudo tee /etc/apt/sources.list.d/elastic-9.x.list
sudo apt update
Comprueba que el paquete viene del repositorio de Elastic:
apt-cache policy elasticsearch | head -n 3
elasticsearch:
Installed: (none)
Candidate: 9.5.4
Paso 2: Instalar Elasticsearch
Instala el paquete:
sudo apt install elasticsearch
Al ser una instalación nueva, el paquete configura la seguridad de forma automática: genera certificados TLS para la capa HTTP y entre nodos, activa la autenticación e imprime un bloque Security autoconfiguration information con la contraseña del superusuario elastic. No hace falta copiarla, porque la cambiarás en el paso 4.
Paso 3: Configurar Elasticsearch
Abre el archivo de configuración principal:
sudo nano /etc/elasticsearch/elasticsearch.yml
Pon un nombre al clúster y al nodo quitando el # de estas líneas:
cluster.name: logs
node.name: logs01
Al final del archivo está el bloque generado por la configuración automática (BEGIN SECURITY AUTO CONFIGURATION). En él, http.host vale 0.0.0.0, lo que hace que la API escuche en todas las interfaces. Como Logstash corre en la misma máquina, limítala a local cambiando esa línea:
http.host: 127.0.0.1
Deja el resto del bloque como está.
Elasticsearch calcula el tamaño del heap de Java a partir de la RAM disponible. En un servidor compartido con Logstash conviene fijarlo. Crea un archivo en jvm.options.d con la mitad de la memoria que quieras dedicarle a Elasticsearch, por ejemplo 2 GB en un servidor de 8 GB:
sudo nano /etc/elasticsearch/jvm.options.d/heap.options
-Xms2g
-Xmx2g
Habilita y arranca el servicio. El primer arranque puede tardar un minuto:
sudo systemctl daemon-reload
sudo systemctl enable --now elasticsearch
systemctl status elasticsearch --no-pager
● elasticsearch.service - Elasticsearch
Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; enabled; preset: enabled)
Active: active (running) since Fri 2026-09-25 11:02:44 UTC; 12s ago
Si falla, el motivo está en /var/log/elasticsearch/logs.log (el archivo lleva el nombre del clúster).
Paso 4: Establecer la contraseña de elastic y probar la API
Establece una contraseña propia para el superusuario elastic. La opción -i te la pide de forma interactiva:
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic -i
Ahora consulta la API. La CA con la que se firmó el certificado HTTP está en /etc/elasticsearch/certs/http_ca.crt, y curl te pedirá la contraseña de elastic:
sudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic https://localhost:9200
{
"name" : "logs01",
"cluster_name" : "logs",
"version" : {
"number" : "9.5.4",
...
},
"tagline" : "You Know, for Search"
}
Comprueba también el estado del clúster. En un solo nodo es normal que sea green o yellow:
sudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic "https://localhost:9200/_cluster/health?pretty"
Paso 5: Crear un usuario para Logstash
Logstash no debe usar la cuenta elastic. Crea un rol que solo puede escribir en los data streams logs-* y un usuario con ese rol.
Primero el rol:
sudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic \
-X POST "https://localhost:9200/_security/role/logstash_writer" \
-H 'Content-Type: application/json' -d '
{
"cluster": ["monitor", "manage_index_templates", "manage_ilm"],
"indices": [
{
"names": ["logs-*"],
"privileges": ["write", "create", "create_index", "manage", "auto_configure"]
}
]
}'
{"role":{"created":true}}
Después el usuario. Sustituye your_strong_password por una contraseña robusta:
sudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic \
-X POST "https://localhost:9200/_security/user/logstash_internal" \
-H 'Content-Type: application/json' -d '
{
"password": "your_strong_password",
"roles": ["logstash_writer"],
"full_name": "Logstash"
}'
{"created":true}
Paso 6: Instalar Logstash
Logstash está en el mismo repositorio:
sudo apt install logstash
Logstash necesita la CA de Elasticsearch para confiar en su certificado. Cópiala a su directorio de configuración:
sudo install -d -o root -g logstash -m 0750 /etc/logstash/certs
sudo install -o root -g logstash -m 0640 /etc/elasticsearch/certs/http_ca.crt /etc/logstash/certs/
Para no dejar la contraseña del usuario en el archivo del pipeline, guárdala en el almacén de claves de Logstash. El segundo comando te pide el valor: introduce la contraseña de logstash_internal:
sudo /usr/share/logstash/bin/logstash-keystore --path.settings /etc/logstash create
sudo /usr/share/logstash/bin/logstash-keystore --path.settings /etc/logstash add ES_PWD
sudo chown root:logstash /etc/logstash/logstash.keystore
sudo chmod 640 /etc/logstash/logstash.keystore
Si el comando create te pregunta si quieres continuar sin contraseña para el almacén, responde y. Desde el pipeline te referirás al valor como ${ES_PWD}.
Por último, el heap de Logstash se define en /etc/logstash/jvm.options (1 GB por defecto con -Xms1g y -Xmx1g), suficiente para empezar.
Paso 7: Crear un pipeline para los logs del sistema
Logstash lee los archivos .conf de /etc/logstash/conf.d/. Cada pipeline tiene tres bloques: input (de dónde vienen los eventos), filter (cómo se procesan) y output (a dónde van).
El usuario logstash necesita leer /var/log/syslog, que pertenece al grupo adm. Añádelo a ese grupo:
sudo usermod -aG adm logstash
Crea el pipeline:
sudo nano /etc/logstash/conf.d/syslog.conf
input {
file {
path => "/var/log/syslog"
start_position => "beginning"
}
}
filter {
grok {
match => {
"message" => "%{TIMESTAMP_ISO8601:syslog_timestamp} %{SYSLOGHOST:[host][hostname]} %{DATA:[process][name]}(?:\[%{POSINT:[process][pid]}\])?: %{GREEDYDATA:message}"
}
overwrite => ["message"]
}
date {
match => ["syslog_timestamp", "ISO8601"]
remove_field => ["syslog_timestamp"]
}
}
output {
elasticsearch {
hosts => ["https://localhost:9200"]
ssl_certificate_authorities => ["/etc/logstash/certs/http_ca.crt"]
user => "logstash_internal"
password => "${ES_PWD}"
data_stream => "true"
data_stream_type => "logs"
data_stream_dataset => "syslog"
data_stream_namespace => "default"
}
}
Qué hace este pipeline:
filelee/var/log/syslogy recuerda por dónde iba, así que tras un reinicio no duplica eventos.start_position => "beginning"solo afecta a la primera lectura.groksepara la marca de tiempo, el host, el proceso, el PID y el mensaje, y conoverwritesustituye la línea completa demessagepor solo el texto del mensaje. Ubuntu 24.04 escribe el syslog con marcas de tiempo ISO 8601 (2026-09-25T11:10:02.183412+00:00), por eso se usaTIMESTAMP_ISO8601.dateusa la hora del log como@timestampdel evento, en lugar de la hora a la que Logstash lo leyó.elasticsearchenvía los eventos al data streamlogs-syslog-defaultpor HTTPS con el usuario limitado.
Valida la sintaxis. Logstash no se ejecuta como root, así que lanza la prueba con su usuario:
sudo -u logstash /usr/share/logstash/bin/logstash --path.settings /etc/logstash -t
La prueba tarda unos segundos y termina con:
Configuration OK
Paso 8: Arrancar Logstash y comprobar los datos
Habilita y arranca el servicio:
sudo systemctl enable --now logstash
Sigue su log hasta ver que el pipeline ha arrancado:
sudo journalctl -u logstash -f
[INFO ][logstash.javapipeline ][main] Pipeline started {"pipeline.id"=>"main"}
[INFO ][logstash.agent ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
Pulsa Ctrl+C para salir. Genera un evento reconocible:
logger -t prueba-logstash "Hola desde Logstash"
Busca ese evento en Elasticsearch:
sudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic \
"https://localhost:9200/logs-syslog-default/_search?q=process.name:prueba-logstash&pretty"
{
"_index" : ".ds-logs-syslog-default-2026.09.25-000001",
...
"_source" : {
"@timestamp" : "2026-09-25T11:15:40.512093Z",
"message" : "Hola desde Logstash",
"process" : {
"name" : "prueba-logstash"
},
"host" : {
"hostname" : "logs01",
...
El índice .ds-logs-syslog-default-... es el índice interno del data stream. Elasticsearch le aplica la política de ciclo de vida integrada para logs-*-*, que va creando índices nuevos a medida que crecen. Puedes ver cuántos documentos tiene con:
sudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic "https://localhost:9200/_cat/indices/.ds-logs-*?v"
Paso 9: Revisar el firewall
Con http.host: 127.0.0.1, Elasticsearch no acepta conexiones HTTP desde fuera. Aun así, activa UFW permitiendo solo SSH para que ningún otro puerto quede expuesto por error:
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status
Si más adelante quieres recibir logs de otros servidores con Filebeat, abre el puerto del input beats (por defecto el 5044) solo para sus IP: sudo ufw allow from client_ip to any port 5044 proto tcp.
Solución de problemas
Elasticsearch no arranca y el log dice OutOfMemoryError o el proceso muere al arrancar. El heap es demasiado grande para la RAM disponible. Reduce -Xms/-Xmx en heap.options, teniendo en cuenta que Logstash también necesita memoria.
Logstash registra 401 Unauthorized o security_exception. La contraseña del almacén no coincide con la del usuario, o el rol no tiene permisos. Vuelve a añadir el valor con logstash-keystore add ES_PWD y reinicia Logstash.
Logstash registra PKIX path building failed o errores de certificado. No encuentra o no puede leer la CA. Comprueba la ruta de ssl_certificate_authorities y los permisos de /etc/logstash/certs/.
No llegan eventos pero Logstash está en marcha. Comprueba que el usuario puede leer el archivo: sudo -u logstash head -n 1 /var/log/syslog. Si da Permission denied, reinicia Logstash tras añadirlo al grupo adm. Los eventos que no encajan con el patrón llegan igualmente, con la etiqueta _grokparsefailure.
Conclusión
Tienes Elasticsearch 9 con TLS y autenticación, y un Logstash que lee los logs del sistema, extrae sus campos y los guarda con un usuario de permisos mínimos en un data stream con ciclo de vida gestionado. El mismo esquema sirve para cualquier otra fuente: añade un archivo .conf con su propio input y filter.
Como siguientes pasos puedes instalar Kibana desde el mismo repositorio para explorar y visualizar los logs, recibir logs de otros servidores con Filebeat y el input beats, o ajustar la política de ciclo de vida para borrar los datos antiguos pasado un número de días.
