Secure, version-controlled DNS management tool with CLI and GUI
Project description
DNSCTL is a local infrastructure tool for managing Cloudflare DNS records safely. It brings a Git-backed state model, drift detection, and a plan/apply workflow to DNS — so you always know what changed, when, and why.
It ships as both a CLI for scripting and automation, and a GUI for interactive use — both powered by the same reconciliation engine.
How it works
1. sync Pull live DNS records from Cloudflare into local state
2. edit Add, edit, or delete records locally (no live changes yet)
3. plan Preview exactly what will be pushed to Cloudflare
4. apply Push the confirmed changes
5. history Every change auto-committed to a local Git repo
No change touches Cloudflare until you explicitly apply it.
✨ Features
- Drift Detection — Spot out-of-band dashboard changes before they cause issues
- Plan / Apply Workflow — Review a diff before any record is touched
- Git-Backed History — Every sync and edit auto-committed; full rollback support
- Secure Token Storage — AES-256-GCM encrypted, key derived via PBKDF2, stored in OS keyring
- Session Locking — Token cached in memory, auto-expires after inactivity
- Multi-Account — Manage multiple Cloudflare accounts; one master password unlocks all
- Protected Records — System-level (NS) and user-defined guards that require
--forceto override - CLI + GUI Parity — Every feature available in both interfaces
📦 Installation
From PyPI (macOS / Linux / Windows)
pip install dnsctl-app
Requires Python 3.11+ and Git. On Linux, ensure a keyring backend is available (e.g.
gnome-keyringorkwallet).
Windows Installer
Download the bundled installer from the Releases page.
Includes both CLI (dnsctl.exe) and GUI (dnsctl-g.exe) with all dependencies — no Python required.
From Source
git clone https://github.com/dhivijit/dnsctl.git
cd dnsctl
pip install -e .
🚀 Quick Start
1. Add your Cloudflare account
dnsctl login
You'll be prompted for an account name, your Cloudflare API token, and a master password. The token is encrypted and stored in your OS keyring — never in plaintext.
2. Unlock your session
dnsctl unlock
Decrypts the token into a short-lived session. One password unlocks all your accounts at once.
3. Pull your DNS records
dnsctl sync
4. Make a local change
dnsctl add --type A --name staging.example.com --content 1.2.3.4
Nothing is sent to Cloudflare yet.
5. Review the plan
dnsctl plan
6. Apply
dnsctl apply
🖥 GUI
Launch the graphical interface:
dnsctl-g
Features:
- Zone selector with drift status indicator
- Record table with add / edit / delete dialogs
- Sync, Plan, and Apply controls
- History viewer and rollback
- Multi-account switcher
- Session unlock dialog
The GUI uses the same reconciliation engine as the CLI — no feature gap between them.
🧰 CLI Reference
Authentication
dnsctl login # Add a Cloudflare account (encrypted)
dnsctl unlock # Unlock session with master password
dnsctl lock # Lock session manually
dnsctl logout # Remove stored credentials for current account
Sync & Status
dnsctl sync [-z ZONE] # Pull records from Cloudflare
dnsctl status # Show accounts, zones, and session state
dnsctl diff [-z ZONE] # Show drift between local state and Cloudflare
dnsctl plan [-z ZONE] # Preview what apply would push
dnsctl apply [-z ZONE] # Push planned changes to Cloudflare
Record Management
dnsctl add --type A --name sub.example.com --content 1.2.3.4
dnsctl edit --type A --name sub.example.com --content 5.6.7.8
dnsctl rm --type A --name sub.example.com
Protected Records
dnsctl protect --type A --name example.com --reason "Critical root record"
dnsctl unprotect --type A --name example.com
dnsctl protected
History & Rollback
dnsctl log
dnsctl rollback <commit_sha>
Import / Export
dnsctl export [-z ZONE] [-o output.json]
dnsctl import zone.json
Account Management
dnsctl accounts list
dnsctl accounts switch <alias>
dnsctl accounts remove <alias>
👥 Multi-Account Support
DNSCTL supports multiple Cloudflare accounts side by side, each with isolated zone state.
# Add accounts
dnsctl login # prompts for account name + token + password
dnsctl login --label "Work" # with explicit label
# Switch between accounts
dnsctl accounts list
dnsctl accounts switch work
# Remove an account
dnsctl accounts remove personal
All accounts share a single master password. Unlocking one automatically unlocks all others in the same session.
🔐 Security Model
Token storage
- API token encrypted with AES-256-GCM
- Encryption key derived via PBKDF2-HMAC-SHA256 (200,000 iterations)
- Encrypted blob stored in the OS keyring (Windows Credential Manager / macOS Keychain / Linux Secret Service)
- Plaintext token held in memory only for the duration of the session, then discarded
Session
- Session expires automatically after inactivity (default: 15 minutes)
dnsctl lockexpires the session immediatelydnsctl logoutremoves all stored credentials for an account
Protected records
Two layers:
- System-protected — NS records are always protected
- User-defined — mark any record with
dnsctl protect; requires--forceto override in apply
🤝 Contributing
Pull requests are welcome. For larger changes, open an issue first to discuss the approach.
git clone https://github.com/dhivijit/dnsctl.git
cd dnsctl
pip install -e ".[dev]"
pytest
📜 License
MIT License — © Dhivijit
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dnsctl_app-1.1.1.tar.gz.
File metadata
- Download URL: dnsctl_app-1.1.1.tar.gz
- Upload date:
- Size: 81.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70133cc0a9b6a699751653ac52a335d422e332c3fdad0bee2afbe5634c4d79dc
|
|
| MD5 |
c0896cd24f0e8862dfee6ffc6e095c7a
|
|
| BLAKE2b-256 |
13de72403abd56174f106e460c86466972689ace6bd4c6e759db900173423471
|
File details
Details for the file dnsctl_app-1.1.1-py3-none-any.whl.
File metadata
- Download URL: dnsctl_app-1.1.1-py3-none-any.whl
- Upload date:
- Size: 81.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f6800d7f209d64495df79a70ed6cc5cfb7895269e9fd2818ab356db3c524d2ac
|
|
| MD5 |
cfde27124f08bca984e71611aa76339d
|
|
| BLAKE2b-256 |
91f8a305b4140f35b955873c7de5a01179de405f59c3844e42d2bd938452c9b0
|