Ir al contenido

Agente para Linux, macOS, FreeBSD y Windows

Un pequeño binario instalado en la máquina a monitorizar. Mide CPU, memoria, discos, red, servicios y contenedores — y, donde la máquina los expone, temperaturas, salud de disco, pools ZFS y máquinas virtuales KVM — y luego envía sus lecturas al servidor DumbMonit por HTTP.

La dirección es deliberada: el agente llama al servidor, nunca al revés. Cruza NAT y cortafuegos domésticos, y no requiere abrir ningún puerto en la máquina monitorizada.

Todas las métricas tienen el prefijo dumbmonit_. Las etiquetas de identidad (target, host, tag_*) las define el servidor al recibir, nunca el agente: una máquina no puede escribir en la serie de otra máquina, ni siquiera falsificando sus etiquetas.

FamiliaMétricasEtiquetas
CPUcpu_usage_percent, cpu_count, load_average_1/5/15; cpu_core_usage_percent solo con cpu_per_core: truecore
Memoriamemory_total/used/available_bytes, memory_used_percent, swap_total/used_bytes, swap_used_percent
Sistemas de archivosfilesystem_total/used/free_bytes, filesystem_used_percentmountpoint, device, fstype
Red (contadores)if_octets_in/out, if_packets_in/out, if_errors_in/outifname
Discos (contadores)disk_read_bytes, disk_written_bytes, una serie por dispositivo de bloquedevice
Hostuptime_seconds, process_count
Serviciosservice_up (1 = en ejecución)service
Contenedorescontainer_up, container_stop_expected (solo contenedores parados: 1 cuando Docker no lo reiniciaría), container_count, container_running_count, container_series_skipped (contenedores más allá de docker_max_containers), container_cpu_percent (porcentaje de un núcleo, desde el segundo ciclo), container_memory_bytes (sin caché), container_memory_limit_bytes y container_memory_percent (solo con límite), container_net_rx_bytes / container_net_tx_bytes y container_block_read_bytes / container_block_write_bytes (contadores acumulados), container_pids y, para todo el host, container_df_images_bytes, container_df_containers_bytes, container_df_volumes_bytes, container_df_build_cache_bytes, container_df_reclaimable_bytes (leídos cada diez minutos)container, image
Sensoresagent_sensor_temperature_celsius, agent_sensor_temperature_critical_celsius (el umbral que el propio hardware declara), agent_sensor_fan_rpmsensor, fan
Salud de disco (SMART)agent_disk_smart_ok (1 = el disco pasa su propia autoevaluación), agent_disk_temperature_celsius, agent_disk_power_on_hours, agent_disk_wearout_percent, agent_disk_reallocated_sectors, agent_disk_pending_sectors, agent_disk_media_errorsdevice, model
KVM / libvirtagent_libvirt_domains, agent_libvirt_domains_running, agent_libvirt_pools; por dominio agent_libvirt_domain_state_info, agent_libvirt_domain_running, agent_libvirt_domain_crashed, agent_libvirt_domain_vcpus, agent_libvirt_domain_memory_max_bytes, agent_libvirt_domain_memory_used_bytes; por pool de almacenamiento agent_libvirt_pool_state_info, agent_libvirt_pool_active, agent_libvirt_pool_capacity_bytes, agent_libvirt_pool_allocation_bytes, agent_libvirt_pool_used_percent — consulta Máquinas virtuales KVM con libvirtdomain, pool, state
ZFSagent_zfs_pool_health (0 online, 1 degraded, 2 peor), agent_zfs_pool_size/used/free_bytes, agent_zfs_pool_used_percent, agent_zfs_pool_fragmentation_percent, agent_zfs_pool_device_errors, agent_zfs_pool_data_errors, agent_zfs_pool_scrub_running, agent_zfs_pool_scrub_errors, agent_zfs_pool_scrub_age_secondspool
WireGuardagent_wireguard_interface_peers; por peer agent_wireguard_peer_handshake_age_seconds, agent_wireguard_peer_has_handshake, agent_wireguard_peer_keepalive_seconds, agent_wireguard_peer_rx_bytes, agent_wireguard_peer_tx_bytes (contadores) — consulta Túneles WireGuardinterface, peer, allowed_ips, name
IPsec (strongSwan)agent_ipsec_tunnel_up; cuando está activo, agent_ipsec_tunnel_bytes_in/out (contadores) y agent_ipsec_tunnel_rekey_seconds — consulta Túneles IPsecconnection, tunnel
Prueba de velocidad de Internetagent_speedtest_ok, agent_speedtest_age_seconds, agent_speedtest_download_bytes_per_second, agent_speedtest_upload_bytes_per_second, agent_speedtest_latency_ms, agent_speedtest_jitter_ms; los umbrales configurados se repiten como agent_speedtest_download_min_bytes_per_second, agent_speedtest_upload_min_bytes_per_second, agent_speedtest_max_latency_ms — consulta Prueba de velocidad de Internet
restic / Borgagent_backup_repo_reachable, agent_backup_repo_last_snapshot_age_seconds, agent_backup_repo_last_snapshot_bytes (restic) — consulta Copias de seguridad restic y Borgtool, repo
Contadores de rendimiento de Windowsagent_perf_counter, una serie por contador listado en perf_counterscounter
MDaemon (Windows)mdaemon_queue_messages, mdaemon_queue_frozen, mdaemon_sessions_active, mdaemon_sessions_total, mdaemon_messages_total, mdaemon_filtered_messages_total, mdaemon_server_active, mdaemon_running, mdaemon_uptime_seconds — consulta MDaemonqueue, protocol, filter, verdict, server
Hyper-V (Windows)hyperv_vms_health_ok, hyperv_vms_health_critical, hyperv_host_cpu_percent, hyperv_host_cpu_guest_percent, hyperv_partitions; por VM hyperv_vm_physical_memory_megabytes, hyperv_vm_guest_visible_memory_megabytes, hyperv_vm_memory_pressure_percent; por disco virtual hyperv_vhd_read_bytes_per_second, hyperv_vhd_write_bytes_per_second, hyperv_vhd_latency_seconds, hyperv_vhd_queue_length, hyperv_vhd_errors_total — consulta Hosts Hyper-Vvm, disk
Agenteagent_collect_seconds, agent_buffered_samples, agent_dropped_samples

Una serie que no se puede medir está ausente, nunca en cero: sin smartctl, sin agent_disk_*; sin sonda legible, sin agent_sensor_*; sin ZFS, sin agent_zfs_*; sin virsh, sin agent_libvirt_*. Una temperatura fuera de 1–150 °C se descarta en lugar de publicarse, y una lectura de ventilador de 0 rpm también se descarta — una placa base tiene más conectores de ventilador que ventiladores, y uno vacío lee cero igual que lo haría un ventilador muerto.

LinuxmacOSFreeBSDWindows
CPU, memoria, swap, sistemas de archivos, red, tiempo de actividad, procesossísísísí
Carga mediasísísíno (Windows no tiene esa noción)
Serviciossystemd (systemctl)launchd (launchctl)rc.d (service)servicios de Windows
Contenedores Dockersísí, si docker_socket apunta al socket de Docker Desktopno (sin demonio Docker)no
Temperaturas/sys/class/hwmonsensores SMCdev.cpu.N.temperature (solo CPU)no
Ventiladores/sys/class/hwmonnonono
Salud de disco (SMART)smartctlsmartctl (Homebrew)smartctl (sysutils/smartmontools)smartctl
Pools ZFSzpool (OpenZFS)nozpoolno
Máquinas virtuales KVM (libvirt)virshnonono
Salud del SO (actualizaciones, reinicio, unidades fallidas, SELinux)sínonono
Copias de seguridad Plakarsísísísí
Túneles WireGuardwg showcuando wg está instalado (no probado)cuando wg está instalado (no probado)no
Túneles IPsecswanctlcuando swanctl está instalado (no probado)cuando swanctl está instalado (no probado)no
Prueba de velocidad de Internetsí, opt-insí, opt-insí, opt-insí, opt-in
Copias de seguridad restic y Borgsísísísolo restic (no probado; Borg no tiene build para Windows)
Contadores de rendimiento, colas MDaemon, Hyper-Vnononosí
Identidad de máquina/etc/machine-idIOPlatformUUIDkern.hostuuid, /etc/hostidnombre de host
Modo relaysísísísí

Windows deliberadamente no tiene fila de temperatura: leer sensores ahí significa pasar por WMI, con derechos administrativos, para valores que la mayoría de máquinas no exponen en absoluto. No publicar nada es la respuesta honesta.

smartctl (smartmontools), zpool y virsh se buscan en cada período de lectura y se usan cuando están presentes; ninguno lo instala el agente, y ninguno es obligatorio. Todos necesitan root (virsh también funciona para un miembro del grupo libvirt) — el servicio que registra el instalador se ejecuta como root, un agente iniciado a mano con tu propia cuenta no encontrará nada.

Los contadores se envían en bruto, para que un reinicio del agente nunca produzca una tasa falsa; aplica rate() en las consultas.

Las reglas integradas que se aplican: Monitor unreachable, High CPU, Unusual CPU. «Monitor unreachable» también funciona en agentes: el servidor comprueba la antigüedad del último lote recibido y declara la máquina silenciosa tras tres períodos perdidos (al menos 90 segundos).

Cuatro más se activan solo en máquinas que producen la serie correspondiente, así que no necesitan ninguna configuración y no pueden activarse en una máquina sin el hardware:

ReglaSe activa cuando
Disk SMART failing (critical)la propia autoevaluación de un disco lo reporta como failing
ZFS pool degraded (critical)un pool ya no está ONLINE durante cinco minutos
ZFS scrub found errors (critical)el último scrub encontró errores, o el pool reporta archivos permanentemente corruptos
KVM domain crashed (critical)libvirt reporta un dominio como crashed
libvirt pool almost full (warning)la asignación de un pool de almacenamiento alcanza el 90 % de su capacidad durante quince minutos
Temperature above critical (critical)un sensor supera el umbral crítico que declara su propio hardware — ningún valor está escrito a fuego, siendo 85 °C una emergencia en un disco y una tarde normal en la CPU de un portátil

Varias más vigilan lo que tú declaras o ejecutas tú mismo, y permanecen en silencio en caso contrario: WireGuard peer silent (un peer con keepalive persistente y sin handshake durante 15 minutos), IPsec tunnel down (un túnel configurado sin sesión instalada durante diez minutos), restic/Borg backup too old (sin snapshot durante 48 horas), restic/Borg repository unreachable y Internet download rate low / Internet upload rate low / Internet latency high (solo cuando se define una opción de umbral) — consulta Túneles WireGuard, Túneles IPsec, Copias de seguridad restic y Borg y Prueba de velocidad de Internet.

En un servidor Windows que ejecuta MDaemon, tres más vigilan sus colas: MDaemon mail queue growing, MDaemon Bad queue not empty y MDaemon Retry queue high (consulta Reglas). En un host Hyper-V, tres vigilan las máquinas virtuales: Hyper-V VM health critical, Hyper-V host CPU high y Hyper-V virtual disk errors (consulta Hosts Hyper-V).

Los pasos de abajo son los que muestra el aviso junto al formulario. No hay ninguna cuenta que crear en la máquina: el token de inscripción es el único secreto.

  1. En DumbMonit, añade un monitor y elige Servidor con el agente. Elige cómo llega la máquina al servidor: Directamente o a través de un relé de un sitio remoto tras un cortafuegos (consulta Supervisar un sitio remoto). Se muestra una vez un token de inscripción (dmon_…), con el comando de instalación listo para copiar para Linux/macOS, Windows y Docker.
  2. Ese token es la clave del agente para enviar sus mediciones; no hay ninguna cuenta que crear en la máquina. Por defecto es de un solo uso: inscribe esta máquina y nada más. Para una flota (un playbook, una imagen de máquina), marca Varias máquinas con este comando antes de crear el comando; un dominio Windows entero pasa por el kit de Active Directory, ofrecido en la misma página. Un token perdido se revoca en Ajustes → Agentes.
  3. Ejecuta el comando de instalación en la máquina a supervisar, con privilegios elevados (sudo en Linux y macOS, un PowerShell como administrador en Windows).
  4. La página espera el primer envío (unos segundos) y luego te deja nombrar la máquina, archivarla en una carpeta y situarla en un sitio, al momento. En ese primer lote el servidor da al agente un secreto propio (/etc/dumbmonit/agent-secret, legible solo por él): desde entonces, esa máquina es la única que puede informar bajo este monitor.
  5. Docker: para ver los contenedores y permitir que DumbMonit los reinicie o actualice, el agente debe alcanzar el socket de Docker. El servicio que registra el instalador ya puede; si ejecutas el agente bajo un usuario dedicado en su lugar, añade ese usuario al grupo «docker» y reinícialo. Las políticas de reinicio y auto-actualización entonces se definen por contenedor en la página del monitor.

Dos cosas vale la pena leer antes de desplegar esto a más de una máquina: Vinculación, que es lo que hace que un monitor realmente pertenezca a una instalación de agente, y Un solo uso o flota, que es la elección que haces al crear un token.

```
usermod -aG docker dumbmonit
```

6. Copias de seguridad Plakar: detectadas automáticamente — aparece un monitor Plakar bajo la máquina cuando se encuentra el binario plakar o un kloset (~/.config/plakar/stores.yml de cada usuario, ~/.plakar, /var/lib/plakar), y no se muestra nada en caso contrario. Define «plakar_klosets» en agent.yaml para vigilar una lista fija, o «plakar: false» para desactivarlo. 7. Los servicios que el agente encuentra (Docker, Plakar, restic/Borg, ZFS, libvirt, WireGuard, IPsec, prueba de velocidad) se convierten cada uno en su propio monitor bajo la máquina, con su propio estado y sus propias alertas. El panel «Servicios encontrados por el agente» de la máquina lista lo que se encontró y lo que no: desmarca un módulo para quitar su monitor, márcalo para vigilarlo antes de que aparezca. Consulta Servicios encontrados por el agente.

Ventana de terminal
curl -sSL https://server:8080/install.sh | sh -s -- --token=dmon_xxx --url=https://server:8080

El script es sh POSIX (BusyBox y dash funcionan), descarga el binario para la arquitectura de la máquina (x86_64 o aarch64) desde el servidor, escribe /etc/dumbmonit/agent.yaml (modo 0600) y registra dumbmonit-agent con systemd, o con OpenRC en Alpine. La unidad systemd está reforzada (ProtectSystem=strict, NoNewPrivileges, MemoryMax=256M, CPUQuota=20%).

El mismo comando que en Linux, ejecutado con sudo:

Ventana de terminal
curl -sSL https://server:8080/install.sh | sudo sh -s -- --token=dmon_xxx --url=https://server:8080

Los binarios de macOS no están en la imagen de DumbMonit: compilarlos requiere el SDK de Apple, cuya licencia prohíbe redistribuirlo. En su lugar se adjuntan a cada versión de GitHub — dumbmonit-agent-macos-aarch64 (Apple silicon) y dumbmonit-agent-macos-x86_64 (Intel), cada uno con su .sha256 — y el servidor redirige /download/dumbmonit-agent-macos-… ahí, así que el script elige el de la arquitectura del Mac (uname -m). El servidor no distribuye esos binarios, así que el comando de instalación no lleva ningún checksum para ellos: añade --sha256=macos-aarch64:<hex> (o macos-x86_64) con el valor del .sha256 de la versión, o el instalador rechaza la descarga. El Mac también necesita alcanzar github.com.

Sin ese acceso, o para instalar un binario que ya tienes, descárgalo y pásalo con --bin (compáralo primero con el .sha256 de la versión: --bin instala lo que le das):

Ventana de terminal
curl -sSLO https://github.com/laupernoe/dumbmonit/releases/latest/download/dumbmonit-agent-macos-aarch64
curl -sSL https://server:8080/install.sh | sudo sh -s -- \
--token=dmon_xxx --url=https://server:8080 --bin=./dumbmonit-agent-macos-aarch64

El script instala el binario en /usr/local/bin (y elimina el atributo de cuarentena que lleva una descarga de navegador, que haría que Gatekeeper se negara a iniciarlo), escribe /usr/local/etc/dumbmonit/agent.yaml (modo 0600) y registra el demonio del sistema com.dumbmonit.agent en /Library/LaunchDaemons, iniciado con launchctl bootstrap system. Se ejecuta al arrancar, sin nadie con sesión iniciada.

Ventana de terminal
fetch -qo - https://server:8080/install.sh | sh -s -- --token=dmon_xxx --url=https://server:8080

Solo x86_64. El script descarga dumbmonit-agent-freebsd-x86_64 desde el servidor, escribe /usr/local/etc/dumbmonit/agent.yaml (modo 0600) e instala /usr/local/etc/rc.d/dumbmonit_agent, activado con service dumbmonit_agent enable. daemon(8) supervisa el agente, lo reinicia si se detiene y escribe /var/log/dumbmonit-agent.log.

Funciona igual en TrueNAS CORE y otros electrodomésticos basados en FreeBSD, donde las series ZFS son el punto del ejercicio.

Ventana de terminal
& ([scriptblock]::Create((irm https://server:8080/install.ps1))) -Token dmon_xxx -Url https://server:8080

El script descarga dumbmonit-agent-windows-x86_64.exe desde el servidor, lo comprueba contra su SHA-256, lo instala como C:\Program Files\DumbMonit\dumbmonit-agent.exe, escribe C:\ProgramData\DumbMonit\agent.yaml (legible solo por SYSTEM y Administrators) y registra el servicio de Windows DumbMonitAgent («DumbMonit system agent»): iniciado automáticamente al arrancar, como LocalSystem, y reiniciado tras un fallo (10 s, 30 s, luego 60 s). El agente habla con el propio gestor de servicios (--service), así que detener el servicio le permite enviar lo que todavía conserva antes de salir.

Un servicio no tiene consola: el agente escribe su registro en C:\ProgramData\DumbMonit\agent.log, archivado como agent.log.old más allá de 10 MB.

No hay compilación ARM64 nativa: en Windows 11 para ARM, el script instala el binario x86_64, que se ejecuta bajo emulación x64.

Un token puede inscribir varias máquinas: nómbralo según un grupo o una máquina.

El agente es un único ejecutable estático por sistema, sin nada que instalar a su lado:

SistemaArchivoDónde obtenerlo
Linux x86_64dumbmonit-agent-linux-x86_64el servidor, /download/…
Linux aarch64 (ARM de 64 bits: Raspberry Pi OS 64 bits, servidores ARM)dumbmonit-agent-linux-aarch64el servidor, /download/…
Windows x86_64dumbmonit-agent-windows-x86_64.exeel servidor, /download/…
FreeBSD x86_64dumbmonit-agent-freebsd-x86_64el servidor, /download/…
macOS Apple silicondumbmonit-agent-macos-aarch64la versión de GitHub (el servidor redirige ahí)
macOS Inteldumbmonit-agent-macos-x86_64la versión de GitHub (el servidor redirige ahí)

Los binarios de Linux están enlazados estáticamente contra musl: se ejecutan en cualquier distribución, glibc o no (Alpine, firmwares de NAS), sin ninguna biblioteca que hacer coincidir. Cada archivo tiene su checksum al lado, <archivo>.sha256, en formato sha256sum. Cada versión de GitHub lleva los seis binarios y sus checksums, para máquinas que no pueden alcanzar el /download/ del servidor o para instalar con --bin.

Desde 0.9.0, cada binario de una versión también está firmado sin claves (keyless) con Sigstore (<archivo>.sigstore.json) y lleva una atestación de procedencia SLSA. Para comprobar que un binario fue compilado por el flujo de trabajo de publicación de este repositorio:

Ventana de terminal
cosign verify-blob dumbmonit-agent-linux-x86_64 \
--bundle dumbmonit-agent-linux-x86_64.sigstore.json \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp '^https://github.com/laupernoe/dumbmonit/\.github/workflows/release\.yml@refs/tags/v'
# or, with the GitHub CLI:
gh attestation verify dumbmonit-agent-linux-x86_64 -R laupernoe/dumbmonit

Para compilar tú mismo los binarios de Linux, Windows y FreeBSD, desde un clon del repositorio (Docker es el único requisito):

Ventana de terminal
docker buildx build --target agent-dist --output type=local,dest=dist/agent .
Linux (systemd)Linux (OpenRC)macOS (launchd)FreeBSD (rc.d)Windows (PowerShell)
Estadosystemctl status dumbmonit-agentrc-service dumbmonit-agent statussudo launchctl print system/com.dumbmonit.agentservice dumbmonit_agent statusGet-Service DumbMonitAgent
Registrosjournalctl -u dumbmonit-agent -ftail -f /var/log/dumbmonit-agent.logtail -f /var/log/dumbmonit-agent.logtail -f /var/log/dumbmonit-agent.logGet-Content C:\ProgramData\DumbMonit\agent.log -Tail 20 -Wait
Reiniciarsystemctl restart dumbmonit-agentrc-service dumbmonit-agent restartsudo launchctl kickstart -k system/com.dumbmonit.agentservice dumbmonit_agent restartRestart-Service DumbMonitAgent
Detenersystemctl stop dumbmonit-agentrc-service dumbmonit-agent stopsudo launchctl bootout system/com.dumbmonit.agentservice dumbmonit_agent onestopStop-Service DumbMonitAgent
Configuración/etc/dumbmonit/agent.yaml/etc/dumbmonit/agent.yaml/usr/local/etc/dumbmonit/agent.yaml/usr/local/etc/dumbmonit/agent.yamlC:\ProgramData\DumbMonit\agent.yaml
Archivo de servicio/etc/systemd/system/dumbmonit-agent.service/etc/init.d/dumbmonit-agent/Library/LaunchDaemons/com.dumbmonit.agent.plist/usr/local/etc/rc.d/dumbmonit_agentservicio DumbMonitAgent (services.msc)

--uninstall (-Uninstall en Windows) lo elimina todo, servicio incluido, en cada sistema.

install.shinstall.ps1Efecto
--token=TOKEN-TokenToken de inscripción (obligatorio).
--url=URL-UrlURL del servidor, por ejemplo https://server:8080. En Linux, se usa DUMBMONIT_URL del entorno si falta el flag.
--interval=N-IntervalPeríodo de muestreo en segundos (por defecto 30).
--services=a,b,c-Services @('a','b')Servicios cuyo estado se reporta, nombrados como los nombra el sistema anfitrión: unidades systemd en Linux, etiquetas launchd (com.apple.sshd) en macOS, nombres rc.d en FreeBSD, servicios de Windows.
--tags=key=value,…-Tags @{key='value'}Etiquetas, copiadas como tag_<key> en cada serie.
--hostname=NAME-HostNameNombre anunciado al servidor (por defecto: el de la máquina).
--bin=PATH-BinPathBinario local a instalar en lugar de descargarlo.
--sha256=LIST-Sha256SHA-256 esperado de la descarga, como pares plataforma-arch:hex separados por comas (un valor hex sin más también funciona). Incluido en el comando que muestra DumbMonit; obligatorio a menos que se dé el siguiente flag.
--insecure-skip-checksum-InsecureSkipChecksumInstala un binario descargado sin verificarlo, con un aviso. Solo para configuraciones aisladas o manuales.
--no-startInstala todo, pero no contacta al servidor ni inicia el servicio (imagen de máquina, pruebas).
--uninstall-UninstallDesinstala el agente y elimina su configuración.
--helpMuestra la ayuda.

Ambos scripts son idempotentes: ejecutar de nuevo el comando de instalación, con el mismo token y URL, sustituye el binario, reescribe la configuración y reinicia el servicio. Ese es el procedimiento de actualización. Toma el comando del servidor actual (Settings → Agents): su --sha256 debe coincidir con los binarios de la versión del servidor a la que actualizaste.

El mismo comando migra una máquina que todavía ejecuta el agente EzyMonit, en Linux y en Windows. El instalador detiene y elimina el servicio antiguo (ezymonit-agent, o EzyMonitAgent en Windows), mueve la configuración a la nueva ruta (/etc/dumbmonit/agent.yaml, C:\ProgramData\DumbMonit\agent.yaml) e instala dumbmonit-agent en su lugar. El antiguo token ezym_… sigue siendo válido, así que el comando mostrado al crear el token sigue funcionando; no hay que revocar nada primero.

El monitor propio de la máquina muestra la máquina: CPU, memoria, sistemas de archivos, red, salud de los discos (SMART), sensores, salud del SO y los servicios que listas en services. Todo lo demás que el agente detecta es un servicio, y cada servicio que encuentra se convierte en un monitor propio, de tipo agent_service, archivado bajo la máquina:

ServicioSus métricasNombre del monitor
Dockercontainer_*<machine> · Docker
Plakarbackup_*<machine> · Plakar
restic / Borgagent_backup_repo_*<machine> · restic/Borg
ZFSagent_zfs_*<machine> · ZFS
KVM / libvirtagent_libvirt_*<machine> · libvirt
WireGuardagent_wireguard_*<machine> · WireGuard
IPsecagent_ipsec_*<machine> · IPsec
Prueba de velocidad de Internetagent_speedtest_*<machine> · Speed test

El reparto se hace en el servidor, por nombre de métrica, así que funciona con cualquier versión del agente. Cada serie se escribe una sola vez, con target apuntando al monitor al que pertenece: las series de un servicio llevan el id del monitor del servicio, las de la máquina el id de la máquina. Nada se cuenta dos veces.

Un monitor de servicio tiene su propio estado, alertas, reglas, excepciones de reglas y silencios. Está inalcanzable cuando el agente deja de reportarlo mientras la máquina sigue reportando (demonio Docker detenido, wg eliminado…), tras los mismos tres periodos perdidos que la propia máquina. Cuando la máquina se queda en silencio, sus servicios se muestran como ocultos detrás de ella (suppressed) en lugar de generar alertas propias. Un monitor de servicio nuevo empieza con las etiquetas de la máquina, así que los silencios y reglas basados en etiquetas siguen aplicándose.

No hay nada que elegir antes de la instalación. Tras el primer reporte, la página de la máquina lista cada módulo en Servicios encontrados por el agente:

  • un servicio encontrado está marcado y enlaza a su monitor;
  • un servicio no encontrado está desmarcado; márcalo para crear igualmente su monitor (permanece inalcanzable hasta que el agente lo reporte — útil para que te avisen si falta un servicio del que dependes);
  • desmarca un servicio encontrado para eliminar su monitor y descartar sus lecturas. El servidor se lo indica al agente en su siguiente confirmación, y el agente deja de recolectarlo (un agente antiguo sigue recolectando, y el servidor sigue descartando). Eliminar un monitor de servicio tiene el mismo efecto. Márcalo de nuevo para recuperarlo.

Eliminar la máquina elimina sus monitores de servicio. Las acciones y políticas de contenedores funcionan desde la página del monitor Docker; los comandos siguen yendo al agente de la máquina.

Igual que en el aviso del monitor:

  1. No hay nada que añadir a mano: instala el agente en la máquina, y cada servicio que encuentra se convierte en un monitor bajo esa máquina en su primer reporte.
  2. Para dejar de vigilar un servicio, desmárcalo en el panel «Servicios encontrados por el agente» de la máquina, o elimina su monitor: las lecturas del agente para él se descartan entonces.

Nada que hacer. La primera vez que el agente reporta un servicio tras la actualización, el servidor crea su monitor y traslada a él lo que concernía a ese servicio en la máquina:

  • las excepciones de las reglas que leen las métricas del servicio se copian al monitor del servicio;
  • las reglas limitadas a la máquina (selector ids) que leen las métricas del servicio ahora seleccionan también el monitor del servicio;
  • los silencios (ventanas de mantenimiento) de la máquina se copian al monitor del servicio;
  • las alertas en curso sobre las series del servicio se trasladan al monitor del servicio con su nueva huella, para que no se resuelvan y vuelvan a dispararse.

El historial se queda donde se escribió: VictoriaMetrics no puede reetiquetar series existentes, así que las lecturas anteriores a la actualización permanecen bajo la máquina (caducan con la retención), y los gráficos del monitor del servicio empiezan en la actualización. Las líneas base de anomalías de las series trasladadas vuelven a empezar a aprender. El historial de alertas (alertas resueltas) también se queda con la máquina.

/etc/dumbmonit/agent.yaml en Linux, /usr/local/etc/dumbmonit/agent.yaml en macOS y FreeBSD, C:\ProgramData\DumbMonit\agent.yaml en Windows:

server_url: https://server:8080
token: dmon_...
interval_secs: 30 # período de muestreo
hostname: nas-basement # opcional: nombre anunciado al servidor
services: # unidades systemd o servicios de Windows
- sshd
- docker
tags: # etiquetas libres, con prefijo "tag_" en el servidor
role: nas
room: basement
docker: true # inventario de contenedores (por defecto: true)
docker_socket: /var/run/docker.sock
sensors: true # temperaturas y ventiladores (por defecto: true)
smart: true # salud de disco a través de smartctl (por defecto: true)
smart_bin: smartctl # ruta, cuando no está en el PATH del servicio
smart_interval_secs: 300 # mínimo 60: un disco dormido nunca se despierta para leerse
zfs: true # pools ZFS a través de zpool (por defecto: true)
zfs_bin: zpool
zfs_interval_secs: 120 # mínimo 30
libvirt: true # dominios KVM y pools de almacenamiento a través de virsh (por defecto: true)
libvirt_bin: virsh
libvirt_uri: qemu:///system
libvirt_interval_secs: 60 # mínimo 15
wireguard: true # túneles WireGuard a través de wg (por defecto: true), ver abajo
ipsec: true # túneles IPsec a través de swanctl (por defecto: true), ver abajo
speedtest: false # prueba de velocidad de Internet (por defecto: false, opt-in), ver abajo
speedtest_download_url: https://speed.example.lan/backend/garbage.php?ckSize=50
speedtest_upload_url: https://speed.example.lan/backend/empty.php
restic_repos: [] # repositorios restic a vigilar, ver "copias de seguridad restic y Borg"
borg_repos: [] # repositorios Borg a vigilar
mdaemon: auto # Windows: colas MDaemon cuando existe su servicio (true / false / auto)
hyperv: auto # Windows: contadores Hyper-V cuando existe el servicio vmms (true / false / auto)
perf_counters: # Windows: contadores de rendimiento a publicar
- '\Memory\Available MBytes'
- path: '\Processor(_Total)\% Processor Time'
name: cpu_total # valor de la etiqueta "counter"; la ruta cuando se omite
max_buffered_samples: 20000
log_level: info

sensors, smart, zfs y libvirt se detectan, nunca se asumen: dejados en true en una máquina sin sonda, sin smartctl, sin pool o sin virsh, cuestan una mirada por período y no emiten nada en absoluto. Define uno como false para dejar de mirar incluso así — vale la pena hacerlo en un NAS cuyos discos prefieras que smartctl nunca toque, aunque el agente ya pasa -n standby para que un disco dormido se mida solo cuando está despierto por otras razones.

En un hipervisor KVM (un host Linux normal con libvirt, no Proxmox VE, que tiene su propia integración), instala el agente en el propio host, no en un invitado. El agente ejecuta virsh -c qemu:///system con list --all --name, dominfo --domain <nombre>, pool-list --all --name y pool-info --pool <nombre>: nunca define, arranca, detiene ni migra un dominio, y nunca modifica un pool de almacenamiento. La URI explícita qemu:///system importa para un agente ejecutado por un miembro del grupo libvirt en lugar de root: sin ella, virsh leería la sesión privada y vacía de ese usuario. Define libvirt_uri para leer otra conexión.

agent_libvirt_domain_memory_used_bytes está ausente para un dominio apagado: libvirt solo conoce su máximo configurado. Los tamaños de los pools de almacenamiento provienen de la salida legible de virsh, redondeada a dos decimales, así que agent_libvirt_pool_used_percent es una aproximación, suficientemente cercana para avisar antes de que un pool se llene. Se detallan como máximo 200 dominios y 64 pools.

Junto a él, /etc/dumbmonit/agent-secret (C:\ProgramData\DumbMonit\agent-secret en Windows) contiene el secreto de vinculación que el servidor dio a esta máquina. El agente lo escribe con modo 0600 y lo vuelve a leer en cada arranque; no es parte de agent.yaml porque no es algo que tú defines — consulta Vinculación. DUMBMONIT_AGENT_SECRET_FILE lo mueve, que es lo que quieres para un agente en un contenedor.

Cada clave se puede anular con el entorno, lo cual hace al agente usable en un contenedor sin montar un archivo:

VariableEfecto
DUMBMONIT_AGENT_CONFIGRuta del archivo de configuración
DUMBMONIT_AGENT_URLURL del servidor
DUMBMONIT_AGENT_TOKENToken de inscripción
DUMBMONIT_AGENT_SECRET_FILEDónde guardar el secreto de vinculación (por defecto: agent-secret, junto al archivo de configuración)
DUMBMONIT_AGENT_INTERVAL_SECSPeríodo de muestreo
DUMBMONIT_AGENT_HOSTNAMENombre anunciado al servidor
DUMBMONIT_AGENT_SERVICESServicios a vigilar, separados por comas
DUMBMONIT_AGENT_TAGSkey=value, separados por comas
DUMBMONIT_AGENT_DOCKERtrue / false
DUMBMONIT_AGENT_DOCKER_SOCKETRuta del socket de Docker
DUMBMONIT_AGENT_DOCKER_MAX_CONTAINERSContenedores detallados por host, por defecto 200 (0: solo recuentos)
DUMBMONIT_AGENT_INTERFACES_IGNOREInterfaces excluidas, nombres o regex separados por comas; por defecto ^(veth|br-|docker|virbr|lo$|vEthernet)
DUMBMONIT_AGENT_INTERFACES_ONLYInterfaces a conservar; si se define, sustituye la lista de exclusión
DUMBMONIT_AGENT_MOUNTS_IGNOREPuntos de montaje excluidos de sistemas de archivos y E/S de disco; por defecto omite /var/lib/docker/, /run/…, /sys/, /proc/, /dev/, /snap/
DUMBMONIT_AGENT_CPU_PER_COREtrue para también enviar una serie de CPU por núcleo (por defecto false)
DUMBMONIT_AGENT_SENSORStrue / false: temperaturas y ventiladores (por defecto true)
DUMBMONIT_AGENT_SMARTtrue / false: salud de disco a través de smartctl (por defecto true)
DUMBMONIT_AGENT_SMART_BINRuta de smartctl
DUMBMONIT_AGENT_SMART_INTERVAL_SECSPeríodo entre dos lecturas SMART, por defecto 300, mínimo 60
DUMBMONIT_AGENT_ZFStrue / false: pools ZFS a través de zpool (por defecto true)
DUMBMONIT_AGENT_ZFS_BINRuta de zpool
DUMBMONIT_AGENT_ZFS_INTERVAL_SECSPeríodo entre dos lecturas ZFS, por defecto 120, mínimo 30
DUMBMONIT_AGENT_LIBVIRTtrue / false: dominios KVM y pools de almacenamiento a través de virsh (por defecto true)
DUMBMONIT_AGENT_LIBVIRT_BINRuta de virsh
DUMBMONIT_AGENT_LIBVIRT_URIURI de conexión de libvirt, por defecto qemu:///system
DUMBMONIT_AGENT_LIBVIRT_INTERVAL_SECSPeríodo entre dos lecturas de libvirt, por defecto 60, mínimo 15
DUMBMONIT_AGENT_WIREGUARDtrue / false: túneles WireGuard a través de wg (por defecto true)
DUMBMONIT_AGENT_WIREGUARD_BINRuta de wg
DUMBMONIT_AGENT_IPSECtrue / false: túneles IPsec a través de swanctl (por defecto true)
DUMBMONIT_AGENT_IPSEC_BINRuta de swanctl
DUMBMONIT_AGENT_SPEEDTESTtrue / false: ejecutar la prueba de velocidad de Internet (por defecto false)
DUMBMONIT_AGENT_SPEEDTEST_DOWNLOAD_URLDirección que se descarga para medir la velocidad de descarga
DUMBMONIT_AGENT_SPEEDTEST_UPLOAD_URLDirección a la que se envía con POST para medir la velocidad de subida
DUMBMONIT_AGENT_SPEEDTEST_DOWNLOAD_BYTES_CAPMáximo de bytes leídos por prueba, por defecto 50000000
DUMBMONIT_AGENT_SPEEDTEST_UPLOAD_BYTESBytes enviados por prueba, por defecto 10000000
DUMBMONIT_AGENT_SPEEDTEST_INTERVAL_SECSPeríodo entre dos pruebas, por defecto 21600 (6 h), mínimo 300
DUMBMONIT_AGENT_SPEEDTEST_MIN_DOWNLOAD_MBPSUmbral de alerta, velocidad de descarga en Mbps (sin definir: sin alerta)
DUMBMONIT_AGENT_SPEEDTEST_MIN_UPLOAD_MBPSUmbral de alerta, velocidad de subida en Mbps (sin definir: sin alerta)
DUMBMONIT_AGENT_SPEEDTEST_MAX_LATENCY_MSUmbral de alerta, latencia en milisegundos (sin definir: sin alerta)
DUMBMONIT_AGENT_RESTIC_BINRuta de restic
DUMBMONIT_AGENT_BORG_BINRuta de borg
DUMBMONIT_AGENT_BACKUP_REPOS_INTERVAL_SECSPeríodo entre dos lecturas de los repositorios restic y Borg, por defecto 600, mínimo 60
DUMBMONIT_AGENT_MDAEMONtrue, false o auto: los contadores de rendimiento de MDaemon (por defecto auto, leído cuando existe el servicio Windows MDaemon)
DUMBMONIT_AGENT_HYPERVtrue, false o auto: los contadores de rendimiento de Hyper-V (por defecto auto, leído cuando existe el servicio Windows vmms)
DUMBMONIT_AGENT_PERF_COUNTERSRutas de contador de rendimiento de Windows, separadas por punto y coma (una coma puede formar parte de un nombre de instancia); sustituye perf_counters
DUMBMONIT_AGENT_SYSTEM_HEALTHtrue / false: salud del sistema operativo, el interruptor general de los cuatro siguientes (por defecto true)
DUMBMONIT_AGENT_CHECK_UPDATEStrue / false: actualizaciones pendientes (por defecto true)
DUMBMONIT_AGENT_UPDATES_INTERVAL_SECSPeriodo entre dos comprobaciones de actualizaciones pendientes, por defecto 3600, mínimo 300
DUMBMONIT_AGENT_CHECK_REBOOTtrue / false: reinicio necesario (por defecto true)
DUMBMONIT_AGENT_CHECK_FAILED_UNITStrue / false: unidades systemd fallidas (por defecto true)
DUMBMONIT_AGENT_MAX_BUFFERED_SAMPLESTamaño del búfer de recuperación
DUMBMONIT_AGENT_LOGtrace, debug, info, warn, error
DUMBMONIT_AGENT_RELAYtrue para ejecutar, por el servidor, las sondas de los monitores asignados a este agente (consulta Ejecutar el agente en Docker / en otra red)
DUMBMONIT_AGENT_SITEEtiqueta de sitio mostrada junto al agente cuando se ofrece como relay
DUMBMONIT_AGENT_GATEWAY_LISTENPasarela de un relé para los agentes de su sitio, por ejemplo 0.0.0.0:8443 (gateway_listen:); prevalece sobre el puerto fijado en la interfaz (consulta Instalar agentes detrás del relé)
DUMBMONIT_AGENT_GATEWAY_MAX_CONNECTIONSConexiones que la pasarela mantiene a la vez, 64 por defecto (gateway_max_connections:)
DUMBMONIT_AGENT_GATEWAY_RATE_KIBCaudal de cada túnel a través de la pasarela, por sentido, en KiB/s, 4096 por defecto (gateway_rate_kib:)

En Windows, el agente lee los contadores de rendimiento — los valores que muestra Performance Monitor (perfmon) — a través de la biblioteca PDH, y los publica en cada período de muestreo. Algún software no publica su estado en ningún otro sitio.

MDaemon. Cuando existe el servicio de Windows llamado MDaemon, el agente lee el objeto de rendimiento de MDaemon: tamaños de cola, sesiones, totales de mensajes y spam, el estado de los servidores internos de MDaemon y su tiempo de actividad. Las series, las reglas y la página que las muestra se describen en la página de MDaemon. mdaemon: true las lee incluso sin el servicio (un servicio renombrado), mdaemon: false nunca lo hace. La presencia del servicio se vuelve a comprobar cada diez períodos, así que un MDaemon instalado después se recoge sin reiniciar el agente.

Hyper-V. Cuando existe el servicio Hyper-V Virtual Machine Management (vmms), el agente lee los objetos de rendimiento de Hyper-V; consulta Hosts Hyper-V. hyperv: true y hyperv: false fuerzan la elección, como para MDaemon.

Cualquier otro contador. Lista su ruta completa bajo perf_counters, como \Objeto(Instancia)\Contador o \Objeto\Contador para un objeto con una sola instancia, y se publica como dumbmonit_agent_perf_counter{counter="…"}, con el nombre que den o la propia ruta:

perf_counters:
- '\LogicalDisk(C:)\% Free Space'
- path: '\MSExchangeTransport Queues(_total)\Messages Queued For Delivery'
name: exchange_queue
  • Escribe los nombres de contador en inglés, tal como aparecen en Performance Monitor en un Windows en inglés: el agente los añade con PdhAddEnglishCounterW, así que el mismo agent.yaml funciona en un Windows en francés o alemán.
  • Pon cada ruta entre comillas simples en YAML, para que las barras invertidas y el % se conserven tal cual.
  • Una ruta mal formada detiene el agente al arrancar con la clave y el motivo. Una ruta que Windows no conoce (el software no está instalado, el nombre está mal escrito) se reporta una vez en el registro, performance counter not available, y los demás contadores se siguen leyendo; se vuelve a intentar cada diez períodos.
  • Las tasas (…/sec) necesitan dos lecturas: aparecen a partir del segundo período.
  • Como máximo se leen 200 contadores. En Linux, macOS y FreeBSD el ajuste se acepta y no se lee nada.

Para ver los nombres exactos en la máquina, ejecuta typeperf -q MDaemon (o cualquier otro nombre de objeto) en una línea de comandos.

Instalado en un host Hyper-V — Windows Server con el rol Hyper-V, o Windows con Hyper-V activado — el agente encuentra el servicio vmms y lee los propios contadores de rendimiento de Hyper-V, sin nada que configurar. La página de monitor del agente entonces muestra un panel Hyper-V: cuántas máquinas virtuales reportan sanas, la carga real de CPU del host, la memoria que retiene cada VM en ejecución, y el caudal, latencia y errores de cada disco virtual.

ContadorSerieEtiquetas
\Hyper-V Virtual Machine Health Summary\Health Ok, …\Health Criticalhyperv_vms_health_ok, hyperv_vms_health_critical: máquinas virtuales en cada estado
\Hyper-V Hypervisor Logical Processor(_Total)\% Total Run Timehyperv_host_cpu_percent: la carga del host, invitados incluidos
\Hyper-V Hypervisor Logical Processor(_Total)\% Guest Run Timehyperv_host_cpu_guest_percent: la proporción dedicada a ejecutar invitados
\Hyper-V Hypervisor\Partitionshyperv_partitions: VMs en ejecución más el propio host
\Hyper-V Dynamic Memory VM(*)\Physical Memory, …\Guest Visible Physical Memoryhyperv_vm_physical_memory_megabytes, hyperv_vm_guest_visible_memory_megabytesvm
\Hyper-V Dynamic Memory VM(*)\Current Pressurehyperv_vm_memory_pressure_percent: demanda de memoria sobre memoria asignada; por encima de 100 la VM quiere más de lo que tienevm
\Hyper-V Virtual Storage Device(*)\Read Bytes/sec, …\Write Bytes/sechyperv_vhd_read_bytes_per_second, hyperv_vhd_write_bytes_per_seconddisk
\Hyper-V Virtual Storage Device(*)\Latency, …\Queue Lengthhyperv_vhd_latency_seconds (promedio), hyperv_vhd_queue_lengthdisk
\Hyper-V Virtual Storage Device(*)\Error Counthyperv_vhd_errors_total, un contadordisk

En un host Hyper-V, \Processor(_Total)\% Processor Time solo mide la propia partición del host, no lo que consumen las máquinas virtuales: el contador de procesador lógico del hipervisor es el que dice si la máquina está saturada. vm es el nombre de la máquina virtual tal como lo muestra Hyper-V Manager; disk es el nombre de instancia que da Windows a cada disco virtual, derivado de su ruta de archivo. Las instancias _Total se excluyen, y como máximo se leen 200 VMs o discos por contador.

Se aplican tres reglas integradas:

  • Hyper-V VM health critical: Hyper-V reporta una VM en salud crítica durante cinco minutos (Warning) — con más frecuencia un disco que se quedó sin espacio.
  • Hyper-V host CPU high: los procesadores lógicos más del 90 % ocupados durante quince minutos (Advisory).
  • Hyper-V virtual disk errors: un disco virtual reportó errores de E/S en la última hora (Advisory).

El agente también se distribuye como una imagen de contenedor, con las mismas etiquetas que el servidor: ghcr.io/laupernoe/dumbmonit-agent:latest (última versión), :edge (último commit en main). Es una imagen FROM scratch que contiene el binario del agente y el paquete de CA de Mozilla, configurada enteramente por variables de entorno. El repositorio incluye un docker-compose.agent.yml listo para usar:

Ventana de terminal
DUMBMONIT_AGENT_URL=https://monitor.example.org \
DUMBMONIT_AGENT_TOKEN=dmon_… \
DUMBMONIT_AGENT_HOSTNAME=docker-host-1 \
docker compose -f docker-compose.agent.yml up -d

Qué ve el contenedor, y qué montar:

NecesidadQué hacerPor qué
CPU, memoria, carga, E/S de disco del hostNada/proc/stat, /proc/meminfo, /proc/loadavg y /proc/diskstats son de todo el host dentro de cualquier contenedor.
Nombre de hostDUMBMONIT_AGENT_HOSTNAMEEl hostname de un contenedor es un id aleatorio; el monitor se nombraría según él.
Contenedores del host- /var/run/docker.sock:/var/run/docker.sock:roOpcional. Listas e inspecciones de solo lectura; las acciones Restart/Update lo necesitan en escritura y DUMBMONIT_AGENT_COMMANDS=true. Sin el socket, el agente simplemente no reporta ningún contenedor.
Uso del sistema de archivos- /:/host:ro (o los montajes que te importen)El agente reporta los montajes visibles dentro del contenedor, bajo su ruta de contenedor.
Contadores de red del hostnetwork_mode: hostLas interfaces están en namespace: sin esto el agente ve un veth.
Monitores de ping relayados a través de este agentesysctls: net.ipv4.ping_group_range: "0 2147483647"ICMP usa un socket de eco, permitido por este sysctl: sin capability. Ver Ping ICMP sin capability.
CA privada- ./ca-bundle.crt:/etc/ssl/certs/ca-certificates.crt:roServidor detrás de un proxy inverso interno, dispositivos con certificados autofirmados.
Mantener la vinculación entre recreaciones- agent-state:/var/lib/dumbmonit-agent y DUMBMONIT_AGENT_SECRET_FILE=/var/lib/dumbmonit-agent/agent-secretEl secreto de vinculación vive en el sistema de archivos del contenedor, que un docker compose up --force-recreate descarta. Sin el volumen, el agente vuelve sin vincular y alguien tiene que permitir la reinscripción desde la página de monitor cada vez.

pid: host y privileged: true nunca son necesarios: el agente no recolecta ninguna métrica por proceso.

Un agente puede hacer más que vigilar su propia máquina. Con relay: true (o DUMBMONIT_AGENT_RELAY=true), el servidor delega sondas en él: los monitores cuyo ajuste Reached through nombra a este agente no son sondeados por el servidor sino por el agente, desde su propia red, con exactamente los mismos recolectores — SNMP, Proxmox VE, Proxmox Backup Server, Synology, HTTP, TCP, DNS, ping, TLS. Los resultados caen bajo el monitor como si el servidor lo hubiera sondeado: mismas métricas, mismo last probe, mismas alertas. Una oficina remota, un segundo homelab o la red de un cliente así aparecen en el único DumbMonit que ya tienes, sin VPN y sin nada que abrir del lado remoto.

Cómo configurarlo, paso a paso, está en Monitorizar un sitio remoto.

Un token de inscripción dice esta máquina puede hablar. No dice cuál máquina está hablando — para eso está la clave de identidad (/etc/machine-id, o el nombre de host), y esa clave no es ningún secreto: se puede leer en cualquier máquina en segundos.

Así que en el primer lote el servidor entrega a cada máquina un secreto de vinculación propio. Solo conserva una huella; el agente escribe el secreto en /etc/dumbmonit/agent-secret con modo 0600 y lo presenta en la cabecera X-DumbMonit-Agent-Secret en cada petición a partir de entonces — mediciones, comandos de contenedor y sondas relayadas por igual. Desde entonces:

  • ninguna otra máquina puede enviar mediciones bajo este monitor, ni reescribir su nombre de host y sistema operativo;
  • ninguna otra máquina puede obtener — y por tanto consumir — los comandos Restart y Update encolados para ella.

La página del monitor muestra dónde está una máquina, bajo Agent → Binding:

EstadoQué significaQué hacer
BoundEl agente tiene un secreto propio.Nada.
Not bound — re-enrol this hostUn host inscrito antes de que existiera la vinculación, y que nunca se vinculó desde entonces. El servidor rechaza sus mediciones, comandos de contenedor y sondas relayadas.Haz clic en Allow re-enrolment en la página del monitor, y luego reinicia el agente. Si el agente es anterior a la vinculación, vuelve a ejecutar primero el comando de instalación en el host.

Para traer de vuelta tal host:

  1. Si su agente es anterior a la vinculación, vuelve a ejecutar el comando de instalación en él (el binario del agente debe poder guardar un secreto de vinculación).
  2. Abre su página de monitor y haz clic en Agent → Allow re-enrolment. Esto abre una ventana de una hora.
  3. Reinicia el agente, o espera a su siguiente reintento: ese lote vincula el host con un secreto nuevo y cierra la ventana. Un token distinto del que inscribió el host todavía debe poder inscribir (no agotado, no caducado).

Hasta entonces, el registro del agente lleva la explicación del servidor:

WARN this agent is not recognised for this machine
reason: This machine was enrolled before agent binding and was never bound
to its agent installation, so the server no longer accepts it. Re-enrol
this host: open its device page in DumbMonit, click 'Allow re-enrolment',
then restart the agent (re-run the install command first if the agent is
older than binding).

Si la máquina se reconstruye, su disco se reemplaza, o su contenedor de agente se recrea sin el volumen que guarda el secreto, el agente vuelve sin él y el servidor rechaza sus lotes. Ese rechazo es deliberado: una máquina que está vinculada permanece vinculada hasta que un humano dice lo contrario, de lo contrario la vinculación no protegería nada.

La vía de vuelta está en la página del monitor: Agent → Allow re-enrolment. Abre una ventana de una hora durante la cual un agente que presenta un token de inscripción válido vincula esa máquina de nuevo, con un secreto nuevo; el secreto antiguo deja de funcionar, y la ventana se cierra en cuanto se usa. El agente reintenta por su cuenta mientras tanto, así que no hay nada que reiniciar en la máquina — y nada se pierde, ya que sus lecturas se mantienen en búfer hasta que se vuelve a aceptar el enlace.

Hasta que alguien abre esa ventana, el registro del agente dice qué hacer:

WARN this agent is not recognised for this machine
reason: This machine is already enrolled and bound to another agent
installation. If you reinstalled it, open its device page in DumbMonit and
click 'Allow re-enrolment', then restart the agent.

El agente olvida su secreto solo ante esa negativa exacta. Cualquier otro 403, por ejemplo de un proxy inverso o de un cortafuegos de aplicaciones web delante de DumbMonit, se registra y se reintenta conservando el secreto.

  • Los tokens se crean al añadir un monitor de tipo agent (de un solo uso o para varias máquinas) y con el kit de Active Directory. El servidor solo conserva una huella: el token en claro se muestra una vez, en la respuesta de creación, con los dos comandos de instalación.
  • El agente lo envía como Authorization: Bearer dmon_… en POST /api/ingest. Nunca aparece en los registros del agente, ni siquiera truncado.
  • Settings → Agents lista los tokens con su prefijo, alcance, fecha de creación y último uso. Revoke detiene cada agente que usa ese token en su próximo envío; las máquinas entonces se vuelven unreachable tras tres períodos perdidos. Vuelve a ejecutar el instalador con un token nuevo para volver a inscribirlas.
  • Las máquinas son monitores separados: revocar un token no las elimina.

El alcance de un token se elige al crearlo, y es una elección, no un valor por defecto que te ocurre:

AlcanceQué inscribeCuándo
Single use (por defecto)Exactamente una máquina.Una instalación. Un comando de instalación persiste en el historial de shell, en un ticket, en un registro de chat; uno de un solo uso no vale nada una vez usado.
Reusable for a fleetTantas máquinas como permitas — un número, o sin límite.Un playbook, una imagen de máquina, un lote de instalaciones.

Ambos pueden llevar un plazo en días. Un plazo solo detiene las inscripciones: las máquinas ya inscritas siguen reportando después de que pase, que es lo que quieres para una ventana de instalación. Revocar es lo que corta a una flota.

Un token que ya no puede inscribir — agotado, o pasado su plazo — se muestra como Enrols no more en Settings → Agents. Sus máquinas siguen reportando; simplemente no puede dejar entrar a una nueva.

Cuando el servidor es inaccesible, el agente sigue midiendo y mantiene sus lecturas en memoria con sus timestamps originales. Se envían en cuanto el enlace vuelve: un reinicio del servidor no deja ningún hueco en las gráficas. El búfer está limitado (max_buffered_samples, aproximadamente una hora por defecto) y descarta las lecturas más antiguas cuando está lleno. Los reintentos se retrasan de 2 a 30 segundos con jitter.

Ventana de terminal
dumbmonit-agent --dry-run # imprime las lecturas, no envía nada
dumbmonit-agent --once # envía un lote y sale
journalctl -u dumbmonit-agent -f # registro del servicio (systemd)
tail -f /var/log/dumbmonit-agent.log # registro del servicio (OpenRC)
SíntomaCausa probable
El instalador dice «could not reach the server»URL o token incorrectos. La configuración se escribe: corrige agent.yaml, y luego reinicia el servicio.
La descarga falla con 404El servidor no tiene binarios de agente (DUMBMONIT_AGENT_DIR vacío). Usa --bin=RUTA con un binario que hayas compilado.
El instalador se detiene con «checksum mismatch»El comando se copió antes de una actualización del servidor (copia uno nuevo al añadir un servidor con el agente), o el binario recibido no es el que sirve el servidor: un proxy o una caché en el camino, o una descarga manipulada.
El instalador se detiene con «no expected checksum»El comando no tiene --sha256 para esta plataforma: un comando antiguo, o un binario de macOS (no distribuido por el servidor). Copia un comando nuevo, o pasa --sha256=<plataforma>-<arch>:<hex> del .sha256 de la versión.
La máquina nunca apareceEl envío va a /api/ingest en la URL del comando de instalación; detrás de un proxy inverso, asegúrate de que se reenvía y que se permiten cuerpos de hasta 16 MB.
Unreachable aunque el agente se ejecuteEl token se revocó, o los envíos se rechazan. Comprueba journalctl -u dumbmonit-agent: el error se registra ahí.
El registro dice «this agent is not recognised for this machine»La máquina está vinculada a una instalación de agente cuyo secreto este agente no tiene — una reinstalación, o un contenedor recreado sin su volumen de estado. Abre la página del monitor y haz clic en Allow re-enrolment; consulta Reinscripción tras una reinstalación.
El registro dice «this machine was enrolled before agent binding»Un host que nunca se vinculó a su agente. Haz clic en Allow re-enrolment en su página de monitor, y luego reinicia el agente; consulta Hosts anteriores a la vinculación.
El registro dice «this agent is too old to be bound to its machine»El binario del agente no puede guardar un secreto de vinculación. Vuelve a ejecutar el comando de instalación en el host; si el monitor ya existe, haz clic primero en Allow re-enrolment.
El registro dice «this enrollment token has already enrolled all the machines it was allowed to»Se está reutilizando un token de un solo uso. Crea uno nuevo, o marca Varias máquinas con este comando al añadir el servidor.
WindowsLas partes de servicio de Windows no se habían probado en la imagen de compilación del proyecto en el momento de escribir esto; reporta problemas en GitHub.

Cuando el agente puede leer el socket de Docker (docker: true, por defecto, y un usuario en el grupo docker o root — usermod -aG docker dumbmonit, y luego reinicia el agente), cada contenedor se convierte en un puñado de series, etiquetadas container e image (el name:tag que muestra docker ps). Si la página del monitor dice «No Docker on this machine» mientras Docker está instalado, eso es lo primero a comprobar.

MétricaSignificado
container_up1 en ejecución, 0 en caso contrario
container_health0 sin healthcheck, 1 sano, 2 no sano, 3 iniciando
container_restart_countEl contador de reinicios de Docker para el contenedor
container_started_secondsSegundos desde que el contenedor se inició por última vez (0 cuando está detenido)
container_image_age_secondsSegundos desde que se compiló la imagen
container_update_available1 cuando el registro tiene una imagen más reciente para la misma etiqueta, 0 cuando está al día, -1 desconocido

La comprobación de actualización compara el digest de la imagen local con el que anuncia el registro para la etiqueta (HEAD /v2/<name>/manifests/<tag>, flujo de token anónimo en Docker Hub y GHCR). Se ejecuta en segundo plano como máximo una vez por hora por imagen y nunca retrasa el ciclo de 30 segundos; un registro privado que rechaza el acceso anónimo simplemente lee como -1. Desactívala con docker_update_check: false (DUMBMONIT_AGENT_DOCKER_UPDATE_CHECK).

Reglas integradas: Container stopped (container_up == 0 durante 2 minutos), Container unhealthy (container_health == 2 durante 3 minutos), Container restarting (tres o más reinicios en 15 minutos), Container update available (info, tras una hora, repetido diariamente). La alerta nombra el contenedor.

En la página del monitor, cada contenedor tiene dos acciones y dos interruptores. Las acciones viajan por un canal de comandos: el servidor encola el comando, el agente lo obtiene tras su siguiente lote (GET /api/agent/commands, mismo token de inscripción), lo ejecuta, y reporta el resultado (queued → running → done | failed), con un registro breve que puedes desplegar en la interfaz. Los comandos de más de diez minutos nunca se ejecutan; el agente ejecuta un comando a la vez.

Un comando en cola se puede cancelar desde la interfaz mientras el agente no lo haya recogido. Un comando que nadie viene a buscar caduca tras diez minutos, en el servidor, tanto si el agente sondea como si no — así que una máquina cuyo agente está detenido nunca mantiene un «Queued» obsoleto para siempre, y nunca bloquea la siguiente acción en ese contenedor.

El agente le dice al servidor, con cada lote, si acepta comandos. Cuando no lo hace — un agente más antiguo que el canal de comandos, o instalado con commands: false — la página del monitor lo indica en lugar de mostrar Restart y Update, la API rechaza los comandos (409), y las políticas no encolan nada. Reinstala el agente con el instalador actual para activar las acciones.

  • Restart — docker restart para un contenedor en ejecución, docker start para uno detenido, y luego una comprobación de 20 segundos de que se ejecuta.
  • Update now — obtiene la etiqueta que ya usa el contenedor, crea un contenedor nuevo con la misma configuración (entorno, montajes, puertos, etiquetas, redes, política de reinicio), detiene el antiguo, intercambia los nombres, inicia el nuevo y espera su healthcheck (o 20 segundos más una comprobación de ejecución cuando la imagen no tiene ninguno). Si algo falla, el agente revierte: el contenedor nuevo se elimina y el antiguo se reinicia, y el comando reporta failed con el motivo. En éxito el contenedor antiguo se elimina y, cuando «prune» está activado, la imagen antigua también — a menos que otro contenedor todavía la use.

Los contenedores gestionados por Compose (etiquetas com.docker.compose.*) se actualizan igual, pero el resultado avisa de que el siguiente docker compose up recreará el contenedor desde el archivo compose. Los contenedores cuyo nombre empieza con dumbmonit o ezymonit se rechazan: el monitor nunca se actualiza a sí mismo.

Una política por contenedor la evalúa el servidor cada minuto:

  • Restart if down — un contenedor que reporta container_up == 0 se reinicia automáticamente, como máximo una vez cada diez minutos.
  • Auto-update in maintenance windows — un contenedor con una actualización disponible se actualiza automáticamente, pero solo mientras una ventana de mantenimiento (silencio) cubra el monitor, como máximo una vez cada seis horas. Programa una en la página Alerts, o silencia el monitor desde su página. Las políticas por defecto podan la imagen antigua y solo en ventanas de mantenimiento.

Dos lugares las definen:

  • la franja Docker bajo la cabecera del monitor: «28 containers · 27 running · 3 updates available · policies: 2 auto-restart, 0 auto-update», la última acción y su estado, Manage containers (abre la lista de abajo) y Policies…, una tabla de cada contenedor con los dos interruptores y una fila «Apply to all» — la forma más rápida de activar el auto-restart para toda una máquina;
  • los interruptores dentro de cada fila de la sección Containers, junto a los botones Restart y Update now.

Cada interruptor se guarda por su cuenta (PUT /api/targets/<id>/containers/<name>/policy); un fallo solo afecta a esa fila y se muestra junto a ella.

Las acciones automáticas aparecen en «Recent actions» como solicitadas por policy.

  • El agente solo actúa cuando commands: true (por defecto); defínelo como false para una máquina que solo deba medirse.
  • El agente obtiene los comandos él mismo, con su token de inscripción — nada se conecta a la máquina. Caducan tras diez minutos y se ejecutan de uno en uno; el agente nunca obtiene una etiqueta distinta de la que ya usa el contenedor.
  • Una actualización que no vuelve sana se revierte al contenedor anterior, y la imagen antigua solo se elimina una vez que el contenedor nuevo se ejecuta.
  • Los contenedores llamados dumbmonit* o ezymonit* se rechazan, a mano o por política: el monitor nunca actúa sobre sus propios contenedores. La comprobación se hace dos veces — el servidor se niega a encolar el comando, y el agente se niega a ejecutarlo — y el agente la vuelve a hacer sobre el nombre que reporta Docker tras inspeccionar el contenedor, así que nombrar uno por su id no cambia nada. El agente también se niega a actuar sobre su propio contenedor, se llame como se llame: no estaría ahí para terminar el trabajo o reportarlo.
  • Los contenedores gestionados por Compose se actualizan, pero el siguiente docker compose up los recrea desde el archivo compose: sube también la etiqueta ahí.

El agente puede vigilar klosets (repositorios) de Plakar: cada diez minutos, en segundo plano, ejecuta plakar at <kloset> ls e info en cada uno y vuelve a emitir la última lectura en cada ciclo.

Plakar se detecta, nunca se asume. Al arrancar y luego en cada ciclo hasta que encuentra algo, el agente busca el binario plakar (en PATH, o plakar_bin) y klosets en las ubicaciones estándar. Cuando no hay ningún binario, ningún kloset ni ningún rastro de Plakar (~/.cache/plakar), el agente no emite ninguna serie backup_* en absoluto, lo indica una vez a nivel debug, y la página del monitor no muestra ningún panel Backups — nada que configurar en máquinas sin Plakar. Para omitir la detección por completo:

plakar: false # o DUMBMONIT_AGENT_PLAKAR=false

Nada que configurar: cuando plakar_klosets está vacío, el agente encuentra los klosets él mismo, en este orden, y lee cada ubicación solo una vez:

  1. el propio directorio de configuración del agente — $XDG_CONFIG_HOME/plakar, o ~/.config/plakar de la cuenta bajo la que se ejecuta (plakar_home cuando se define);
  2. /root/.config/plakar;
  3. /home/*/.config/plakar, alfabéticamente;
  4. /var/lib/plakar, cuando ese directorio existe.

En cada directorio lee stores.yml (o stores.yaml; el antiguo plakar.yml también se acepta) y toma cada entrada del mapa stores (también repositories y klosets) que tiene una location. Solo se lee la ubicación: las frases de paso y secretos de rclone que están junto a ella nunca se conservan ni se registran. Cada entrada se convierte en el kloset @<name>, leído con plakar -configdir <dir> at @<name>, así que un kloset creado por un usuario se lee incluso cuando el agente se ejecuta como root. ~/.plakar de cada cuenta se añade cuando existe (el kloset por defecto de plakar create). Dos cuentas que nombran klosets distintos de la misma forma se distinguen como @name y <user>:@name.

El resultado se registra una vez a nivel info (y de nuevo solo cuando cambia). Dos gauges, emitidos solo una vez detectado Plakar, permiten a la interfaz distinguir los demás casos: backup_plakar_present (1 cuando el binario se ejecuta) y backup_klosets_found (número de klosets leídos). La página del monitor entonces dice «Plakar is installed but no kloset was found», o lista los klosets. Cuando existen klosets pero el binario no se ejecuta (un PATH de servicio sin plakar, típicamente), se listan como illegibles con una pista para definir plakar_bin, y el agente avisa una vez.

Para vigilar una lista fija en su lugar, nómbrala — el descubrimiento entonces se omite:

plakar: true # por defecto: detectar Plakar; false lo oculta por completo
plakar_bin: /usr/bin/plakar # por defecto: "plakar" en PATH
plakar_klosets: # lista explícita: anula el descubrimiento
- /srv/backups/main
- "@diskext" # un store nombrado de la cuenta del agente
plakar_home: /home/noe # opcional: HOME (y directorio de config) usado al ejecutar plakar
plakar_interval_secs: 600 # mínimo 60
VariableEfecto
DUMBMONIT_AGENT_PLAKARtrue / false — vigilar copias Plakar cuando se detectan (por defecto true)
DUMBMONIT_AGENT_PLAKAR_BINRuta del binario plakar
DUMBMONIT_AGENT_PLAKAR_KLOSETSKlosets, separados por comas (anula el descubrimiento)
DUMBMONIT_AGENT_PLAKAR_HOMEDirectorio home usado al ejecutar plakar
DUMBMONIT_AGENT_PLAKAR_INTERVAL_SECSSegundos entre dos lecturas
DUMBMONIT_AGENT_DOCKER_UPDATE_CHECKtrue / false — comprobación de registro para actualizaciones de contenedor
DUMBMONIT_AGENT_COMMANDStrue / false — aceptar acciones del servidor

Un kloset cifrado necesita su frase de paso: ponla en la entrada del store (plakar store set <name> passphrase=…, que es lo que hace plakar store add) o exporta PLAKAR_PASSPHRASE en el entorno del servicio del agente. Sin ella el kloset se lee como «Cannot be opened» (backup_last_status = 0).

Métricas, etiquetadas kloset y source (el directorio que se respaldó): backup_last_success_seconds (antigüedad del snapshot más reciente), backup_snapshot_count, backup_last_status (1 cuando el snapshot más reciente no tiene errores, 0 cuando los tiene o el kloset no se puede abrir), backup_size_bytes{kloset} (tamaño de almacenamiento del repositorio), más backup_plakar_present y backup_klosets_found descritos arriba. Ninguna de ellas existe mientras no se detecta Plakar, así que las reglas integradas de abajo no pueden activarse en una máquina sin Plakar.

Reglas integradas: Plakar backup too old (advisory, sin snapshot durante más de dos días) y Plakar backup failed (warning). La página del monitor muestra un bloque por kloset — antigüedad de la última copia, recuento de snapshots, tamaño, último estado — y una línea por fuente, con una pista «Backup too old» pasados dos días.

Con Plakar 1.1 instalado en la máquina (plakar version), como el usuario que será propietario de las copias:

Ventana de terminal
# 1. un store de kloset, nombrado para que el agente lo encuentre en ~/.config/plakar/stores.yml
plakar store add diskext /mnt/diskext/plakar passphrase=… # o cualquier ubicación que acepte Plakar
plakar at @diskext create # añade -plaintext para omitir el cifrado
# 2. una primera copia, luego compruébala
plakar at @diskext backup /srv/photos
plakar at @diskext ls

plakar at <path> create y plakar at <path> backup <dir> funcionan igual con un directorio plano en lugar de @name; plakar create sin at usa ~/.plakar, que el agente también encuentra. Programa plakar at @diskext backup /srv/photos con cron o un timer systemd: el agente reporta la antigüedad del snapshot más reciente, y alerta cuando pasa un día sin uno — dos días para la regla integrada.

Para probarlo localmente con un kloset sin cifrar:

Ventana de terminal
mkdir -p /tmp/plakar-demo-src && echo hello > /tmp/plakar-demo-src/a.txt
plakar at /tmp/plakar-demo create -plaintext
plakar at /tmp/plakar-demo backup /tmp/plakar-demo-src
plakar at /tmp/plakar-demo ls

y luego añade plakar_klosets: ["/tmp/plakar-demo"] a agent.yaml (una ruta plana fuera de un home no se descubre) y comprueba con dumbmonit-agent --dry-run que aparecen muestras backup_*.

El agente puede vigilar repositorios restic y Borg: cada diez minutos, en segundo plano, abre cada repositorio que declaras y reporta si se pudo leer y cuán antiguo es su snapshot más reciente. Nada se descubre: un repositorio no tiene ninguna ubicación estándar y no se puede abrir sin su contraseña, así que cada uno se lista en agent.yaml, con la forma de obtener su contraseña.

La contraseña nunca sale de la máquina. El agente la entrega a restic o borg solo a través del entorno del proceso hijo; nunca se registra, nunca se envía al servidor, y las series solo llevan el nombre del repositorio.

restic_repos:
- name: nas # la etiqueta "repo"; por defecto: el repositorio, sin credenciales
repository: sftp:backup@nas.lan:/srv/restic # pasado como RESTIC_REPOSITORY, nunca en la línea de comandos
password_file: /etc/dumbmonit/restic-nas.pass
host: web-01 # opcional: solo los snapshots de este host (--host), para un repositorio compartido
args: ["-o", "sftp.command=ssh -i /etc/dumbmonit/id_backup -o UserKnownHostsFile=/etc/dumbmonit/known_hosts backup@nas.lan -s sftp"]
- name: b2
repository: s3:https://s3.eu-central-003.backblazeb2.com/my-bucket
password_command: cat /etc/dumbmonit/restic-b2.pass # o cualquier comando que la imprima (RESTIC_PASSWORD_COMMAND)
env: # entorno extra solo para este repositorio
AWS_ACCESS_KEY_ID: "…"
AWS_SECRET_ACCESS_KEY: "…"
borg_repos:
- name: offsite
repository: ssh://borg@offsite.example.net/./backups # pasado como BORG_REPO
password_file: /etc/dumbmonit/borg-offsite.pass # leído por el agente, pasado como BORG_PASSPHRASE
glob_archives: "web-01-*" # opcional: solo estos archivos (--glob-archives)
env:
BORG_RSH: "ssh -i /etc/dumbmonit/id_borg -o UserKnownHostsFile=/etc/dumbmonit/known_hosts"
restic_bin: restic # por defecto: en PATH
borg_bin: borg
backup_repos_interval_secs: 600 # mínimo 60

Mantén agent.yaml y los archivos de contraseña legibles solo por root (chmod 600), como hace el instalador para agent.yaml. password_command se mapea a RESTIC_PASSWORD_COMMAND o BORG_PASSCOMMAND. Cualquier cosa que las herramientas lean de su entorno puede ir bajo env (RESTIC_PASSWORD, BORG_PASSPHRASE, claves cloud, BORG_RSH…), y el propio entorno de servicio del agente también se pasa.

Lo que ejecuta el agente, de solo lectura en el sentido más estricto:

  • restic snapshots --json --latest 1 --no-lock --no-cache: no se escribe ningún bloqueo, así que un repositorio de solo lectura o solo-anexar se puede vigilar, y un prune que mantiene el bloqueo exclusivo no hace que el repositorio parezca caído; tampoco caché, ya que el servicio instalado no puede escribir en /root.
  • borg --bypass-lock list --json --last 1: sin --bypass-lock, la lectura fallaría durante toda la duración de cada borg create, que mantiene el bloqueo exclusivo. Borg escribe un pequeño registro de seguridad bajo ~/.config/borg; cuando ese home no se puede escribir (el servicio instalado se ejecuta con ProtectHome=yes), el agente apunta BORG_BASE_DIR a su /tmp privado en su lugar, a menos que tú mismo definas BORG_BASE_DIR. Un repositorio en modo keyfile entonces necesita BORG_KEY_FILE en su env.

Como el servicio se ejecuta con ProtectHome=yes, mantén lo que necesitan las herramientas fuera de los directorios home: archivos de contraseña, claves SSH y known_hosts bajo /etc/dumbmonit/, como en el ejemplo, y repositorios locales bajo /srv, /mnt o /var en lugar de /home. Las lecturas se ejecutan una tras otra, dentro del límite de memoria del servicio (128 MiB con el propio agente).

Métricas, etiquetadas tool (restic o borg) y repo: agent_backup_repo_reachable (1 cuando la última lectura tuvo éxito, 0 en caso contrario: repositorio inaccesible, contraseña rechazada, binario faltante — el agente registra el motivo una vez, y de nuevo cuando cambia), agent_backup_repo_last_snapshot_age_seconds (antigüedad del snapshot más reciente, ausente mientras el repositorio está vacío), y agent_backup_repo_last_snapshot_bytes (bytes que procesó el snapshot restic más reciente, restic 0.17 y posteriores). Con --latest 1, restic devuelve el snapshot más reciente de cada host y conjunto de rutas; se conserva el más reciente de todos, así que define host en un repositorio compartido por varias máquinas.

Reglas integradas: restic/Borg backup too old (sin snapshot durante más de 48 horas) y restic/Borg repository unreachable (durante 30 minutos). La página del monitor muestra un panel Backup repositories, una línea por repositorio.

Para comprobar una declaración, ejecuta el agente una vez en primer plano y busca las muestras agent_backup_repo_*:

Ventana de terminal
sudo dumbmonit-agent --config /etc/dumbmonit/agent.yaml --dry-run

En una máquina que ejecuta WireGuard, el agente lee cada interfaz y cada peer con wg show all dump, en cada ciclo. Nada que configurar: sin el comando wg (wireguard-tools) o sin ninguna interfaz, no se emite ninguna serie y no se muestra ningún panel. wg necesita root (CAP_NET_ADMIN); el servicio instalado lo tiene, un agente iniciado a mano con tu propia cuenta registra el rechazo una vez y no reporta nada.

El dump también contiene la clave privada de la interfaz y la clave precompartida de cada peer: el agente omite ambos campos sin copiarlos nunca.

Por peer, etiquetado interface, peer (su clave pública) y allowed_ips: agent_wireguard_peer_handshake_age_seconds (segundos desde el último handshake), agent_wireguard_peer_has_handshake (0 mientras el peer nunca ha completado uno), agent_wireguard_peer_keepalive_seconds (su keepalive persistente, 0 cuando está desactivado), y los contadores agent_wireguard_peer_rx_bytes y agent_wireguard_peer_tx_bytes; por interfaz, agent_wireguard_interface_peers. Para un peer que nunca ha completado un handshake, la antigüedad se cuenta desde el momento en que el agente lo vio por primera vez: un túnel que nunca se levantó también está en silencio, y se reporta como tal.

WireGuard no tiene nombres de peer. Da los tuyos en agent.yaml, por clave pública, y se convierten en la etiqueta name:

wireguard: true # por defecto; false deja de mirar incluso así
wireguard_bin: wg # por defecto: en PATH
wireguard_peer_names:
"zonmO992nrIL4FgJ3B/wccmu/SBkoX2kDhSYr8KpgRU=": office-gateway
"UsKpqhrXNlYy/+rh2DLAOOEqesn8L8okEwNNorZ09lQ=": laptop

La regla integrada WireGuard peer silent se activa cuando un peer con keepalive persistente no ha completado un handshake durante más de 15 minutos. Mientras un túnel está levantado, WireGuard renueva su handshake cada dos minutos, y un keepalive lo mantiene levantado incluso sin tráfico; un peer sin keepalive (un teléfono, un portátil) puede estar inactivo durante días sin nada roto, así que se excluye. Define PersistentKeepalive = 25 en los túneles que deben permanecer levantados (enlaces sitio a sitio, gateways remotos). N es el umbral de la regla: cámbialo en Alerts → Rules, o elimina la parte and on (…) de su consulta para vigilar cada peer. La página del monitor muestra un panel WireGuard con cada peer, el tiempo desde su último handshake, su tráfico y su keepalive.

En una máquina que ejecuta strongSwan, el agente lee cada túnel configurado con dos comandos de solo lectura: swanctl --list-conns, para los CHILD_SA declarados en swanctl.conf (o ipsec.conf a través de swanctl --load-all, la capa de compatibilidad propia de strongSwan — al agente le da igual cuál escribió la configuración), y swanctl --list-sas, para los que están realmente instalados. Nada que configurar: sin el comando swanctl o sin ninguna conexión configurada, no se emite ninguna serie ni se muestra ningún panel. El agente nunca envía --initiate, --terminate ni ningún otro comando que cambie el estado de un túnel; solo lee lo que swanctl ya muestra en la línea de comandos.

Leer ambos comandos, y no solo el activo, es lo que permite que un túnel que nunca ha subido se informe como caído en lugar de invisible: un CHILD_SA declarado en la configuración pero ausente de --list-sas cuenta como caído desde el primer ciclo.

Por túnel, con las etiquetas connection (el nombre del IKE_SA) y tunnel (el nombre del CHILD_SA): agent_ipsec_tunnel_up (1 instalado, 0 en caso contrario) y, solo mientras está activo, los contadores agent_ipsec_tunnel_bytes_in / agent_ipsec_tunnel_bytes_out y agent_ipsec_tunnel_rekey_seconds (tiempo restante hasta el próximo rekey).

ipsec: true # por defecto; false deja de mirar incluso así
ipsec_bin: swanctl # por defecto: en PATH

La regla integrada IPsec tunnel down se activa cuando un túnel configurado no tiene ningún CHILD_SA instalado durante diez minutos. La página del monitor muestra un panel IPsec con cada túnel, activo o caído, su tráfico y el tiempo hasta su próximo rekey.

Desactivada por defecto: a diferencia de todo lo demás que mide el agente, esta prueba consume ancho de banda — y, en una conexión de pago por uso o con límite, dinero — cada vez que se ejecuta. Activarla requiere tanto speedtest: true como una dirección de descarga; sin la dirección, no se ejecuta nada aunque speedtest sea true.

No se elige ningún servidor por ti. DumbMonit no incluye un endpoint por defecto y nunca contacta con un tercero salvo que tú lo indiques: tú decides contra el servidor de quién se mide tu línea y quién ve la dirección del agente mientras se ejecuta.

La prueba es HTTP plano, de solo lectura en el otro extremo: un GET sobre speedtest_download_url, leído trozo a trozo y detenido en cuanto se han leído speedtest_download_bytes_cap bytes (50 MB por defecto, lo que termine primero), da la velocidad de descarga; un POST de speedtest_upload_bytes bytes (10 MB por defecto) a speedtest_upload_url, si está definida, da la velocidad de subida; un puñado de peticiones HEAD sobre la dirección de descarga dan la latencia (el viaje de ida y vuelta más corto) y el jitter (la dispersión entre el más corto y el más largo). Un servidor que rechaza HEAD simplemente deja la latencia y el jitter sin medir — el resto de la prueba no depende de ello.

Funciona con un backend LibreSpeed autohospedado (backend/garbage.php?ckSize=N para la descarga, backend/empty.php para la subida), con los endpoints de prueba de velocidad de Cloudflare (https://speed.cloudflare.com/__down?bytes=N y https://speed.cloudflare.com/__up, que cualquiera puede llamar sin cuenta), o con cualquier archivo HTTP plano y endpoint de subida propios — no hay ningún protocolo específico de proveedor que implementar, ni ninguna dependencia nueva más allá del cliente HTTP que el agente ya usa.

speedtest: false # por defecto: opt-in, esta prueba consume ancho de banda
speedtest_download_url: https://speed.cloudflare.com/__down?bytes=50000000
speedtest_upload_url: https://speed.cloudflare.com/__up
speedtest_download_bytes_cap: 50000000 # por defecto; se leen como máximo estos bytes
speedtest_upload_bytes: 10000000 # por defecto; enviados en un solo bloque
speedtest_interval_secs: 21600 # por defecto: 6 horas, mínimo 300
speedtest_min_download_mbps: 50 # opcional: activa "Internet download rate low"
speedtest_min_upload_mbps: 10 # opcional: activa "Internet upload rate low"
speedtest_max_latency_ms: 80 # opcional: activa "Internet latency high"

La prueba se ejecuta en segundo plano, como máximo una vez cada speedtest_interval_secs (6 horas por defecto, nunca menos de 300 segundos: un valor menor detiene el agente al arrancar); además se ejecuta una prueba unos segundos después de cada arranque del agente; el ciclo de recolección solo lee su último resultado, exactamente igual que las lecturas de restic/Borg y Plakar. agent_speedtest_ok vale 0 cuando falló la propia descarga (dirección inaccesible, timeout, error HTTP) — el único fallo que impide que la prueba mida nada en absoluto.

Las tres opciones de umbral son opcionales a propósito: sin speedtest_min_download_mbps, nadie en DumbMonit sabe qué significa «lento» para tu línea, así que Internet download rate low, Internet upload rate low e Internet latency high permanecen en silencio hasta que definas la que corresponda. Cada umbral se publica como su propia serie (agent_speedtest_download_min_bytes_per_second, etc.), que es con lo que las reglas integradas comparan la medición; cambia el umbral en agent.yaml, no en Alerts → Rules. La página del monitor muestra un panel de prueba de velocidad con la última velocidad de descarga y de subida, la latencia, el jitter y hace cuánto se ejecutó la prueba.

Certificados TLS (Certbot / Let’s Encrypt)

Sección titulada «Certificados TLS (Certbot / Let’s Encrypt)»

El agente no lee /etc/letsencrypt directamente. Cada certificado que renueva Certbot se sirve en algún sitio — un servidor web, un servidor de correo, un proxy inverso — y ahí es donde lo lee DumbMonit: añade un monitor de certificado TLS (o uno de sitio web o API web, para un sitio ya vigilado de esa forma) apuntado al puerto en el que realmente se presenta el certificado. Lee el certificado en vivo, no un archivo en disco, así que también detecta una renovación que tuvo éxito en /etc/letsencrypt pero que el servicio nunca recogió (un proxy inverso que necesita una recarga para ver el archivo nuevo es el caso habitual, y exactamente el hueco que importa).

Leer /etc/letsencrypt/live/*/cert.pem, la configuración de renovación y el registro de Certbot desde el agente se consideró y se descartó: duplicaría la fecha de caducidad que ya reporta el monitor TLS, mientras añade una segunda ruta, local al host, a la misma información — una cosa más que mantener sincronizada tras mover un certificado o renombrar un dominio. Un host donde se ejecuta Certbot pero que no sirve nada que DumbMonit pueda alcanzar directamente (un paso de CA interna, un hook de validación DNS) es el único caso que esto deja sin cubrir; también es el caso en el que un monitor TLS tampoco podría ayudar, ya que nada en ese host habla TLS para sondearse.