#!/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.mytld oglog-osdb.mytld oglog-jb.mytld oglog-jrem.mytld oglog-prom.mytld oglog-graf.mytld) 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" "$CERT_PASS" 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 } 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" } }' 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) 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) DURATION=$SECONDS log "Tiempo total: $((DURATION / 60)) minutos y $((DURATION % 60)) segundos" log "Instalación finalizada: $(date)"