Author: Rubem Swensson
Co-Authors: ChatGPT + Codex
- 2026-05-17: Added optional generic No-IP DDNS records for independent IP exposure.
- 2026-05-17: Preserved consolidated previous public IP in DUC hook updates.
- 2026-05-17: Preserved previous public IP and ISP as the last different network state.
- 2026-05-17: Persisted status before optional DUC restart to avoid reentrant duplicate IP change events.
- 2026-05-17: Added DNS-based public IP detection fallback.
- 2026-05-17: Added known ISP names cache for ISP detection before WHOIS lookup.
- 2026-05-17: Made WHOIS ISP matching tolerant of accent and encoding differences.
- 2026-05-17: Added optional WHOIS-based ISP detection fallback.
- 2026-05-17: Renamed visible project references to multi-WAN.
- 2026-05-17: Initial GitHub-ready project structure, monitor, API, systemd units, installer, and documentation.
noip-multiwan-monitor monitors the current public IP of a multi-WAN network and compares it with the IP currently published in DNS for a No-IP hostname. It is designed for a Debian host running No-IP DUC 3.x and a router where the active WAN can change during failover.
The first version focuses on reliable observation:
- checks the current public IP every minute through a systemd timer;
- resolves the No-IP hostname through DNS;
- writes a consolidated status file for Home Assistant and troubleshooting;
- appends relevant events to an audit-friendly history log;
- exposes plain text and JSON HTTP endpoints;
- prepares optional DUC restart behavior, disabled by default.
- reuses the installed No-IP DUC and its existing secrets file instead of managing credentials.
config/ Example configuration
scripts/ Monitor, DUC hook, startup writer, and manual consistency check
api/ Lightweight Python HTTP API
systemd/ Service and timer units
docs/ Architecture, Home Assistant, and migration notes
install/ Conservative installer
Default runtime paths are configured in /etc/noip-monitor.conf:
/var/lib/noip/status.txt
/var/lib/noip/history.log
The status file uses simple KEY=value lines:
HOSTNAME=realswensson.ddns.net
CURRENT_PUBLIC_IP=187.59.12.49
PUBLISHED_DNS_IP=187.59.12.49
DNS_STATUS=OK
NOIP_DDNS_01_NAME=primary
NOIP_DDNS_01_HOSTNAME=realswensson.ddns.net
NOIP_DDNS_01_PUBLIC_IP=187.59.12.49
NOIP_DDNS_02_NAME=main
NOIP_DDNS_02_HOSTNAME=realswensson-main.ddns.net
NOIP_DDNS_02_PUBLIC_IP=187.59.12.49
NOIP_DDNS_03_NAME=backup
NOIP_DDNS_03_HOSTNAME=realswensson-bkp.ddns.net
NOIP_DDNS_03_PUBLIC_IP=189.101.176.64
CURRENT_ISP=Claro
PREVIOUS_PUBLIC_IP=179.x.x.x
PREVIOUS_ISP=Vivo
LAST_CHECK=2026-05-17T20:15:00-03:00
LAST_IP_CHANGE=2026-05-17T20:13:42-03:00
LAST_DUC_HOOK_UPDATE=2026-05-17T20:13:50-03:00
LAST_DUC_RESTART_TRIGGER=
Default API port: 8085.
GET /noipreturns the status file as plain text.GET /noip.jsonreturns the same status as JSON.GET /history?lines=50returns the last history lines.GET /healthreturns a simple health payload.
On the Debian host:
sudo ./install/install.sh
sudo nano /etc/noip-monitor.conf
sudo systemctl status noip-monitor.timer
sudo systemctl status noip-api.serviceThe installer creates backups with cp -p before replacing existing installed files. It does not modify an existing noip-duc.service; use systemd/noip-duc.service.example as a reference.
The project does not install No-IP DUC and does not copy or rewrite its secrets. Keep the existing DUC environment file, usually:
/etc/noip-duc.env
The example DUC unit keeps using that file through EnvironmentFile=/etc/noip-duc.env.
DUC restart is intentionally disabled by default:
ENABLE_DUC_RESTART="false"After validating monitoring, history, DNS consistency, and API behavior, it can be enabled by setting:
ENABLE_DUC_RESTART="true"
DUC_SERVICE_NAME="noip-duc.service"
DUC_ENV_FILE="/etc/noip-duc.env"
DUC_BINARY="/usr/bin/noip-duc"