dns-monitor
Multi-provider DNS zone guard that detects accidental edits and hijacking across INWX and Cloudflare zones.
USP: the package never calls mutating API methods — drift detection is the compensating control for providers that offer no read-only role.
Installation
pip install dns-monitor # library only
pip install dns-monitor[cli] # + CLI and dotenv support
Providers
| Provider | Auth | Minimum permissions |
|---|---|---|
| INWX | username + password | Domain Management, DNS Management (no read-only role exists) |
| Cloudflare | API token | Zone:Read + DNS:Read |
Set credentials in .env (see .env.example) or export them directly:
export INWX_USERNAME=svc-monitor-inwx
export INWX_PASSWORD=...
export CF_API_TOKEN=...
CLI
dns-monitor zones # list all zones across configured providers
dns-monitor baseline # save current state as drift baseline
dns-monitor check # check guards and detect drift
dns-monitor check --policies my_policies.py # inject custom policies
Exit codes match violation severity: 0 = clean, 1 = MEDIUM, 2 = HIGH, 3 = CRITICAL.
Library usage
from dns_monitor.providers.inwx import InwxProvider
from dns_monitor.guards.policy import Policy
from dns_monitor.guards.predicates import is_address_record, has_public_ip
from dns_monitor.guards.runner import run_policies
from dns_monitor.model.severity import Severity
vpn_policy = Policy(
name="vpn-endpoints-must-be-public",
applies_to=lambda r: is_address_record(r) and r.name in VPN_HOSTNAMES,
require=has_public_ip,
severity=Severity.CRITICAL,
message="{type} {name} → {content} is non-public — VPN tunnel at risk",
)
with InwxProvider(username, password) as p:
for zone in p.list_zones():
records = p.get_records(zone)
violations = run_policies(records, [vpn_policy])
Drift detection
from dns_monitor.model import snapshot
from dns_monitor.guards.runner import run_drift
baseline = snapshot.load(Path("snapshots/latest.json"))
current = p.get_records(zone)
violations = run_drift(baseline.get(f"inwx:{zone}", []), current, zone=zone)
Records exempt from drift detection by default:
- A/AAAA with TTL ≤ 300 (DynDNS — expected to change with WAN IP)
_acme-challenge.*TXT records (transient ACME DNS-01 challenge)
Salt grains
Copy src/dns_monitor/contrib/salt_grains.py to /srv/salt/_grains/. The minion must have dns_monitor[cli] installed and INWX_USERNAME/INWX_PASSWORD in its environment.
Grain returned: dns_monitor.inwx_zones — list of zone names.
License
Apache 2.0
Release files for dns-monitor 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dns_monitor-0.1.1.tar.gz | 41.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dns_monitor-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 62.7 kB
Release files / dns_monitor-0.1.1.tar.gz
| Download URL | dns_monitor-0.1.1.tar.gz |
|---|---|
| Size | 41.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cf60c611d5031da2a73ac0fa2899f10b1172d7967f9e3834e3cce05296e10ac6
|
|
BLAKE2b-256 checksum How to use checksums |
7041f3ad3a5d7549ac4a3d2fe4361fcaa7e039a588c7cdc22e12c5cd64b07c16
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 30, 2026.
Transparency logRelease files / dns_monitor-0.1.1-py3-none-any.whl
| Download URL | dns_monitor-0.1.1-py3-none-any.whl |
|---|---|
| Size | 21.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
26338a3936c0cbaea5c1e60199665bdc4aff047d247bbc3e2ae6cfb93b3b0cf9
|
|
BLAKE2b-256 checksum How to use checksums |
82856706b83255467329e68da734505836c749f0ff17f15279f9fc87c0e175c9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 30, 2026.
Transparency log