Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

domain-watchtower

License: MIT Python 3.10+ systemd

Daily monitoring for domain expiry, trademark expiry, and DNS/SSL drift. One Python service, one systemd timer, one daily summary email. Replaces three separate paid SaaS tools.

Born from running 40+ domains and 12+ trademarks at Die Netzhandwerker. Combines patterns from three internal tools (Verfallswache, Markenwacht, DailyWatch) into one open package.

What it watches

Check What it catches Tool replaced
Domain WHOIS expiry A domain you forgot is expiring next month DomainTools, $50/mo
Trademark expiry (DPMAregister, EUIPO, USPTO) IP-protected name expiring or contested Markify, $30/mo
SSL certificate expiry A subdomain cert silently expired UptimeRobot, $7/mo
DNS record drift A registrar changed your nameservers or your DNSSEC (DIY)
New TXT records Someone added an SPF/DMARC entry behind your back (DIY)
Whois owner change Domain was transferred or hijacked (DIY)

You get one mail per day (default 06:00 UTC) summarizing what changed.

Quickstart

git clone https://github.com/netzhandwerker/domain-watchtower.git
cd domain-watchtower
sudo ./install.sh

Edit /etc/domain-watchtower/watchlist.yml:

domains:
  - name: example.com
    checks: [expiry, ssl, dns, txt]
    alert_days: [60, 30, 14, 7, 3, 1]
  - name: example.de
    checks: [expiry, ssl]
    alert_days: [60, 14, 1]

trademarks:
  - name: "Example"
    register: dpma  # dpma | euipo | uspto
    id: "302024123456"
    alert_days: [180, 90, 30]

alert:
  to: ops@example.com
  smtp_host: localhost
  smtp_port: 25

Enable the daily run:

sudo systemctl enable --now domain-watchtower.timer

You'll get the first report tomorrow at 06:00 UTC.

Architecture

              ┌─────────────────────────────┐
              │   /etc/domain-watchtower/   │
              │   watchlist.yml             │
              └────────────┬────────────────┘
                           │
              ┌────────────▼────────────────┐
              │   watchtower.py             │
              │                             │
              │   ┌──────────────────────┐  │
              │   │ checks/whois.py      │──┼──→ python-whois
              │   │ checks/ssl.py        │──┼──→ openssl s_client
              │   │ checks/dns.py        │──┼──→ dnspython
              │   │ checks/txt.py        │──┼──→ dnspython
              │   │ checks/trademark.py  │──┼──→ DPMA/EUIPO/USPTO
              │   └──────────────────────┘  │
              │                             │
              │   State diff against        │
              │   /var/lib/domain-watch...  │
              └────────────┬────────────────┘
                           │
              ┌────────────▼────────────────┐
              │   Daily summary mail        │
              │   (only sent if changes)    │
              └─────────────────────────────┘

State is kept in /var/lib/domain-watchtower/state.json. On first run there's no baseline — second run onwards detects diffs.

Sample alert

Subject: [domain-watchtower] 3 alerts on 2026-05-20

DOMAIN EXPIRY
  example.de       expires in  14 days  (2026-06-03)
  oldsite.com      expires in   3 days  (2026-05-23)  *** URGENT ***

TRADEMARK EXPIRY
  "Example" (DPMA 302024123456)  expires in 87 days

SSL EXPIRY
  api.example.com  cert expires in  9 days  (2026-05-29)

DNS / TXT CHANGES
  example.com    NEW TXT record: "v=spf1 include:_spf.mailerlite.com ~all"
                 (was: "v=spf1 include:_spf.google.com ~all")

DRIFT
  example.de    nameservers changed:
                old: ns1.registrar-a.com, ns2.registrar-a.com
                new: ns1.registrar-b.com, ns2.registrar-b.com

Configuration reference

See examples/watchlist.full.yml for all available options.

What this is not

  • Not a registrar — it watches your domains, you renew them yourself
  • Not a legal monitor — for actual trademark litigation use a real IP lawyer
  • Not real-time — daily resolution by design (cron-friendly)
  • Not a registrar webhook handler — pull-based via public WHOIS / RDAP

Modules included

The repo combines three previously-separate tools:

  • Verfallswache — domain expiry monitoring with daily alerts
  • Markenwacht — German DPMA trademark expiry monitor (extended to EUIPO + USPTO)
  • DailyWatch — DNS/SSL/TXT drift detection with state diff

All three are now subcommands of a single CLI.

License

MIT.

Author

Built by Daniel Wesseling at Die Netzhandwerker. In daily production use against 40+ domains and 12+ trademarks since 2025.

About

Daily monitoring for domain expiry, trademark expiry, SSL, and DNS drift. One Python service, one systemd timer, one daily summary email.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages