No description
  • Go 85.8%
  • Python 12.7%
  • Dockerfile 1.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Renfrew County Scanner 8c3d51b020
All checks were successful
Build and release / linux (push) Successful in 2m19s
Build and release / windows (push) Successful in 2m16s
Build and release / release (push) Successful in 1m39s
Verify bound peer outages never use another interface
2026-10-28 08:19:00 -04:00
.gitea/workflows Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00
docs Verify bound peer outages never use another interface 2026-10-28 08:19:00 -04:00
scripts Verify bound peer outages never use another interface 2026-10-28 08:19:00 -04:00
.dockerignore Add remote ICMP agent with Windows service and Docker releases 2026-10-28 05:25:23 -04:00
.gitignore Add remote ICMP agent with Windows service and Docker releases 2026-10-28 05:25:23 -04:00
binding.go Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00
binding_linux.go Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00
binding_linux_test.go Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00
binding_other.go Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00
binding_other_test.go Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00
binding_test.go Verify bound peer outages never use another interface 2026-10-28 08:19:00 -04:00
binding_windows.go Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00
binding_windows_test.go Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00
compose.yaml Add remote ICMP agent with Windows service and Docker releases 2026-10-28 05:25:23 -04:00
config.example.yaml Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00
config.go Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00
Dockerfile Add remote ICMP agent with Windows service and Docker releases 2026-10-28 05:25:23 -04:00
go.mod Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00
go.sum Add remote ICMP agent with Windows service and Docker releases 2026-10-28 05:25:23 -04:00
main.go Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00
monitor.go Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00
monitor_test.go Add remote ICMP agent with Windows service and Docker releases 2026-10-28 05:25:23 -04:00
README.md Add optional per-target NIC binding on Linux and Windows 2026-10-28 08:16:16 -04:00

Kuma Remote Monitor

Ping machines on a remote network and send their status and response time to Uptime Kuma. Run one agent on a Windows machine or in a Linux Docker container, with a separate Kuma push monitor for each IP address.

The agent checks ICMP reachability. It does not collect CPU, memory, disk, or application health data. A machine that blocks ICMP can appear down even when its applications work.

Downloads and requirements

Download ready-to-run files from Releases:

File Use
kuma-remote-monitor-windows-amd64.zip Windows x64 executable, sample config.yaml, and README
kuma-remote-monitor-linux-amd64 Linux executable for Intel/AMD 64-bit machines
kuma-remote-monitor-linux-arm64 Linux executable for ARM64 machines
SHA256SUMS SHA-256 checksums of the release downloads

For Docker, use git.uberplex.ca/renfrewcountyscanner/kuma-remote-monitor:latest, or pin a published version such as :v0.1.4. The image supports Linux amd64 and arm64. Go is not required to run the downloads or container.

You need an existing Uptime Kuma installation, permission to create push monitors, and network access from the agent to both the target IPs and Kuma. Windows service installation requires administrator access. Docker instructions below assume Linux Docker Engine and the Docker Compose plugin (docker compose). No inbound port is opened by the agent.

1. Set up Uptime Kuma

  1. Create and enable a monitor with type Push for each IP you want to check.
  2. Copy each monitor's push URL. Each target must report to its own monitor; do not share a push URL between agents.
  3. With the agent's default 60-second checks, set Kuma's heartbeat interval to 90 seconds or more to allow time for probes and delivery. For other check intervals, set Kuma's interval longer than the agent's interval, with additional margin for delays.
  4. Configure notifications in Kuma if you want alerts.

The agent sends up or down, a status message, and average response time in milliseconds when replies are received. The push token in the URL is the credential; Kuma's administrator login is not needed by the agent. Keep your configuration file private.

2. Configure targets

Save the following as config.yaml, or edit the sample configuration. Replace the example addresses and push URLs with your own:

defaults:
  interval: 60s
  count: 3
  timeout: 2s
  failure_threshold: 1

targets:
  - name: server
    ip: 192.168.1.10
    push_url: "https://kuma.example.com/api/push/REPLACE_TOKEN_1"
  - name: router
    ip: 192.168.1.1
    push_url: "https://kuma.example.com/api/push/REPLACE_TOKEN_2"

The full URL copied from Kuma may include ?status=up&msg=OK&ping=. You can keep that query string: the agent replaces those three values on each report. Use the final HTTP or HTTPS push endpoint; redirects and URLs containing a username or password are rejected. HTTPS requires a certificate trusted by the agent; there is no app flag to disable certificate verification or load a custom CA file.

Every target needs a unique, nonempty name, an IPv4 or IPv6 address in ip, and a push_url. Hostnames, including localhost and host.docker.internal, are not accepted in ip. Use a plain IPv6 address without brackets; scoped addresses such as fe80::1%eth0 are not supported.

The following settings can be placed under defaults or directly inside a target to override its defaults:

Setting Built-in default Meaning
interval 60s Intended time between the start of successive checks for that target
count 3 Number of ICMP echo requests per check, from 1 to 100
timeout 2s Spacing between requests; the total probe time budget is count × timeout
failure_threshold 1 Consecutive failed checks before reporting down

Durations use units such as 500ms, 2s, or 1m. Omitted or zero-valued settings inherit defaults. Effective settings must be positive, and count × timeout must not exceed interval. Unknown fields and invalid configuration stop the agent at startup.

Checks start immediately when the agent runs. Any reply makes a check successful; partial packet loss remains up. A check fails if there are no replies or a local ICMP error occurs. Recovery is reported after the next successful check. Targets run independently, and checks for a single target never overlap. If a check and push take longer than the interval, the next check starts after they finish.

With failure_threshold greater than 1, the agent keeps reporting up during failures below the threshold if it has previously received replies. It omits latency for those failed checks. Before the first successful check, it sends nothing until the failure threshold is reached. Counters reset when the agent restarts. Kuma can still mark a monitor down independently if heartbeats stop arriving.

Optional interface binding

Starting with v0.2.0, add interface to an individual target to send that target's pings through a specific NIC. Omit it, or use interface: "", to let the operating system select its normal route. Existing configurations keep working without changes. Binding is per target, not a setting under defaults.

You can check the same IP through multiple NICs. Give each entry a different name and push URL:

targets:
  - name: internet-via-first-nic
    ip: 1.1.1.1
    interface: eth0
    push_url: "https://kuma.example.com/api/push/REPLACE_TOKEN_1"
  - name: internet-via-second-nic
    ip: 1.1.1.1
    interface: eth1
    push_url: "https://kuma.example.com/api/push/REPLACE_TOKEN_2"
  - name: internet-via-default-route
    ip: 1.1.1.1
    push_url: "https://kuma.example.com/api/push/REPLACE_TOKEN_3"

Use the exact local interface name. List available names and addresses without needing a configuration file:

# Docker: lists the interfaces visible inside a new container.
docker run --rm git.uberplex.ca/renfrewcountyscanner/kuma-remote-monitor:latest -list-interfaces

# Native Linux:
./kuma-remote-monitor-linux-amd64 -list-interfaces

On Windows, run .\kuma-remote-monitor.exe -list-interfaces and use the displayed name, for example interface: "Ethernet" or interface: "Ethernet 2".

The selected NIC needs a suitable IP address of the same address family as the target and a usable route to it. The agent selects a local source address on that NIC and pins the ping socket to the NIC; it does not add or change routes or choose a gateway for you. For routed destinations, configure the appropriate routes and gateways in the operating system first.

If the NIC is missing, down, has no suitable address, or cannot reach the target, that check fails and follows failure_threshold. It never silently retries using another NIC. Other targets continue running. NICs and their addresses are checked again on each cycle, so a restored NIC can recover without restarting the agent. -check validates the configuration syntax but does not verify NIC availability or routing.

Only ICMP probes are bound. HTTP/HTTPS reports to Kuma still use the operating system's normal route, so an outage on the monitored NIC need not prevent reporting it through another working connection.

Docker and physical NICs: the normal Compose bridge exposes container interfaces, not the host's physical NIC names. On native Linux, use network_mode: host under the monitor service if you need to select physical host NICs. Keep NET_RAW. You can inspect that network's names with:

docker run --rm --network host git.uberplex.ca/renfrewcountyscanner/kuma-remote-monitor:latest -list-interfaces

Other Docker networking setups can also expose multiple container NICs; bind using the names visible inside that container. Docker Desktop's host networking does not provide the same direct access to Windows NICs. Use the native Windows app to select Windows adapters.

Run with Docker

Create a working directory and download the Compose file and configuration example:

mkdir kuma-remote-monitor
cd kuma-remote-monitor
curl -fL -o compose.yaml https://git.uberplex.ca/renfrewcountyscanner/kuma-remote-monitor/raw/branch/main/compose.yaml
curl -fL -o config.example.yaml https://git.uberplex.ca/renfrewcountyscanner/kuma-remote-monitor/raw/branch/main/config.example.yaml
cp config.example.yaml config.yaml

Edit config.yaml using the configuration instructions above before continuing. Keep it in the same directory as compose.yaml.

Validate the configuration, then start the agent:

docker compose run --rm monitor -config /etc/kuma-remote-monitor/config.yaml -check
docker compose up -d
docker compose logs -f monitor

-check validates the file without pinging or sending data. A valid file does not prove that a target or push URL is reachable. Look for check reported in the runtime logs, then confirm the corresponding monitor in Kuma receives data. Ctrl+C exits the log viewer; the background container keeps running.

The supplied Compose file mounts configuration read-only, grants the NET_RAW capability needed for ICMP, and restarts the container unless you stop it. Docker logs rotate at 10 MB, with up to three files.

Choosing the target IP: 127.0.0.1 and ::1 inside the container refer to the container itself. To check the Docker host, use the host's LAN IP. To check another device, use that device's reachable LAN IP. The sample's 127.0.0.1 target checks only the container, so change it if you intend to monitor the host. IPv6 requires working IPv6 routing in Docker. On native Linux, adding network_mode: host under the monitor service lets loopback refer to the host instead.

Apply configuration changes by recreating the container:

docker compose up -d --force-recreate

Upgrade the image with:

docker compose pull
docker compose up -d

If you pin a version in compose.yaml, change that tag before upgrading. Stop the agent with docker compose down; this does not delete your configuration file.

Run on Windows

Download and extract kuma-remote-monitor-windows-amd64.zip into a permanent directory, such as C:\Program Files\KumaRemoteMonitor. The ZIP includes a sample config.yaml; the app's default configuration location is under ProgramData, not beside the executable.

Open PowerShell as Administrator, then create the configuration directory and copy the sample on a fresh installation:

Set-Location "C:\Program Files\KumaRemoteMonitor"
New-Item -ItemType Directory -Force "$env:ProgramData\KumaRemoteMonitor"
Copy-Item .\config.yaml "$env:ProgramData\KumaRemoteMonitor\config.yaml"
notepad "$env:ProgramData\KumaRemoteMonitor\config.yaml"

Replace the sample targets and push URLs, save the file, and close the editor before continuing. Preserve any existing configuration when upgrading.

Validate the file, install the service, and start it:

.\kuma-remote-monitor.exe -check
.\kuma-remote-monitor.exe -service install
.\kuma-remote-monitor.exe -service start
Get-Service KumaRemoteMonitor

Continue with installation only after validation prints Configuration valid. The service is named KumaRemoteMonitor, runs as LocalSystem, and is configured to start automatically at boot. It has no desktop or tray interface. Keep its executable in the directory where you installed the service.

View service logs with:

Get-Content "$env:ProgramData\KumaRemoteMonitor\logs\agent.log" -Tail 20 -Wait

Logs rotate at 10 MB, retaining up to three backups with a 14-day age limit. Restrict write access to the executable and configuration to administrators. The service needs permission to send ICMP and reach Kuma through any firewall.

For a custom configuration location, supply its absolute path during validation and installation:

.\kuma-remote-monitor.exe -config "C:\Monitoring\config.yaml" -check
.\kuma-remote-monitor.exe -config "C:\Monitoring\config.yaml" -service install

That path is saved in the service registration; service logs go under a logs directory beside that configuration. To change a registered configuration path, stop and uninstall the service, then install it again with the new path.

To test interactively, stop any installed service first, then run:

.\kuma-remote-monitor.exe -config "$env:ProgramData\KumaRemoteMonitor\config.yaml"

Foreground mode writes to the console. Ctrl+C stops it. Do not run the service and foreground process against the same push monitors at the same time.

After editing configuration, restart the service:

Restart-Service KumaRemoteMonitor

To upgrade, stop the service, replace the executable with the new release, and start it again. Keep your existing configuration:

.\kuma-remote-monitor.exe -service stop
# Replace kuma-remote-monitor.exe with the new executable here.
.\kuma-remote-monitor.exe -service start

To remove the service:

.\kuma-remote-monitor.exe -service stop
.\kuma-remote-monitor.exe -service uninstall

Run a Linux binary without Docker

Download the binary matching your CPU from Releases, place it beside your config.yaml, and make it executable. For amd64:

chmod +x kuma-remote-monitor-linux-amd64
./kuma-remote-monitor-linux-amd64 -config ./config.yaml -check
sudo ./kuma-remote-monitor-linux-amd64 -config ./config.yaml

For ARM64, substitute kuma-remote-monitor-linux-arm64. Raw ICMP needs root or an appropriately configured CAP_NET_RAW capability. This command runs in the foreground and writes logs to the terminal; Ctrl+C stops it. Linux service installation is not provided by the app's -service commands. Docker Compose provides the documented option for running unattended on Linux.

Troubleshooting

Symptom Check
Configuration is rejected File path, YAML indentation, IP literals, unique target names, and timing constraints. Run -check with the same path used by the service/container.
probe error or no ICMP replies Target IP, network route, firewall rules, ICMP permissions, and any configured interface name and address family. Docker needs NET_RAW; native Linux needs root or equivalent capabilities.
push connection failed Reachability from the agent to Kuma, DNS for the push URL, certificate trust, and whether the request exceeds the 10-second delivery timeout.
push HTTP status ... Exact push URL, active Kuma monitor, reverse proxy rules, and authentication requirements. Redirects are not followed.
Kuma rejected push response The URL must reach Kuma's push endpoint and return its JSON success response, rather than a login page or another service.
Windows service will not start Validate the registered configuration file and run the executable interactively with that path to see startup errors. Errors before service logging initializes may not appear in agent.log.
Kuma reports missing heartbeats Agent/service status, delivery errors, and Kuma's heartbeat interval. Leave enough margin beyond the agent's check interval.

Failed deliveries are logged and the agent tries again with the next fresh check. It does not queue or replay old results. Stopping the agent stops pushes; Kuma can mark monitors down when their heartbeat allowance expires. This also means an agent-to-Kuma network outage cannot be distinguished from an agent failure using a missing push alone.

-list-interfaces lists local NIC names, flags, and IP addresses without loading configuration. -version prints the agent version. Changes to configuration take effect after restarting the process, Windows service, or container.

Building from source

See the maintainer build and release guide. The online README has the current installation instructions.