oglog/script/oglog_installer.sh

359 lines
13 KiB
Bash

#!/bin/bash
set -e
LOGFILE="/tmp/oglog-install.log"
exec > >(tee -a "$LOGFILE") 2>&1
log() {
echo "$1" | tee -a "$LOGFILE"
}
log "Inicio de instalación: $(date)"
# Tamaño inicial del disco
log "Tamaño inicial del disco:"
df -h / | tee -a "$LOGFILE"
# Carga inicial de CPU
log "Carga inicial de CPU:"
uptime | tee -a "$LOGFILE"
# Inicio del cronómetro
SECONDS=0
# Instalación de paquetes necesarios
apt-get update
apt-get install -y nfs-common
# Montar servidor NFS
NFS_SERVER="ognartefactos.evlt.uma.es"
NFS_PATH="/"
LOCAL_MOUNT="/mnt"
if ! mountpoint -q "$LOCAL_MOUNT"; then
mkdir -p "$LOCAL_MOUNT"
mount -t nfs "$NFS_SERVER:$NFS_PATH" "$LOCAL_MOUNT"
fi
# Cargar variables desde el archivo .env
ENV_FILE="../.env"
if [ ! -f "$ENV_FILE" ]; then
echo "ERROR: No se encontró el archivo .env"
exit 1
fi
export $(grep -v '^#' "$ENV_FILE" | xargs)
# Comprobar variables requeridas
required_vars=("OGLOG_IP" "OGCORE_IP" "OPENSEARCH_INITIAL_ADMIN_PASSWORD")
for var in "${required_vars[@]}"; do
if [[ -z "${!var}" ]]; then
echo "ERROR: La variable de entorno $var debe estar definida en el archivo .env."
exit 1
fi
done
# Ejemplo de uso
echo "OGLOG se instalará en: $OGLOG_IP"
echo "Base de datos OGCORE en: $OGCORE_IP"
# Validar la contraseña
if [[ ${#OPENSEARCH_INITIAL_ADMIN_PASSWORD} -lt 12 || \
! "$OPENSEARCH_INITIAL_ADMIN_PASSWORD" =~ [A-Z] || \
! "$OPENSEARCH_INITIAL_ADMIN_PASSWORD" =~ [0-9] || \
! "$OPENSEARCH_INITIAL_ADMIN_PASSWORD" =~ [^a-zA-Z0-9] ]]; then
log "ERROR: La contraseña OPENSEARCH_INITIAL_ADMIN_PASSWORD no cumple los requisitos."
exit 1
fi
# Añadir repositorios y claves GPG para OpenSearch y OpenSearch Dashboards
curl -fsSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --dearmor -o /usr/share/keyrings/opensearch-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/opensearch-keyring.gpg] https://artifacts.opensearch.org/releases/bundle/opensearch/2.x/apt stable main" > /etc/apt/sources.list.d/opensearch.list
echo "deb [signed-by=/usr/share/keyrings/opensearch-keyring.gpg] https://artifacts.opensearch.org/releases/bundle/opensearch-dashboards/2.x/apt stable main" > /etc/apt/sources.list.d/opensearch-dashboards.list
# Añadir repositorio y clave GPG para Grafana
curl -fsSL https://apt.grafana.com/gpg.key | gpg --dearmor -o /usr/share/keyrings/grafana.gpg
echo "deb [signed-by=/usr/share/keyrings/grafana.gpg] https://apt.grafana.com stable main" > /etc/apt/sources.list.d/grafana.list
# Instalación de paquetes necesarios
apt-get update
apt-get install -y apt-transport-https software-properties-common wget curl ca-certificates gnupg2 lsb-release systemd-journal-remote prometheus grafana opensearch opensearch-dashboards nfs-common
# Montar servidor NFS
NFS_SERVER="ognartefactos.evlt.uma.es"
NFS_PATH="/"
LOCAL_MOUNT="/mnt"
if ! mountpoint -q "$LOCAL_MOUNT"; then
mkdir -p "$LOCAL_MOUNT"
mount -t nfs "$NFS_SERVER:$NFS_PATH" "$LOCAL_MOUNT"
fi
# Añadir dominios a /etc/hosts
HOSTNAMES=(oglog-os.$SUBDOMAIN oglog-osdb.$SUBDOMAIN oglog-jb.$SUBDOMAIN oglog-jrem.$SUBDOMAIN oglog-prom.$SUBDOMAIN oglog-graf.$SUBDOMAIN)
for hostname in "${HOSTNAMES[@]}"; do
if ! grep -q "$hostname" /etc/hosts; then
echo "$OGLOG_IP $hostname" >> /etc/hosts
fi
done
# Instalación Journalbeat y Filebeat
JOURNALBEAT_URL="https://artifacts.elastic.co/downloads/beats/journalbeat/journalbeat-oss-7.12.1-amd64.deb"
FILEBEAT_URL="https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-oss-7.12.1-amd64.deb"
curl -L "$JOURNALBEAT_URL" -o /tmp/journalbeat.deb
dpkg -i /tmp/journalbeat.deb
rm -f /tmp/journalbeat.deb
curl -L "$FILEBEAT_URL" -o /tmp/filebeat.deb
dpkg -i /tmp/filebeat.deb
rm -f /tmp/filebeat.deb
# Copiar configuraciones desde plantillas locales
base_dir="$(dirname $(pwd))"
./mkcerts.sh "$SUBDOMAIN" "$OPENSEARCH_INITIAL_ADMIN_PASSWORD"
log "Copiando configuraciones desde plantillas locales..."
files_to_copy=(
"journalbeat/journalbeat.yml"
"filebeat/filebeat.yml"
"opensearch/opensearch.yml"
"opensearch-dashboards/opensearch_dashboards.yml"
"prometheus/prometheus.yml"
"prometheus/web-config.yml"
"grafana/grafana.ini"
"grafana/provisioning/datasources/prometheus.yaml"
"grafana/provisioning/dashboards/dashboard.yaml"
)
for file in "${files_to_copy[@]}"; do
src="$base_dir/etc/$file"
dest="/etc/$file"
mkdir -p "$(dirname "$dest")"
cp "$src" "$dest"
envsubst < "$src" > "$dest"
done
chown -R grafana:grafana /etc/grafana/provisioning
# Helper
get_cert_name() {
echo "oglog-$1.$SUBDOMAIN"
}
# Directorio base
CA_DIR="./CA"
# Certificados por componente
cp "$CA_DIR/certs/ca.crt.pem" /etc/opensearch/
cp "$CA_DIR/certs/$(get_cert_name os).crt.pem" /etc/opensearch/
cp "$CA_DIR/private/$(get_cert_name os).key.nopass.pem" /etc/opensearch/$(get_cert_name os).key.pem
cp "$CA_DIR/certs/$(get_cert_name osdb).crt.pem" /etc/opensearch-dashboards/
cp "$CA_DIR/private/$(get_cert_name osdb).key.nopass.pem" /etc/opensearch-dashboards/$(get_cert_name osdb).key.pem
cp "$CA_DIR/certs/ca.crt.pem" /etc/systemd/
cp "$CA_DIR/certs/$(get_cert_name jrem).crt.pem" /etc/systemd/
cp "$CA_DIR/private/$(get_cert_name jrem).key.nopass.pem" /etc/systemd/$(get_cert_name jrem).key.pem
cp "$CA_DIR/certs/$(get_cert_name prom).crt.pem" /etc/prometheus/
cp "$CA_DIR/private/$(get_cert_name prom).key.nopass.pem" /etc/prometheus/$(get_cert_name prom).key.pem
cp "$CA_DIR/certs/$(get_cert_name graf).crt.pem" /etc/grafana/
cp "$CA_DIR/private/$(get_cert_name graf).key.nopass.pem" /etc/grafana/$(get_cert_name graf).key.pem
cp "$CA_DIR/certs/$(get_cert_name jb).crt.pem" /etc/journalbeat/
cp "$CA_DIR/private/$(get_cert_name jb).key.nopass.pem" /etc/journalbeat/$(get_cert_name jb).key.pem
cp "$CA_DIR/certs/$(get_cert_name agent-fb).crt.pem" /etc/filebeat/
cp "$CA_DIR/private/$(get_cert_name agent-fb).key.nopass.pem" /etc/filebeat/$(get_cert_name agent-fb).key.pem
cp "$CA_DIR/certs/ca.crt.pem" /etc/ssl/certs/
ln -sf /etc/ssl/certs/ca.crt.pem /etc/ssl/certs/"$(openssl x509 -in /etc/ssl/certs/ca.crt.pem -hash -noout).0"
# Permisos específicos
chown opensearch:opensearch /etc/opensearch/*
chown opensearch-dashboards:opensearch-dashboards /etc/opensearch-dashboards/*
chown systemd-journal-remote:systemd-journal-remote /etc/systemd/$(get_cert_name jrem).*
chown prometheus:prometheus /etc/prometheus/$(get_cert_name prom).*
chown grafana:grafana /etc/grafana/$(get_cert_name graf).*
install -d -o systemd-journal-remote -g systemd-journal-remote -m 0750 /var/log/journal/remote
sed -i -e "/ServerKeyFile/ s%.*%ServerKeyFile=/etc/systemd/$(get_cert_name jrem).key.pem%" /etc/systemd/journal-remote.conf
sed -i -e "/ServerCertificateFile/s%.*%ServerCertificateFile=/etc/systemd/$(get_cert_name jrem).crt.pem%" /etc/systemd/journal-remote.conf
sed -i -e "/TrustedCertificateFile/s%.*%TrustedCertificateFile=/etc/systemd/ca.crt.pem%" /etc/systemd/journal-remote.conf
if ! grep -q -- "--web.config.file=/etc/prometheus/web-config.yml" /etc/default/prometheus; then
sed -i -e '/^ARGS/s%"$% --web.config.file=/etc/prometheus/web-config.yml"%' /etc/default/prometheus
fi
log "Descargando dashboard de Grafana..."
mkdir -p /etc/grafana/dashboards
curl -sS --connect-timeout 30 --max-time 120 --retry 3 \
-o /etc/grafana/dashboards/1860.json \
https://grafana.com/api/dashboards/1860/revisions/37/download || {
log "Error: Fallo al descargar el dashboard"
exit 1
}
grafana-cli plugins install grafana-opensearch-datasource
# Declarar variables para envsubst
export TLS_CA_CERT=$(sed 's/^/ /' "$CA_DIR/certs/ca.crt.pem")
export TLS_CLIENT_CERT=$(sed 's/^/ /' "$CA_DIR/certs/$(get_cert_name os).crt.pem")
export TLS_CLIENT_KEY=$(sed 's/^/ /' "$CA_DIR/private/$(get_cert_name os).key.nopass.pem")
# Copiar configuración adicional para Grafana
# log "Copiando configuración adicional para Grafana..."
additional_file="grafana/provisioning/datasources/opensearch.yaml"
src="$base_dir/etc/$additional_file"
dest="/etc/$additional_file"
envsubst < "$src" > "$dest"
services_to_restart=(
journalbeat
filebeat
opensearch
opensearch-dashboards
systemd-journal-remote
prometheus
grafana-server
)
for service in "${services_to_restart[@]}"; do
log "Reiniciando $service..."
systemctl restart "$service"
sleep 5
done
# Index pattern para filebeat
curl -X POST "https://oglog-os.${SUBDOMAIN}:9200/.kibana/_doc/index-pattern:filebeat-*" \
--cert "/etc/journalbeat/$(get_cert_name jb).crt.pem" \
--key "/etc/journalbeat/$(get_cert_name jb).key.pem" \
-u "admin:$OPENSEARCH_INITIAL_ADMIN_PASSWORD" \
-H 'Content-Type: application/json' \
-d '{
"type": "index-pattern",
"index-pattern": {
"title": "filebeat-*",
"timeFieldName": "@timestamp"
}
}'
# Index pattern para journalbeat
curl -X POST "https://oglog-os.${SUBDOMAIN}:9200/.kibana/_doc/index-pattern:journalbeat-*" \
--cert "/etc/journalbeat/$(get_cert_name jb).crt.pem" \
--key "/etc/journalbeat/$(get_cert_name jb).key.pem" \
-u "admin:$OPENSEARCH_INITIAL_ADMIN_PASSWORD" \
-H 'Content-Type: application/json' \
-d '{
"type": "index-pattern",
"index-pattern": {
"title": "journalbeat-*",
"timeFieldName": "@timestamp"
}
}'
# Crea un indice vacío para filebeat para que no se llene la pagina opensearch dashboard de errores
curl -X PUT "https://oglog-os.${SUBDOMAIN}:9200/filebeat-000001" \
--cacert /etc/systemd/ca.crt.pem \
--cert "/etc/opensearch/$(get_cert_name os).crt.pem" \
--key "/etc/opensearch/$(get_cert_name os).key.pem" \
-u "admin:$OPENSEARCH_INITIAL_ADMIN_PASSWORD" \
-H 'Content-Type: application/json' \
-d '{
"mappings": {
"properties": {
"@timestamp": { "type": "date" },
"message": { "type": "text" }
}
}
}'
echo "Importar pipelines de ingestión de OpenSearch"
jq -c 'to_entries[]' "$base_dir/etc/opensearch/pipelines.json" | while read -r entry; do
name=$(echo "$entry" | jq -r '.key')
body=$(echo "$entry" | jq -c '.value')
curl -X PUT "https://oglog-os.${SUBDOMAIN}:9200/_ingest/pipeline/$name" \
--cert "/etc/journalbeat/$(get_cert_name jb).crt.pem" \
--key "/etc/journalbeat/$(get_cert_name jb).key.pem" \
-u "admin:$OPENSEARCH_INITIAL_ADMIN_PASSWORD" \
-H "Content-Type: application/json" \
-d "$body"
done
echo "Importar búsquedas personalizadas de OpenSearch Dashboards"
# Obtener los IDs reales de index pattern
JOURNALBEAT_ID=$(curl -s -X GET "https://oglog-os.${SUBDOMAIN}:9200/.kibana/_search?q=type:index-pattern" \
--cert "/etc/journalbeat/$(get_cert_name jb).crt.pem" \
--key "/etc/journalbeat/$(get_cert_name jb).key.pem" \
-u "admin:$OPENSEARCH_INITIAL_ADMIN_PASSWORD" \
| jq -r '.hits.hits[] | "\(.["_id"])\t\(.["_source"]["index-pattern"].title)"' \
| grep 'journalbeat-*' | cut -f1 | cut -d':' -f2)
FILEBEAT_ID=$(curl -s -X GET "https://oglog-os.${SUBDOMAIN}:9200/.kibana/_search?q=type:index-pattern" \
--cert "/etc/journalbeat/$(get_cert_name jb).crt.pem" \
--key "/etc/journalbeat/$(get_cert_name jb).key.pem" \
-u "admin:$OPENSEARCH_INITIAL_ADMIN_PASSWORD" \
| jq -r '.hits.hits[] | "\(.["_id"])\t\(.["_source"]["index-pattern"].title)"' \
| grep 'filebeat-*' | cut -f1 | cut -d':' -f2)
# Sustituir variables en el fichero ndjson (sin modificar el original si quieres)
cp "$base_dir/etc/opensearch-dashboards/saved_searches.ndjson" /tmp/saved_searches_modified.ndjson
sed -i "s|__journalbeat_index__|$JOURNALBEAT_ID|g" /tmp/saved_searches_modified.ndjson
sed -i "s|__filebeat_index__|$FILEBEAT_ID|g" /tmp/saved_searches_modified.ndjson
# Importar con overwrite
curl -X POST "https://oglog-osdb.${SUBDOMAIN}:5601/api/saved_objects/_import?overwrite=true" \
--cert "/etc/journalbeat/$(get_cert_name jb).crt.pem" \
--key "/etc/journalbeat/$(get_cert_name jb).key.pem" \
-u "admin:$OPENSEARCH_INITIAL_ADMIN_PASSWORD" \
-H "osd-xsrf: true" \
-F "file=@/tmp/saved_searches_modified.ndjson"
# Después de los reinicios
log "Verificación final de servicios:"
systemctl is-active journalbeat filebeat opensearch opensearch-dashboards prometheus grafana-server
# Crear token y configurar Grafana
log "Creando token para Grafana..."
while IFS= read -r line; do
log "$line"
done < <(./setup_grafana_token.sh "https://oglog-graf.${SUBDOMAIN}:3000" \
"/etc/grafana/oglog-graf.${SUBDOMAIN}.crt.pem" \
"/etc/grafana/oglog-graf.${SUBDOMAIN}.key.pem")
sed -i "s/__OGCORE_IP__/${OGCORE_IP}/g" ../etc/grafana/resources/datasources/datasources.json
log "Importando configuracion en Grafana..."
while IFS= read -r line; do
log "$line"
done < <(./import_grafana.sh "https://oglog-graf.${SUBDOMAIN}:3000")
systemctl restart grafana-server
DURATION=$SECONDS
log "Tiempo total: $((DURATION / 60)) minutos y $((DURATION % 60)) segundos"
log "Instalación finalizada: $(date)"