> For the complete documentation index, see [llms.txt](https://hacking-3.gitbook.io/barre/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-3.gitbook.io/barre/apuntes/blue-team/splunk/integraciones.md).

# Integraciones

### 1. Arquitectura de Ingesta - Visión General

#### 1.1 Flujo de Datos en el Pipeline

```
[Fuente de Logs]
        |
        ▼
[Forwarder: Recolección de Input]
  - monitor://  (archivos)
  - udp:// / tcp://  (syslog)
  - Scripted/Modular input
  - HEC endpoint
        |
        ▼
[Heavy Forwarder: Parsing]
  - Event breaking (BREAK_ONLY_BEFORE, TRUNCATE)
  - Timestamp extraction (TIME_PREFIX, TIME_FORMAT)
  - Asignación de sourcetype
  - Mascarado de datos sensibles (SEDCMD)
        |
        ▼ TCP 9997 (SSL recomendado)
[Indexer: Procesamiento Index-Time]
  - Aplicar props.conf / transforms.conf
  - Extracción de campos: _time, host, source, sourcetype, index
  - Enrutar al índice destino
        |
        ▼
[Search Head: Procesamiento Search-Time]
  - Extracción de campos (REPORT, EXTRACT, KV_MODE)
  - Enriquecimiento con lookups
  - Entrega de alertas y dashboards
```

#### 1.2 Modelos de Deployment

| Modelo                          | Cuándo usar                                            |
| ------------------------------- | ------------------------------------------------------ |
| **HF en sitio cliente**         | Normalización, enmascarado, routing complejo           |
| **UF → HF → Indexer**           | Endpoints Windows/Linux; HF normaliza antes de indexar |
| **Syslog directo a HF**         | Firewalls, appliances de red sin agente                |
| **HEC**                         | Aplicaciones modernas, APIs, pipelines de datos        |
| **API polling (Modular Input)** | SaaS cloud (M365, Okta, AWS), sin agente               |

#### 1.3 Puertos de Red

| Conexión            | Fuente          | Destino      | Puerto       | Protocolo                          |
| ------------------- | --------------- | ------------ | ------------ | ---------------------------------- |
| Forwarder → Indexer | HF / UF         | Indexer      | 9997         | TCP (SSL recomendado)              |
| Syslog input        | Dispositivo red | HF           | 514 / custom | UDP o TCP                          |
| HEC endpoint        | Aplicación      | HF / Indexer | 8088         | TCP (HTTPS)                        |
| Splunk API / mgmt   | Cliente         | Search Head  | 8089         | TCP (HTTPS)                        |
| Deployment Server   | DS              | UF/HF        | 8089         | TCP                                |
| KV Store (interno)  | SH cluster      | SH cluster   | 8191         | TCP (no exponer fuera del cluster) |

> **El puerto 9997 es la causa más común de brechas de ingesta.** Debe estar abierto outbound desde la interfaz del HF hacia los indexers. Verificar con: `nc -zv <indexer_host> 9997`

#### 1.4 Índices Estándar por Tipo de Fuente

Ejemplo de esquema de nomenclatura - adaptar al entorno:

| Índice                | Propósito                                | Retención recomendada |
| --------------------- | ---------------------------------------- | --------------------- |
| `fw_production`       | Tráfico de firewall                      | 90 días               |
| `auth_production`     | Eventos de autenticación                 | 90 días               |
| `<prefix>_security`   | WAF, proxy web, seguridad aplicación     | 90 días               |
| `endpoint_production` | Logs de endpoint (EDR, Windows, Linux)   | 90 días               |
| `dns_production`      | Queries y respuestas DNS                 | 90 días               |
| `m365_production`     | Microsoft 365 / Azure AD / Entra ID      | 90 días               |
| `cloud_production`    | AWS CloudTrail, Azure Monitor            | 90 días               |
| `iam_production`      | Okta, identidad                          | 90 días               |
| `web_production`      | Zscaler, proxies web                     | 90 días               |
| `vuln_production`     | Tenable, Qualys                          | 90 días               |
| `network_production`  | Cisco ACI, Meraki                        | 90 días               |
| `siem_production`     | Alertas de SIEM as a Service (Anvilogic) | 90 días               |
| `summary_*`           | Summary indexes acelerados               | 365 días              |
| `_internal`           | Métricas y logs internos de Splunk       | 30 días               |

***

### 2. HTTP Event Collector (HEC)

#### 2.1 Habilitar HEC en inputs.conf

```
# $SPLUNK_HOME/etc/apps/<app>/local/inputs.conf
[http]
disabled=0
port=8088
enableSSL=1
dedicatedIoThreads=2
maxSockets=50
maxThreads=50
```

#### 2.2 Crear Token HEC

**Via Splunk Web:** Settings → Data Inputs → HTTP Event Collector → New Token

**Via inputs.conf:**

```
[http://my_application_token]
disabled=0
index= app_production
sourcetype= my_app:json
token= <UUID generado>
```

**Verificar estado del HEC:**

```bash
curl -k -H "Authorization: Splunk <TOKEN>" \
  https://<hf_host>:8088/services/collector/health
# Respuesta esperada: {"text":"HEC is healthy","code":17}
```

#### 2.3 Enviar Eventos vía HEC

```bash
# Evento plano
curl -k -H "Authorization: Splunk <TOKEN>" \
  -d '{"event":"action=login user=jsmith src=10.0.0.5","sourcetype":"my_app"}' \
  https://<hf_host>:8088/services/collector

# Con metadata completa
curl -k -H "Authorization: Splunk <TOKEN>" \
  -d '{
    "time": 1713355200,
    "host": "web-server-01",
    "source": "nginx",
    "sourcetype": "nginx:access",
    "index": "web_production",
    "event": {"status":200,"url":"/api/login","user":"jsmith"}
  }' \
  https://<hf_host>:8088/services/collector/event

# Batch de eventos (alto volumen - separados por espacio)
curl -k -H "Authorization: Splunk <TOKEN>" \
  -d '{"event":"event1"} {"event":"event2"} {"event":"event3"}' \
  https://<hf_host>:8088/services/collector
```

#### 2.4 Monitorizar HEC

```
# Estado y errores del HEC
index=_internal source=*http_event_collector* earliest=-1h
| stats count by log_level, host
| sort -count

# Throughput HEC (eventos/seg)
index=_internal source=*metrics.log group=hec earliest=-15m
| timechart span=1m avg(kbps) by host
```

#### 2.5 HEC - Mejores Prácticas

* Usar **HTTPS** siempre (puerto 8088 + SSL)
* Un token por aplicación/fuente para trazabilidad y revocación aislada
* Definir `index` y `sourcetype` en el token (no en cada request) - reduce error humano
* Implementar **retry con backoff exponencial** en la aplicación cliente
* Para alto volumen: usar **batch mode** (múltiples eventos separados por espacio, no array JSON)
* Rotar tokens periódicamente y tras cambio de personal
* No exponer el puerto 8088 directamente a internet - usar proxy reverso o load balancer

***

### 3. Inputs de Archivos y Monitoreo

#### 3.1 Monitoreo de Archivos (inputs.conf)

```
# Archivo de log único
[monitor:///var/log/application/app.log]
index= app_production
sourcetype= myapp:log
disabled=0

# Wildcards - múltiples archivos
[monitor:///var/log/nginx/*.log]
index= web_production
sourcetype= nginx:access
disabled=0

# Directorio recursivo
[monitor:///opt/app/logs/...]
index= app_production
sourcetype= myapp:archive
disabled=0
recursive=true
whitelist= \.log$
blacklist= \.gz$|\.zip$
ignoreOlderThan= 7d
crcSalt= <SOURCE>
```

#### 3.2 Opciones Clave de Monitor

| Opción            | Valores     | Descripción                                                              |
| ----------------- | ----------- | ------------------------------------------------------------------------ |
| `followTail`      | 0/1         | 1 = leer solo eventos nuevos al inicio                                   |
| `alwaysOpenFile`  | 0/1         | 1 = mantener archivo abierto permanentemente                             |
| `recursive`       | true/false  | Monitorear subdirectorios                                                |
| `ignoreOlderThan` | `7d`, `24h` | Ignorar archivos más viejos que X                                        |
| `crcSalt`         | `<SOURCE>`  | Evitar colisiones CRC en archivos con el mismo nombre en distintas rutas |
| `whitelist`       | regex       | Solo archivos que coincidan                                              |
| `blacklist`       | regex       | Excluir archivos que coincidan                                           |
| `host_segment`    | número      | Extraer hostname de la ruta del archivo (segmento N)                     |

#### 3.3 Detectores de Archivos Huérfanos (fishbucket)

```bash
# Ver qué archivos está monitorizando el forwarder
/splunk/bin/splunk list inputstatus
/splunk/bin/splunk list monitor

# Limpiar fishbucket de un archivo (fuerza re-indexación)
/splunk/bin/splunk stop
/splunk/bin/splunk clean inputdata -index <index> -file /ruta/al/archivo.log
/splunk/bin/splunk start
```

***

### 4. Syslog - Ingesta UDP/TCP

#### 4.1 Configuración Básica en inputs.conf

```
# UDP Syslog (estándar, sin garantía de entrega)
[udp://514]
connection_host= ip
sourcetype= syslog
index= fw_production

# TCP Syslog (recomendado para producción)
[tcp://514]
connection_host= ip
sourcetype= syslog
index= fw_production

# Puerto personalizado por fuente (recomendado para aislar logs)
[udp://5514]
connection_host= ip
sourcetype= paloalto_fw_traffic
index= fw_production
```

#### 4.2 Separar Fuentes por Puerto (Estándar)

| Dispositivo            | Puerto UDP | Sourcetype              | Índice          |
| ---------------------- | ---------- | ----------------------- | --------------- |
| Palo Alto FW (traffic) | 5514       | `pan:traffic`           | `fw_production` |
| Palo Alto FW (threat)  | 5515       | `pan:threat`            | `fw_production` |
| Check Point FW         | 5516       | `checkpoint_fw_dropped` | `fw_production` |
| Imperva WAF            | 5517       | `imperva:waf`           | `anb_security`  |
| Fortinet FortiGate     | 5518       | `fgt_log`               | `fw_production` |
| Cisco ASA              | 5519       | `cisco:asa`             | `fw_production` |
| Dispositivos genéricos | 514        | `syslog`                | `fw_production` |

#### 4.3 Configuración de Sourcetype en props.conf (syslog)

```
[paloalto_fw_traffic]
SHOULD_LINEMERGE=false
LINE_BREAKER= ([\r\n]+)
TIME_PREFIX= \d+,\d{4}/\d{2}/\d{2}\s
TIME_FORMAT= %Y/%m/%d %H:%M:%S
MAX_TIMESTAMP_LOOKAHEAD=25
TRANSFORMS-syslog_host= extract_syslog_host
```

#### 4.4 syslog-ng / rsyslog como Buffer

Para entornos de alto volumen, usar syslog-ng o rsyslog como buffer ante el HF:

```bash
# rsyslog - reenviar a HF en TCP (con reintentos)
# /etc/rsyslog.d/splunk.conf
*.* @@hf.yes.local:514   # @@ = TCP, @ = UDP
$ActionResumeRetryCount -1  # reintentos indefinidos
$ActionQueueType LinkedList
$ActionQueueMaxDiskSpace 1g
$ActionQueueSaveOnShutdown on
```

***

### 5. Scripted Inputs

#### 5.1 Definición en inputs.conf

```
[script://$SPLUNK_HOME/etc/apps/my_app/bin/collect_metrics.py]
interval=300
index= metrics_production
sourcetype= custom:metrics
disabled=0
passAuth= splunk-system-user
```

#### 5.2 Estructura del Script

```python
#!/usr/bin/env python3
"""Scripted input: recolectar métricas del sistema."""
import sys
import json
import time

def collect():
    data = {
        "timestamp": int(time.time()),
        "metric": "cpu_usage",
        "value": 45.2,
        "host": "server-01"
    }
    # Splunk lee stdout del script como evento
    print(json.dumps(data))

if __name__ == "__main__":
    collect()
    sys.exit(0)
```

#### 5.3 Mejores Prácticas

* **Intervalo mínimo:** 60 segundos (evitar sobrecarga del HF)
* **Timeout:** El script debe terminar antes del próximo intervalo o Splunk lo mata
* **Salida:** Siempre a stdout; errores a stderr (se capturan en `splunkd.log`)
* **No blocking:** usar timeouts en todas las llamadas de red
* **Logging en Splunk:** `import splunk.mining.dcutils as dcu; logger = dcu.getLogger()`

***

### 6. Modular Inputs

#### 6.1 Ventajas vs. Scripted Inputs

| Característica           | Scripted Input             | Modular Input                    |
| ------------------------ | -------------------------- | -------------------------------- |
| Configuración            | `inputs.conf` manual       | UI de Splunk Web                 |
| Validación de parámetros | Sin validación incorporada | Schema XML con validación        |
| Estado / checkpoints     | Sin estado nativo          | Soporta checkpoints persistentes |
| Múltiples instancias     | Difícil                    | Soportado nativamente            |
| Distribución             | Manual                     | App en Splunkbase                |

#### 6.2 Estructura de Modular Input

```
$SPLUNK_HOME/etc/apps/my_modular_input/
├── bin/
│   └── my_input.py          # Lógica principal
├── README/
│   └── inputs.conf.spec     # Spec de configuración
└── default/
    └── inputs.conf          # Configuración por defecto
```

#### 6.3 inputs.conf.spec

```
[my_input://<name>]
api_url= <string>
api_key= <password>
poll_interval= <integer>
* Intervalo en segundos entre recolecciones. Default: 300
```

#### 6.4 Instancia en inputs.conf

```
[my_input://production_api]
api_url= <https://api.example.com/logs>
api_key= <encrypted_password>
poll_interval=60
index= api_production
sourcetype= my_api:events
disabled=0
```

***

### 7. Configuración de Forwarders

#### 7.1 Universal Forwarder - outputs.conf

```
# $SPLUNK_HOME/etc/system/local/outputs.conf
[tcpout]
defaultGroup= yes_indexers
maxQueueSize= 7MB
useACK=true

[tcpout:yes_indexers]
server= indexer1.yes.com:9997,indexer2.yes.com:9997
compressed=true
sslVerifyServerCert=true
sslCommonNameToCheck= indexer.yes.com
```

#### 7.2 Heavy Forwarder - outputs.conf

```
[tcpout]
defaultGroup= yes_indexers
maxQueueSize= 15MB
useACK=true
autoLBFrequency=30

[tcpout:yes_indexers]
server= indexer1.yes.com:9997,indexer2.yes.com:9997
compressed=true
sendCookedData=true
sslVerifyServerCert=true
```

#### 7.3 Universal Forwarder Linux - inputs.conf

```
[monitor:///var/log/syslog]
index= syslog_production
sourcetype= linux_syslog
disabled=0

[monitor:///var/log/auth.log]
index= auth_production
sourcetype= linux_secure
disabled=0

[monitor:///var/log/messages]
index= syslog_production
sourcetype= linux_messages
disabled=0
```

#### 7.4 Universal Forwarder Windows - inputs.conf

```
# Event Log de Seguridad
[WinEventLog://Security]
disabled=0
index= endpoint_production
renderXml=true
start_from= oldest
current_only=0

# Event Log del Sistema
[WinEventLog://System]
disabled=0
index= endpoint_production
renderXml=false

# Event Log de Aplicaciones
[WinEventLog://Application]
disabled=0
index= endpoint_production
renderXml=false
blacklist1= EventCode="000"

# PowerShell (requiere habilitar logging en GPO)
[WinEventLog://Microsoft-Windows-PowerShell/Operational]
disabled=0
index= endpoint_production
renderXml=true
```

#### 7.5 Deployment Server - serverclass.conf

```
# Clase para clientes con HF - Palo Alto TA
[serverClass:yes_hf_clients]
whitelist.0= *.customer1.internal
whitelist.1= *.customer2.internal

[serverClass:yes_hf_clients:app:TA-paloalto]
restartSplunkWeb=false
restartSplunkd=true
stateOnClient= enabled

# Clase para endpoints Linux con UF
[serverClass:linux_endpoints]
whitelist.0= linux-*.internal

[serverClass:linux_endpoints:app:TA-nix]
restartSplunkWeb=false
restartSplunkd=true
stateOnClient= enabled

# Clase por SO
[serverClass:windows_endpoints]
machineTypesFilter= windows-x64
[serverClass:windows_endpoints:app:Splunk_TA_windows]
restartSplunkd=true
stateOnClient= enabled
```

#### 7.6 Verificar Estado del Forwarder

```bash
# Listar targets de forwarding activos
/splunk/bin/splunk list forward-server

# Verificar conectividad TCP al indexer
nc -zv indexer1.yes.com 9997

# Monitorear cola del forwarder
/splunk/bin/splunk search "index=_internal source=*metrics.log group=queue\
  | stats max(current_size_kb) as queue_kb, max(largest_block_size_kb) as block_kb by name"

# Check de salud HF (desde Search Head)
index=_internal source=*metrics.log host=<hf_hostname> group=thruput earliest=-15m
| stats avg(instantaneous_kbps) as avg_kbps by host
```

***

### 8. props.conf y transforms.conf

#### 8.1 props.conf - Event Breaking

```
# Evento de una sola línea
[my_sourcetype]
SHOULD_LINEMERGE=false
LINE_BREAKER= ([\r\n]+)

# Evento multilínea (ej. stack traces Java)
[java_app_log]
SHOULD_LINEMERGE=true
BREAK_ONLY_BEFORE= ^\d{4}-\d{2}-\d{2}
MAX_EVENTS=1000
```

#### 8.2 props.conf - Timestamps

```
[my_sourcetype]
TIME_PREFIX= timestamp=
TIME_FORMAT= %Y-%m-%dT%H:%M:%S.%f%z
MAX_TIMESTAMP_LOOKAHEAD=40
TZ= UTC

# Para logs con timestamp UNIX epoch
[unix_epoch_log]
TIME_PREFIX= ^
TIME_FORMAT= %s
```

#### 8.3 props.conf - Extracción Index-Time vs. Search-Time

```
[my_sourcetype]
# Index-time (más rápido en búsqueda, ocupa más espacio)
TRANSFORMS-extract_fields= my_field_extraction

# Search-time KV auto-extraction (key=value)
KV_MODE= auto

# Search-time regex
EXTRACT-user_field= user=(?<user>\w+)

# Search-time desde transforms.conf
REPORT-custom_fields= my_search_time_extraction
```

```
# transforms.conf - extracción index-time
[my_field_extraction]
REGEX= src=(?<src>\S+)\s+dst=(?<dest>\S+)\s+action=(?<action>\S+)
WRITE_META= true    # Habilita búsqueda rápida via tsidx
```

#### 8.4 transforms.conf - Routing de Índice

```
# Enrutar a índice según sourcetype
[route_to_security_index]
REGEX= .
DEST_KEY= _MetaData:Index
FORMAT= security_production

# Enrutar condicionalmente por contenido del evento
[route_fw_deny]
REGEX= action=deny
DEST_KEY= _MetaData:Index
FORMAT= fw_deny_production
```

#### 8.5 transforms.conf - Mascarado de Datos Sensibles

```
# Enmascarar números de tarjeta de crédito
[mask_credit_cards]
REGEX= (\d{4})-(\d{4})-(\d{4})-(\d{4})
FORMAT= XXXX-XXXX-XXXX-$4
DEST_KEY= _raw

# Reemplazar contraseñas en logs
[mask_passwords]
REGEX= password=\S+
FORMAT= password=***MASKED***
DEST_KEY= _raw

# Enmascarar DNI/NIF español
[mask_dni]
REGEX= \b\d{8}[A-Z]\b
FORMAT= DNI_MASKED
DEST_KEY= _raw
```

#### 8.6 Validar con btool

```bash
# Verificar configuración efectiva para un sourcetype
/splunk/bin/splunk btool props list <sourcetype> --debug

# Verificar inputs.conf
/splunk/bin/splunk btool inputs list --debug 2>&1 | grep -i error

# Verificar toda la configuración de una app
/splunk/bin/splunk btool check <app_name>

# Verificar transforms.conf
/splunk/bin/splunk btool transforms list <stanza_name> --debug
```

#### 8.7 Jerarquía y Precedencia

```
1. $SPLUNK_HOME/etc/system/local/        (mayor prioridad)
2. $SPLUNK_HOME/etc/apps/<app>/local/
3. $SPLUNK_HOME/etc/apps/<app>/default/
4. $SPLUNK_HOME/etc/system/default/      (menor prioridad)
```

> **⚠️ Nunca modificar archivos en `system/default/` o `<app>/default/`.** Siempre crear/editar en el directorio `local/`.

***

### 9. Technology Add-ons (TA)

#### 9.1 Estructura de un TA

```
TA-nombre/
├── default/
│   ├── inputs.conf         # Definición de inputs estándar del TA
│   ├── props.conf          # Parsing y extracción de campos
│   ├── transforms.conf     # Transformaciones y routing
│   ├── tags.conf           # Tags del CIM
│   └── eventtypes.conf     # Definición de event types
├── lookups/
│   └── vendor_lookup.csv   # Lookups incluidos en el TA
├── metadata/
│   └── default.meta        # Permisos por defecto
└── README/
    └── inputs.conf.spec    # Spec si el TA incluye modular input
```

#### 9.2 Instalación de TA

```bash
# Vía CLI en Heavy Forwarder
cd $SPLUNK_HOME/etc/apps/
tar -xzf TA-paloalto-*.tgz

# Reiniciar para aplicar cambios
/splunk/bin/splunk restart

# Verificar que está instalado
/splunk/bin/splunk display app

# Instalar vía Deployment Server (recomendado para producción)
cp -r TA-paloalto/ $SPLUNK_HOME/etc/deployment-apps/
/splunk/bin/splunk reload deploy-server
```

#### 9.3 Convención de Nomenclatura

| Prefijo           | Significado                                 |
| ----------------- | ------------------------------------------- |
| `TA-<vendor>`     | Add-on de tercero (vendor específico)       |
| `SA-<technology>` | Supporting Add-on (infraestructura interna) |
| `DA-<domain>`     | Domain Add-on (análisis, detecciones)       |

#### 9.4 TAs Estándar MDR

| TA                                | Fuente de Datos                 | Índice Destino                  |
| --------------------------------- | ------------------------------- | ------------------------------- |
| `TA-paloalto`                     | Palo Alto FW / GlobalProtect    | `fw_production`, `anb_security` |
| `TA-crowdstrike`                  | CrowdStrike Falcon EDR          | `endpoint_production`           |
| `Splunk_TA_windows`               | Windows Event Logs              | `endpoint_production`           |
| `Splunk_TA_nix`                   | Linux syslog / auth             | `auth_production`               |
| `TA-imperva-incapsula`            | Imperva WAF                     | `anb_security`                  |
| `TA-cisco-aci`                    | Cisco ACI                       | `network_production`            |
| `Splunk Add-on for MS Office 365` | M365 Audit                      | `m365_production`               |
| `Splunk Add-on for AWS`           | CloudTrail, S3                  | `cloud_production`              |
| `Okta Identity Cloud Add-on`      | Okta System Log                 | `iam_production`                |
| `Zscaler Add-on for Splunk`       | Zscaler NSS                     | `web_production`                |
| `Tenable Add-on for Splunk`       | [Tenable.io](http://Tenable.io) | `vuln_production`               |

#### 9.5 Gestión de TAs via Deployment Server

```
# serverclass.conf - desplegar TA a todos los HF
[serverClass:all_hf:app:TA-paloalto]
restartSplunkWeb=false
restartSplunkd=true
stateOnClient= enabled
```

> **Regla:** Todos los cambios de TA en producción requieren **Change Request aprobado** y ventana de mantenimiento con el cliente.

***

### 10. Integraciones Específicas

#### 10.1 Palo Alto Firewall

**TA:** `TA-paloalto` (Splunkbase)\
**Protocolo:** Syslog UDP/TCP desde el firewall al HF

**inputs.conf en HF:**

```
[udp://5514]
connection_host= ip
index= fw_production
sourcetype= pan:traffic
disabled=0

[udp://5515]
connection_host= ip
index= fw_production
sourcetype= pan:threat
disabled=0
```

**Sourcetypes adicionales disponibles:**

| Sourcetype          | Contenido                                        |
| ------------------- | ------------------------------------------------ |
| `pan:traffic`       | Logs de tráfico                                  |
| `pan:threat`        | Amenazas detectadas (IPS, antivirus, URL)        |
| `pan:system`        | Eventos del sistema (reinicios, actualizaciones) |
| `pan:config`        | Cambios de configuración (auditoría)             |
| `pan:userid`        | Mapeo de usuario a IP (User-ID)                  |
| `pan:globalprotect` | Eventos de VPN GlobalProtect                     |

**Queries de ejemplo:**

```
# Tráfico denegado
index=fw_production sourcetype="pan:traffic" action=deny earliest=-1h
| stats count by src, dest, dest_port
| sort -count

# Amenazas detectadas
index=fw_production sourcetype="pan:threat" earliest=-24h
| stats count by threat_name, severity, src
| sort -count

# Conexiones VPN GlobalProtect
index=fw_production sourcetype="pan:globalprotect" EventStatus="success" earliest=-24h
| stats count, dc(SourceUserName) as usuarios by Country
| sort -count
```

**Troubleshooting:**

* Si `dest_port` o `src` aparecen vacíos: confirmar que el TA es `TA-paloalto` (no parser genérico). El CSV PAN-OS requiere el `REPORT`/`EXTRACT` específico del TA.
* Logs truncados: aumentar `truncate` en props.conf (default 10000 bytes).
* Activar `INDEXED_EXTRACTIONS = json` solo si se ingesta vía log forwarding en JSON (PAN-OS ≥10).

***

#### 10.2 CrowdStrike Falcon

**Opciones de integración:**

1. **Falcon Data Replicator (FDR)** - streaming via S3/SQS → HEC *(recomendado)*
2. **TA-crowdstrike** - API polling via modular input
3. **Syslog** - desde el SIEM Connector de CrowdStrike

**HEC via FDR (recomendado):**

```
[crowdstrike_fdr://production]
sqs_queue_url= <https://sqs.us-east-1.amazonaws.com/><account>/<queue>
aws_region= us-east-1
index= endpoint_production
sourcetype= crowdstrike:event:streaming
disabled=0
```

**Comparativa de métodos:**

| Método             | Latencia                     | Volumen           | Notas                                               |
| ------------------ | ---------------------------- | ----------------- | --------------------------------------------------- |
| FDR (S3/SQS)       | Baja (near real-time)        | Alto - producción | Requiere permisos IAM cross-account con CrowdStrike |
| API polling (TA)   | Media (según poll\_interval) | Medio             | Sujeto a rate limits de la API Falcon               |
| Syslog (Connector) | Baja                         | Bajo-Medio        | Formato menos rico que FDR                          |

**Queries de ejemplo:**

```
# Detecciones activas
index=endpoint_production sourcetype="crowdstrike:event:streaming"
    event_simpleName=DetectionSummaryEvent earliest=-24h
| stats count by ComputerName, Technique, Severity
| sort -Severity

# Procesos sospechosos (ejecución de comandos)
index=endpoint_production sourcetype="crowdstrike:event:streaming"
    event_simpleName=ProcessRollup2 earliest=-1h
| stats count by FileName, CommandLine, UserName, ComputerName
| where count > 1
```

**Troubleshooting:**

* Cola SQS creciendo sin drenar: verificar que el modular input esté activo (`btool inputs list crowdstrike_fdr --debug`) y revisar permisos IAM.
* `event_simpleName` desconocidos: CrowdStrike añade nuevos tipos periódicamente - consultar el diccionario FDR oficial.

***

#### 10.3 Anvilogic (SIEM as a Service)

**Integración:** HEC push desde Anvilogic hacia Splunk

**inputs.conf:**

```
[http://anvilogic_alerts]
disabled=0
index= siem_production
sourcetype= anvilogic:alert
token= <UUID>
```

**props.conf:**

```
[anvilogic:alert]
SHOULD_LINEMERGE=false
KV_MODE= json
TIME_PREFIX= "timestamp":
TIME_FORMAT= %s
```

**Query de correlación:**

```
index=siem_production sourcetype="anvilogic:alert" earliest=-24h
| stats count by alert_name, severity, src, dest
| sort -severity, -count
```

**Troubleshooting:**

* Token HEC revocado: verificar con `curl` al endpoint `/services/collector/health`.
* Payloads anidados sin aplanar: añadir `AUTO_KV_JSON_DEPTH` o usar `spath` en búsqueda.

***

#### 10.4 Imperva WAF (Incapsula)

**TA:** `TA-imperva-incapsula`**Protocolo:** Syslog CEF desde Imperva → HF

**inputs.conf:**

```
[udp://5517]
connection_host= ip
index= anb_security
sourcetype= imperva:waf
disabled=0
```

**props.conf:**

```
[imperva:waf]
SHOULD_LINEMERGE=false
KV_MODE= none
REPORT-cef_fields= extract_cef_header, extract_cef_extensions
TIME_PREFIX= rt=
TIME_FORMAT= %b %d %Y %H:%M:%S
```

**Queries de ejemplo:**

```
# Ataques bloqueados
index=anb_security source="imperva" act="REQ_BLOCKED_SECURITY" earliest=-1h
| stats count by category, src, dest_name
| sort -count

# XSS/SQLi no bloqueados (crítico)
index=anb_security source="imperva" earliest=-24h
NOT act IN ("REQ_BLOCKED_SECURITY","REQ_BLOCKED_COOKIELESS_SESSION")
| search category IN ("SQL Injection","Cross Site Scripting")
| stats count by category, src
| sort -count
```

**Troubleshooting:**

* Campos CEF vacíos: el REPORT-cef\_fields debe apuntar al transforms.conf correcto - la estructura de extensiones CEF varía entre versiones del appliance.
* Duplicados por HA: si el WAF está en modo HA con syslog replicado a ambos nodos, deduplicar por `cef_id`/`event_id`.

***

#### 10.5 DB Connect (Ingesta desde Bases de Datos)

**Ubicación:** Corre en el Heavy Forwarder (requiere KV Store saludable)

**Logs de diagnóstico:**

```bash
tail -f /splunk/var/log/splunk/splunk_app_db_connect_server.log
tail -f /splunk/var/log/splunk/dbx_java_server_error.log
```

**Verificar conectividad:**

```bash
nc -zv <db_host> <db_port>
# Settings → DB Connect → Databases → <connection> → Test Connection
```

**Problema - queries no corren en horario:**

```bash
/splunk/bin/splunk restart splunk_app_db_connect
```

**Problema - Java OutOfMemoryError:**

```bash
# Localizar config de JVM
find /splunk/etc/apps/splunk_app_db_connect -name "db-connect.conf"
# Aumentar: javaHeapSize = 1024  (default 512)
```

**Buenas prácticas:**

* Usar **rising column** (`checkpoint` incremental) para tablas grandes - reduce carga en la BD origen.
* Definir `fetch_size` acorde al ancho de fila (default 300) para evitar OOM con columnas BLOB/TEXT.
* Crear un usuario de BD de solo lectura específico para DB Connect - nunca usar credenciales administrativas.

***

#### 10.6 Microsoft 365 / Azure AD (Entra ID)

**TA:** `Splunk Add-on for Microsoft Office 365` + `Splunk Add-on for Microsoft Cloud Services`**Protocolo:** API polling (O365 Management Activity API / Microsoft Graph) - requiere app registration en Azure con permisos `ActivityFeed.Read` y `Directory.Read.All`

**inputs.conf:**

```
[o365_management_activity://production]
tenant_id= <tenant_guid>
client_id= <app_id>
client_secret= <secret>
content_types= Audit.AzureActiveDirectory,Audit.Exchange,Audit.SharePoint,Audit.General
index= m365_production
disabled=0

[aad://azure_ad_signin]
tenant_id= <tenant_guid>
client_id= <app_id>
client_secret= <secret>
azure_service= signin_logs
index= m365_production
disabled=0
```

**Queries de ejemplo:**

```
# Inicios de sesión fallidos por usuario
index=m365_production sourcetype="azure:aad:signin" ResultType!=0 earliest=-24h
| stats count by UserPrincipalName, ResultDescription
| sort -count

# Cambios de configuración Exchange (auditoría)
index=m365_production sourcetype="o365:management:activity" Workload=Exchange earliest=-24h
| stats count by Operation, UserId

# MFA deshabilitado o cambiado
index=m365_production sourcetype="o365:management:activity"
    Operation IN ("Update user.", "Disable Strong Authentication.")
| table _time, UserId, Operation, ModifiedProperties
```

**Troubleshooting:**

* Error `AADSTS7000215` (secret inválido/expirado): rotar en Azure y actualizar `inputs.conf`.
* Content types sin datos: activar la suscripción una vez por `content_type` vía Management Activity API.
* Rotación del client\_secret recomendada cada 6-12 meses - configurar alerta de expiración en Azure.

***

#### 10.7 AWS (CloudTrail y Servicios)

**TA:** `Splunk Add-on for Amazon Web Services`**Protocolo:** Polling S3 (CloudTrail logs) o SQS-based S3

**inputs.conf:**

```
[aws_cloudtrail://production]
aws_account= yes_aws_role
aws_region= eu-west-1
sourcetype= aws:cloudtrail
bucket_name= yes-cloudtrail-logs
key_name= AWSLogs/
index= cloud_production
disabled=0
```

**Queries de ejemplo:**

```
# Llamadas API por usuario IAM
index=cloud_production sourcetype="aws:cloudtrail" earliest=-1h
| stats count by userIdentity.arn, eventName
| sort -count

# Cambios de seguridad críticos
index=cloud_production sourcetype="aws:cloudtrail" earliest=-24h
    eventName IN ("CreateUser","AttachUserPolicy","AuthorizeSecurityGroupIngress","DeleteTrail")
| table _time, userIdentity.arn, eventName, requestParameters

# Errores de acceso (posible enumeración)
index=cloud_production sourcetype="aws:cloudtrail" errorCode="AccessDenied" earliest=-1h
| stats count by userIdentity.arn, eventName, awsRegion
| sort -count
```

**Troubleshooting:**

* Retraso de ingesta >15 min: CloudTrail entrega con demora nativa de \~5-15 min - no es fallo del TA salvo que supere 1h.
* Errores de permisos IAM: el rol asumido requiere `s3:GetObject`, `s3:ListBucket` y, si aplica, `sqs:ReceiveMessage`/`sqs:DeleteMessage`.

***

#### 10.8 Fortinet FortiGate

**TA:** `TA-fortinet_fortigate` (o `Fortinet FortiGate Add-on for Splunk`)\
**Protocolo:** Syslog UDP/TCP en formato key-value nativo de FortiOS

**inputs.conf:**

```
[udp://5518]
connection_host= ip
index= fw_production
sourcetype= fgt_log
disabled=0
```

**Queries de ejemplo:**

```
# Tráfico denegado por política
index=fw_production sourcetype="fgt_log" action=deny earliest=-1h
| stats count by srcip, dstip, dstport, policyid
| sort -count

# Eventos UTM (IPS/Antivirus)
index=fw_production sourcetype="fgt_log" logid=* type=utm earliest=-24h
| stats count by subtype, attack, srcip
```

**Troubleshooting:**

* Campos `srcip`/`dstip` sin normalizar a CIM: confirmar `tags.conf` del TA activo - FortiGate usa nombres propios que requieren el TA para el mapeo CIM.

***

#### 10.9 Cisco (ASA / Firepower / Meraki)

**TA:** `Splunk Add-on for Cisco ASA`, `Cisco Networks Add-on` (Firepower/FTD), `TA-cisco-meraki`**Protocolo:** Syslog (ASA/Firepower) o API polling (Meraki Dashboard API)

**inputs.conf (ASA):**

```
[udp://5519]
connection_host= ip
index= fw_production
sourcetype= cisco:asa
disabled=0
```

**inputs.conf (Meraki API):**

```
[meraki_api://production]
api_key= <encrypted_api_key>
organization_id= <org_id>
poll_interval=300
index= network_production
disabled=0
```

**Queries de ejemplo:**

```
# Conexiones denegadas ASA
index=fw_production sourcetype="cisco:asa" earliest=-1h "%ASA-*-106023"
| stats count by src, dest, dest_port
| sort -count
```

**Troubleshooting:**

* ASA: los mensajes `%ASA-N-XXXXXX` requieren el TA para mapear a `action`/CIM.
* Meraki: rate limiting de la API (5 req/seg por organización) - ajustar `poll_interval` si se ven errores 429.

***

#### 10.10 Okta

**TA:** `Okta Identity Cloud Add-on for Splunk`**Protocolo:** API polling (Okta System Log API) vía token API u OAuth2

**inputs.conf:**

```
[okta_log://production]
okta_domain= yes.okta.com
api_token= <encrypted_token>
poll_interval=60
index= iam_production
disabled=0
```

**Queries de ejemplo:**

```
# Inicios de sesión fallidos y bloqueos
index=iam_production sourcetype="OktaIM2:log" eventType=user.session.start outcome.result=FAILURE earliest=-24h
| stats count by actor.alternateId
| where count > 5

# Cambios de MFA
index=iam_production sourcetype="OktaIM2:log" eventType=user.mfa.factor.* earliest=-24h
| table _time, actor.alternateId, eventType, outcome.result

# Nuevas apps asignadas a usuarios
index=iam_production sourcetype="OktaIM2:log" eventType=application.user_membership.add earliest=-24h
| table _time, actor.alternateId, target{}.displayName
```

**Troubleshooting:**

* Token API expirado/revocado: fallo total y súbito de ingesta - revocación manual generalmente, no expiración automática.
* Volumen alto: preferir `poll_interval` de 30-60s con paginación correcta (`after` cursor) para no perder eventos.

***

#### 10.11 Zscaler

**TA:** `Zscaler Add-on for Splunk`**Protocolo:** Syslog NSS (Nanolog Streaming Service) o Cloud NSS Feed (HTTPS push)

**inputs.conf (NSS Syslog):**

```
[udp://5520]
connection_host= ip
index= web_production
sourcetype= zscalernss-web
disabled=0
```

**Queries de ejemplo:**

```
# Categorías web bloqueadas
index=web_production sourcetype="zscalernss-web" action=Blocked earliest=-1h
| stats count by urlcategory, user, url
| sort -count

# Amenazas detectadas por Zscaler
index=web_production sourcetype="zscalernss-web" threatcategory!="None" earliest=-24h
| stats count by threatname, user, url
```

**Troubleshooting:**

* Formato NSS variable entre feeds (`zscalernss-web`, `zscalernss-fw`, `zscalernss-dns`): confirmar el sourcetype correcto por feed configurado en el portal Zscaler.

***

#### 10.12 Tenable / Qualys (Vulnerability Management)

**TA:** `Tenable Add-on for Splunk` / `Qualys Technology Add-On`**Protocolo:** API polling ([Tenable.io](http://Tenable.io) Export API / Qualys API)

**inputs.conf (Tenable):**

```
[tenable_io://production]
access_key= <encrypted_key>
secret_key= <encrypted_key>
poll_interval=3600
index= vuln_production
disabled=0
```

**Queries de ejemplo:**

```
# Vulnerabilidades críticas abiertas por host
index=vuln_production sourcetype="tenable:io:vuln" severity=Critical earliest=-7d
| stats count by asset.hostname, plugin.name
| sort -count

# Nuevas vulnerabilidades en 24h
index=vuln_production sourcetype="tenable:io:vuln" earliest=-24h
| dedup plugin.id, asset.uuid
| stats count by plugin.name, severity
```

**Troubleshooting:**

* `poll_interval` debe alinearse a la frecuencia real de escaneo del cliente - no más frecuente que el escaneo mismo para evitar polling redundante.

***

#### 10.13 SentinelOne / Microsoft Defender for Endpoint

**TA:** `SentinelOne Add-on for Splunk` / `Splunk Add-on for Microsoft Defender for Endpoint`**Protocolo:** API polling

**inputs.conf (SentinelOne):**

```
[sentinelone://production]
console_url= <https://yes.sentinelone.net>
api_token= <encrypted_token>
poll_interval=60
index= endpoint_production
disabled=0
```

**inputs.conf (Defender for Endpoint):**

```
[msgraph_security://defender_atp]
tenant_id= <tenant_guid>
client_id= <app_id>
client_secret= <secret>
index= endpoint_production
disabled=0
```

**Queries de ejemplo:**

```
# Amenazas SentinelOne por nivel de confianza
index=endpoint_production sourcetype="sentinelone:threats" earliest=-24h
| stats count by agentComputerName, threatName, confidenceLevel
| sort -count

# Alertas Defender por severidad
index=endpoint_production sourcetype="msgraph:security:alert" earliest=-24h
| stats count by severity, category, deviceName
```

**Troubleshooting:**

* Ambos TAs dependen de tokens/app registrations con expiración - fallo total y súbito = token/secret expirado.
* Deduplicar alertas cuando ambos EDR coexisten en el mismo endpoint usando `deviceName`/`agentComputerName`.

***

#### 10.14 Sysmon (Windows Endpoint Avanzado)

**TA:** `Splunk Add-on for Sysmon` (parte de `Splunk_TA_windows` o separada)\
**Fuente:** Windows Event Log canal `Microsoft-Windows-Sysmon/Operational`

**inputs.conf:**

```
[WinEventLog://Microsoft-Windows-Sysmon/Operational]
disabled=0
index= endpoint_production
renderXml=true
```

**Queries de ejemplo:**

```
# Creación de procesos desde ubicaciones sospechosas (Event ID 1)
index=endpoint_production source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"
    EventCode=1 earliest=-1h
| where match(Image, "(?i)(temp|appdata|downloads|public)")
| stats count by Image, CommandLine, ParentImage, Computer
| sort -count

# Conexiones de red a IPs externas (Event ID 3)
index=endpoint_production source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"
    EventCode=3 Initiated=true earliest=-1h
| where NOT cidrmatch("10.0.0.0/8", DestinationIp)
    AND NOT cidrmatch("192.168.0.0/16", DestinationIp)
| stats count by Image, DestinationIp, DestinationPort, Computer

# Creación / modificación de servicios (Event ID 7, 13)
index=endpoint_production source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"
    EventCode IN (7, 13) earliest=-24h
| stats count by EventCode, Image, TargetObject, Details, Computer
```

***

### 11. Onboarding de Nueva Fuente - Checklist

#### Fase 1: Preparación

```
[ ] Identificar tipo de fuente (archivo, syslog, API, DB, HEC)
[ ] Determinar volumen estimado (eventos/segundo, GB/día) - impacto en licencia
[ ] Confirmar que hay capacidad de licencia disponible
[ ] Seleccionar índice destino (nuevo o existente) - ver tabla §1.4
[ ] Verificar si existe TA en Splunkbase y su versión compatible con el entorno
[ ] Crear Change Request aprobado
[ ] Confirmar ventana de mantenimiento con cliente
[ ] Verificar apertura de puertos de red necesarios (ver tabla §1.3)
```

#### Fase 2: Configuración en HF

```
[ ] Instalar TA si aplica (vía Deployment Server)
[ ] Configurar inputs.conf con el método de ingesta adecuado
[ ] Configurar props.conf: sourcetype, event breaking, timestamp
[ ] Configurar transforms.conf: routing de índice, enmascarado de datos sensibles
[ ] Validar con btool: /splunk/bin/splunk btool props list <sourcetype> --debug
[ ] Reiniciar/recargar el HF
```

#### Fase 3: Validación de Ingesta

```
[ ] Verificar que eventos llegan al índice (query §11.1)
[ ] Verificar timestamp correcto (query §11.2)
[ ] Verificar sourcetype asignado correctamente
[ ] Verificar campos CIM normalizados (src, dest, action, user)
[ ] Verificar ausencia de errores en splunkd.log
[ ] Verificar volumen razonable (ni 0 ni explosión de eventos)
```

**Query de validación de ingesta:**

```
index=<target> sourcetype=<sourcetype> earliest=-15m
| stats count, min(_time) as first_event, max(_time) as last_event by host, sourcetype
| eval delay_min = round((now() - last_event) / 60, 1)
| convert ctime(first_event) ctime(last_event)
```

**Query de validación de timestamp:**

```
index=<target> sourcetype=<sourcetype> earliest=-15m
| eval time_diff = abs(now() - _time)
| where time_diff > 300
| stats count, avg(time_diff) as avg_delay_sec by host
```

#### Fase 4: Normalización CIM

```
[ ] Verificar campos del data model:
      index=<target> sourcetype=<sourcetype> earliest=-15m
      | fieldsummary | table field, count, distinct_count
[ ] Confirmar que los tags del TA están activos (eventtypes.conf + tags.conf)
[ ] Correr conformidad CIM:
      | datamodelaccelerator info <datamodel>
[ ] Verificar que las búsquedas de detección existentes recogen los nuevos eventos
```

#### Fase 5: Documentación y Cierre

```
[ ] Registrar en inventario de fuentes: nombre, sourcetype, índice, HF, volumen
[ ] Documentar configuración de props/transforms en wiki interna
[ ] Crear búsqueda de validación en saved searches (alerta si count=0 en 30 min)
[ ] Confirmar al cliente que la integración está activa y enviando datos
[ ] Cerrar Change Request con detalles de implementación y evidencia
```

***

### 12. Errores Comunes y Soluciones

| Síntoma                                | Causa más probable                     | Diagnóstico                              | Solución                                    |
| -------------------------------------- | -------------------------------------- | ---------------------------------------- | ------------------------------------------- |
| Sin eventos en el índice               | Puerto bloqueado / input deshabilitado | `btool inputs list --debug`              | Habilitar input; abrir firewall             |
| Timestamp incorrecto (`_time` = ahora) | TIME\_PREFIX/TIME\_FORMAT incorrecto   | Ver eventos raw en Splunk Web            | Ajustar TIME\_FORMAT en props.conf          |
| Todos los eventos en uno solo          | Event breaking incorrecto              | Ver `_raw` del evento                    | Ajustar LINE\_BREAKER o BREAK\_ONLY\_BEFORE |
| Campos CIM vacíos                      | TA no instalado o mal configurado      | `\| fieldsummary`                        | Instalar/actualizar TA; verificar tags.conf |
| Datos sensibles en claro               | Sin mascarado                          | Inspeccionar `_raw`                      | Añadir SEDCMD o transforms de mascarado     |
| Eventos duplicados                     | Monitor apunta a archivo ya indexado   | Verificar fishbucket                     | Limpiar fishbucket o excluir con blacklist  |
| Cola de ingesta saturada               | Volumen excesivo o parser lento        | `index=_internal group=queue`            | Optimizar regex en props.conf; añadir HF    |
| Token HEC rechazado                    | Token revocado o incorrecto            | `curl` al endpoint health                | Rotar token en Splunk Web                   |
| API polling sin datos                  | Token API expirado / rate limit        | Logs del modular input                   | Renovar token; ajustar poll\_interval       |
| Licencia warning                       | Volumen súbito alto                    | `index=_internal source=*license_usage*` | Identificar fuente; filtrar en origen       |

***

### 13. Referencias Oficiales por Integración

| Integración                         | Recurso                                                                |
| ----------------------------------- | ---------------------------------------------------------------------- |
| Palo Alto Networks                  | Splunk Add-on for Palo Alto Networks (Splunkbase)                      |
| CrowdStrike Falcon                  | CrowdStrike FDR App for Splunk / TA for CrowdStrike Event Streams      |
| Anvilogic                           | Portal Anvilogic - integración vía HEC                                 |
| Imperva WAF                         | Imperva Incapsula Add-on for Splunk (Splunkbase)                       |
| DB Connect                          | `help.splunk.com` → *Database Connectivity*                            |
| Microsoft 365 / Azure AD            | Splunk Add-on for Microsoft Office 365 / Cloud Services (Splunkbase)   |
| AWS                                 | Splunk Add-on for Amazon Web Services (Splunkbase)                     |
| Fortinet FortiGate                  | Fortinet FortiGate Add-on for Splunk (Splunkbase)                      |
| Cisco (ASA/Firepower/Meraki)        | Splunk Add-on for Cisco ASA / Cisco Networks Add-on (Splunkbase)       |
| Okta                                | Okta Identity Cloud Add-on for Splunk (Splunkbase)                     |
| Zscaler                             | Zscaler Add-on for Splunk (Splunkbase)                                 |
| Tenable / Qualys                    | Tenable Add-on for Splunk / Qualys Technology Add-On (Splunkbase)      |
| SentinelOne / Defender for Endpoint | SentinelOne Add-on / Splunk Add-on for Microsoft Defender (Splunkbase) |
| Sysmon                              | Splunk Add-on for Sysmon (Splunkbase)                                  |
| HEC / Inputs / props-transforms     | `help.splunk.com` → *Getting Data In*                                  |
| Deployment Server                   | `help.splunk.com` → *Update Your Deployment*                           |
| CIM / Normalización                 | `help.splunk.com` → *Common Information Model Add-on Manual*           |

> **Nota:** Verificar siempre la compatibilidad del TA con la versión de Splunk Enterprise desplegada antes de instalar o actualizar.

***

### 14. Troubleshooting Avanzado de Forwarders

#### 14.1 Flowchart de Diagnóstico

```
¿Hay datos en el índice destino?
         |
    NO ──┼── SÍ ──> ¿Timestamp correcto? ──NO──> Ajustar TIME_FORMAT en props.conf
         |                   |
         v                YES ──> ¿Campos CIM presentes? ──NO──> Verificar TA + tags.conf
                                           |
                                         YES ──> Integración OK ✅
         |
¿El HF/UF está activo?
         |
    NO ──┼── SÍ ──> ¿Puerto 9997 alcanzable desde el HF?
         |                   |
    Arrancar                NO ──> Abrir regla de firewall outbound
    Splunk                  |
                           SÍ ──> ¿Input habilitado?
                                   |
                              NO ──┼── SÍ ──> ¿Hay errores en splunkd.log?
                                   |                   |
                             Habilitar          Ver §14.2 ──> Diagnóstico por tipo de error
                             en inputs.conf
```

#### 14.2 Errores Frecuentes en splunkd.log y mongod.log

| Patrón en log                                          | Causa                                                         | Solución                                                                                            |
| ------------------------------------------------------ | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `TcpOutputProc - Cooked connection to ip=X` (repetido) | HF no puede alcanzar el indexer en puerto 9997                | Verificar firewall outbound; `nc -zv <indexer> 9997`                                                |
| `LicenseUsage - type=Warn msg=...over limit`           | Volumen diario supera la cuota                                | Identificar fuente con `index=_internal source=*license_usage*`; reducir volumen o ampliar licencia |
| `QueueFull` para `parsingQueue` o `typingQueue`        | Pipeline de indexación saturado                               | Reducir volumen fuente; añadir HF; optimizar regex en props.conf                                    |
| `CRCCollision`                                         | Dos archivos diferentes con el mismo CRC inicial (fishbucket) | Añadir `crcSalt = <SOURCE>` en `inputs.conf` para el input afectado                                 |
| `No events for ...` (sobre un sourcetype esperado)     | Input deshabilitado o archivo no accesible                    | `btool inputs list <stanza> --debug`; verificar permisos del archivo                                |
| `Expired or not yet valid` (en mongod.log)             | Certificado del KV Store caducado                             | Renombrar `/splunk/etc/auth/server.pem` a `.bak` y reiniciar Splunk                                 |
| `OSError: [Errno 28] No space left on device`          | Disco lleno en el HF                                          | Limpiar logs históricos; ampliar disco; verificar `$SPLUNK_HOME/var/lib/splunk/fishbucket`          |
| `The output queue is full`                             | Indexer no disponible o lento                                 | Verificar estado del indexer; revisar colas con `index=_internal group=queue`                       |

#### 14.3 Comandos de Diagnóstico - Referencia Rápida

```bash
# Ver configuración efectiva de un input (debugging avanzado)
/splunk/bin/splunk btool inputs list <nombre_stanza> --debug

# Ver configuración efectiva de props (qué regla se aplica a un sourcetype)
/splunk/bin/splunk btool props list <sourcetype> --debug

# Comprobar conectividad del HF con los indexers
/splunk/bin/splunk list forward-server

# Ver colas de ingesta en tiempo real
/splunk/bin/splunk _internal call /services/admin/queues

# Comprobar si un archivo está siendo monitoreado
/splunk/bin/splunk list monitor | grep <ruta_archivo>

# Limpiar fishbucket de un archivo específico (PRECAUCIÓN: re-indexa desde inicio)
/splunk/bin/splunk clean eventdata -index <index> -source <file_path>

# Verificar fishbucket (checksums de archivos monitorizados)
/splunk/bin/python $SPLUNK_HOME/bin/fishbucket.py --dump <ruta_archivo>
```

#### 14.4 Validar Ingesta vía SPL

```
# Flujo de datos: últimos 15 minutos por fuente y host
index=<destino> earliest=-15m
| stats count, max(_time) as ultimo_evento by host, sourcetype, source
| eval ultima_vez = strftime(ultimo_evento, "%Y-%m-%d %H:%M:%S")
| sort -count

# Detectar gaps de ingesta (hosts sin datos en >30 min)
| tstats count WHERE index=<destino> earliest=-1h
  BY _time span=5m, host, sourcetype
| timechart span=5m count by host
| fillnull value=0

# Verificar parsing de timestamp (eventos con _time > 5 min de retraso)
index=<destino> earliest=-15m
| eval retraso = abs(now() - _time)
| where retraso > 300
| stats count, avg(retraso) as avg_retraso_seg by host, sourcetype
| sort -avg_retraso_seg

# Throughput de ingesta por sourcetype (KB/s)
index=_internal source=*metrics.log group=per_sourcetype_thruput earliest=-15m
| stats avg(kbps) as avg_kbps by series
| sort -avg_kbps
```

***

### 15. Ciclo de Vida del Universal Forwarder

#### 15.1 Despliegue de un Nuevo UF

```bash
# 1. Instalar el UF en el endpoint
# Linux:
tar -xzvf splunkforwarder-9.x.x-<build>-Linux-x86_64.tgz -C /opt
sudo /opt/splunkforwarder/bin/splunk start --accept-license --answer-yes
sudo /opt/splunkforwarder/bin/splunk enable boot-start

# Windows (PowerShell como Administrador):
msiexec.exe /i splunkforwarder-9.x.x-<build>-x64-release.msi AGREETOLICENSE=Yes /quiet

# 2. Apuntar el UF al Deployment Server para que reciba su configuración
/opt/splunkforwarder/bin/splunk set deploy-poll <deployment_server>:8089 -auth admin:changeme

# 3. Verificar que el UF aparece en el Deployment Server
# (en el DS, ejecutar):
/splunk/bin/splunk list deploy-clients | grep <hostname_UF>
```

#### 15.2 Actualización de Versión de UF

**Opción 1 - Via Deployment Server (método preferido para actualizar en masa):**

```
# En el Deployment Server - serverclass.conf
# Añadir la app de upgrade al server class del UF
[serverClass:all_uf:app:SplunkUniversalForwarder_upgrade]
restartSplunkd=true
stateOnClient= enabled
```

**Opción 2 - Upgrade manual (un solo UF):**

```bash
# Detener el UF
/opt/splunkforwarder/bin/splunk stop

# Extraer nuevo binario sobre el existente
tar -xzvf splunkforwarder-9.x.x-<build>-Linux-x86_64.tgz -C /

# Reiniciar y aceptar licencia
sudo -u splunk /opt/splunkforwarder/bin/splunk start --accept-license --answer-yes

# Verificar versión instalada
/opt/splunkforwarder/bin/splunk version
```

#### 15.3 Retirada de un UF

```bash
# 1. Detener y deshabilitar el servicio
/opt/splunkforwarder/bin/splunk stop
/opt/splunkforwarder/bin/splunk disable boot-start

# 2. Desregistrar del Deployment Server (en el DS):
/splunk/bin/splunk remove deploy-clients <clientName>

# 3. Verificar que el host ya no aparece en el índice destino (esperar 5 min):
index=<destino> host=<hostname_retirado> earliest=-5m

# 4. Eliminar la instalación del endpoint (Linux):
rm -rf /opt/splunkforwarder
```

#### 15.4 Monitorización de la Flota de UF

```
# UF que no han reportado en >1 hora
| rest /services/deployment/server/clients
| eval minutos_sin_reporte = round((now() - phoneHomeTime) / 60, 0)
| where minutos_sin_reporte > 60
| table clientName, ip, splunkVersion, minutos_sin_reporte
| sort -minutos_sin_reporte

# Versiones de UF desplegadas (detectar UF desactualizados)
| rest /services/deployment/server/clients
| stats count by splunkVersion
| sort -count

# UF con errores de conectividad recientes
index=_internal source=*splunkd.log component=TcpOutputProc earliest=-1h
| stats count by host, message
| sort -count
```
