No description
  • Python 90.2%
  • Makefile 6.5%
  • Dockerfile 3.3%
Find a file
François Schmidts de6af7a1f6
All checks were successful
Docker / lint (push) Successful in 29s
Docker / push (push) Successful in 5m50s
release 1.1.0
2026-03-17 14:29:43 +01:00
.claude refactor(livebox): replace monolithic capabilities with per-item list 2026-03-02 20:30:06 +01:00
.forgejo/workflows chore(ci): quiet docker buildx output in CI 2026-03-03 11:48:18 +01:00
grafana feat(grafana): add Grafana dashboard 2026-03-02 15:29:15 +01:00
wan_monitor fix(gateway): recreate session each crawl loop 2026-03-17 14:29:30 +01:00
.gitignore feat: initial wan-monitor implementation 2026-02-26 10:42:53 +01:00
CLAUDE.md fix(collectors): handle None values from sysbus API 2026-02-26 15:02:40 +01:00
Dockerfile feat(build): add multi-arch Docker build support 2026-02-27 16:51:42 +01:00
Makefile chore(ci): quiet docker buildx output in CI 2026-03-03 11:48:18 +01:00
poetry.lock chore(deps): bump the-conf to 1.1.2 2026-02-27 15:15:02 +01:00
project_vars.mk chore(build): default REGISTRY to WAN_MONITOR_REGISTRY env var 2026-02-26 11:46:22 +01:00
pyproject.toml release 1.1.0 2026-03-17 14:29:43 +01:00
README.md feat(ci): add Forgejo Actions workflow and release target 2026-03-03 11:24:51 +01:00

wan-monitor

Monitor WAN IP changes on an Orange Livebox gateway and get notified via Telegram, email, or any Apprise-supported service.

Queries the Livebox sysbus API directly (no authentication required) to detect changes in both IPv4 address and IPv6 delegated prefix.

Includes a Prometheus exporter (default :9100) exposing WAN status and, when gateway authentication is configured, DSL line stats, interface traffic, and device info.

Configuration

Configuration is loaded from environment variables or JSON files (in order):

  • ~/.config/wan-monitor.json
  • /etc/wan-monitor/wan-monitor.json

Example

{
    "alias": "Home Livebox",
    "gateway": {
        "url": "http://192.168.1.1",
        "password": "my-livebox-password"
    },
    "notificationurls": [
        "tgram://BOT_TOKEN/CHAT_ID",
        "mailto://user:pass@smtp.example.com"
    ],
    "loop": {
        "interval": 300
    },
    "prometheus": {
        "port": 9100,
        "namespace": ""
    },
    "logging": {
        "level": "INFO"
    }
}

Parameters

Parameter Default Description
alias (required) Location name shown in notifications
gateway.url http://192.168.1.1 Livebox gateway URL
gateway.password (empty) Livebox admin password; enables authenticated metrics when set
notificationurls (required) List of Apprise notification URLs
loop.interval 300 Polling interval in seconds
prometheus.port 9100 Prometheus metrics HTTP port
prometheus.namespace (empty) Prefix for all metric names
prometheus.url (empty) Prometheus base URL; seeds WAN state on startup to avoid false change notifications after restarts
prometheus.filters (empty) PromQL label matchers for seeding (e.g. job="wan-monitor")
api.port 8000 HTTP API port
logging.level WARNING Log level (DEBUG, INFO, WARNING, ERROR, FATAL)

Apprise URL examples

  • Telegram: tgram://BOT_TOKEN/CHAT_ID
  • Email (SMTP): mailto://user:pass@smtp.example.com
  • Gotify: gotify://hostname/token
  • ntfy: ntfy://topic

See the full list at https://github.com/caronc/apprise/wiki

Prometheus Metrics

Always available (no authentication)

Metric Type Labels Description
wan_link_up Gauge 1 if WAN link is up, 0 otherwise
wan_info Info ipv4, ipv6_address, ipv6_prefix, link_type WAN connection information

With authentication (gateway.password set)

DSL stats (NeMo/Intf/dsl0:getDSLStats):

Metric Type Labels Description
dsl_sync_rate_kbps Gauge direction DSL sync rate in kbps
dsl_snr_db Gauge direction Signal-to-noise ratio in dB
dsl_attenuation_db Gauge direction Line attenuation in dB
dsl_errors_total Gauge type Error counters — crc: frames with checksum mismatch (data corruption), fec: errors corrected by forward error correction (noisy line), hec: corrupted ATM cell headers, errored_seconds: one-second intervals containing at least one error

Interface traffic (NeMo/Intf/<iface>:getStats):

Metric Type Labels Description
interface_bytes_total Gauge interface, direction Bytes transferred (tx/rx)
interface_packets_total Gauge interface, direction Packets transferred (tx/rx)
interface_errors_total Gauge interface Error count
interface_discards_total Gauge interface Packets dropped by the interface (buffer overflows, QoS policies, rate limiting)

Interfaces monitored: data, eth0, wl0.

Device info (DeviceInfo:get, Hosts:getDevices):

Metric Type Labels Description
device_uptime_seconds Gauge Device uptime in seconds
device_info Info model, firmware, serial Device information
connected_devices Gauge Number of active connected devices

Usage

Local

pip install wan-monitor
python -m wan_monitor

Docker

docker run -v ~/.config/:/etc/wan-monitor/:ro \
    -p 8000:8000 -p 9100:9100 \
    wan-monitor:latest

HTTP API

The API server (default :8000) exposes management endpoints. Prometheus metrics are served separately on :9100.

Endpoint Port Method Description
/metrics 9100 GET Prometheus metrics
/test-notification 8000 POST Send a test notification to all configured URLs
# Test notification setup
curl -X POST http://localhost:8000/test-notification

How it works

  1. Starts a Prometheus HTTP server on the configured port
  2. Queries the Livebox sysbus API at POST <gateway>/sysbus/NMC:getWANStatus
  3. Extracts IPAddress (IPv4) and IPv6DelegatedPrefix from the response
  4. Updates Prometheus metrics with current WAN status
  5. If authenticated, collects DSL stats, interface traffic, and device info
  6. Compares WAN IPs against previously stored state
  7. On change, sends a notification with old and new values
  8. Saves new state and sleeps until next check

Build

make build

Release

Bump the version, commit, and tag in one step:

make release
git push && git push --tags

Docker tags

Trigger Tags
Push to main :latest
Semver tag (e.g. 1.2.3) :v1, :v1.2, :v1.2.3
Other tag :{tag}

CI/CD

The Forgejo Actions workflow (.forgejo/workflows/docker.yaml) runs linting and pushes Docker images on every push to main or any tag.

Repository configuration

Name Type Description
DOCKER_REGISTRY Variable Registry URL (e.g. registry.example.com/user)
DOCKER_USERNAME Secret Registry username
DOCKER_PASSWORD Secret Registry password/token