- Python 77%
- JavaScript 9.3%
- Jinja 8.3%
- CSS 4.6%
- Dockerfile 0.8%
| .github/workflows | ||
| .vscode | ||
| lib | ||
| static | ||
| templates | ||
| tests | ||
| zoneforge | ||
| .gitignore | ||
| .pylintrc | ||
| .python-version | ||
| app.py | ||
| Dockerfile | ||
| eslint.config.js | ||
| LICENSE | ||
| pyproject.toml | ||
| pytest.ini | ||
| README.md | ||
| stylelint.config.js | ||
| uv.lock | ||
ZoneForge
ZoneForge is a web UI and REST API to manage RFC1035/BIND style DNS zone files.
About
ZoneForge provides a web-based interface and REST API for managing DNS records efficiently. Rather than re-inventing an entire DNS server, ZoneForge serves as a management layer for RFC1035/BIND-style DNS zone files. This project is ideal for administrators who require:
- A centralized, user-friendly tool to manage DNS records.
- Robust REST API.
- Deployment flexibility for various environments.
Zone files are a commonly supported standard for serving authoritative DNS zone records, such as in BIND, NSD, and CoreDNS's file plugin. While these DNS servers are highly-perfomant and lightweight, they often lack user-friendly management tools, which is where ZoneForge comes in.
Table of Contents
Demo
A public demo, with sample data, is currently deployed here. It runs the latest released Docker image (polled every 15 minutes).
Many replicas are deployed, load balanced with session affinity. Instances are torn down nightly to reset the container.
Installation
Deployment using the published Docker image is preferred, as it is tested and includes setup for using Gunicorn as a production WSGI server. Deploy it via Docker/Docker Compose/Kubernetes. Simple usage might look like:
docker run -d --rm \
-e ZONE_FILE_FOLDER=/etc/zones \
-v /path/to/zonefiles:/etc/zones \
-p 5000:5000 \
ghcr.io/holysoles/zoneforge:latest
Local installation should work as well. Check the Dockerfile for the latest targeted Python version.
With UV
git clone https://github.com/holysoles/zoneforge.git
cd zoneforge
uv run --no-dev --group prod gunicorn app:production --bind 0.0.0.0:5000 --workers 4
With pip
git clone https://github.com/holysoles/zoneforge.git
cd zoneforge
python -m venv .venv
source .venv/bin/activate
pip install -r requirements/prod.txt
gunicorn app:production --bind 0.0.0.0:5000 --workers 4
Configuration
Environment variables are available to configure the application. Additional information about Gunicorn configuration can be found here.
| Variable | Default | Description |
|---|---|---|
| ZONE_FILE_FOLDER | "./lib/examples" |
The folder path to store/load zone files. |
| DEFAULT_ZONE_TTL | 86400 |
The default TTL for new zones. |
| LOG_LEVEL | "WARNING" |
Log level for the application. Options: ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] |
| PORT | 5000 |
Port for the web server to listen on. |
| GUNICORN_WORKERS | 4 |
How many worker processes to use for Gunicorn. |
| GUNICORN_CMD_ARGS | "--bind 0.0.0.0:\${PORT} --workers \${GUNICORN_WORKERS}" |
The command line arguments to pass Gunicorn. |
REST API
Overview
- Zones: Create, Read, Update, Delete
- Records: Create, Read, Update, Delete
- EOL comments are supported in the
commentparameter in record related requests. - Note that deprecated DNS record types are not supported by ZoneForge.
- EOL comments are supported in the
- Record Type Info: Read
- Server Status: Read
Documentation
For comprehensive examples, check out the Swagger/OpenAPI (v2.0) documentation here! You can also import the spec into Postman.
This documentation is also available in local instances /api.
Web UI
The web UI is written with a focus on being lightweight for ease of maintenance and speed. This is accomplished with Flask templating and server-side rendering whenever possible, with minimal client side javascript with no external dependencies.
Feature Roadmap
| Feature | Status |
|---|---|
| Web Interface | |
| CRUD for DNS Zones | Complete |
| CRUD for DNS Records | Complete |
| Client side validation | Planned |
| REST API | |
| CRUD for DNS Zones | Complete |
| CRUD for DNS Records | Complete |
| Thread Safety for DNS Record CRUD | Backlog |
| Zone Name Mutability | Backlog |
| Patch Method for DNS Zones | Backlog |
| Patch Method for DNS Records | Backlog |
| Management | |
| Authentication | In Progress |
| Zone Import/Export | Backlog |
| Preserve Default Zone TTL | Backlog |
| CI/CD | |
| Docker Image | Complete |
| Test Suite | Complete |
| Package for PyPi/pip | Backlog |
| CoreDNS Kubernetes Integration | Backlog |
Resources
Zone Files
- Zone File Validator by @woodjme
- DYN
- Oracle
Record Types
RFCs
Migrating Existing DNS to a Zone File
For each domain that a given DNS server is authorative for:
-
First ensure that the zone is enabled for Zone transfer. For Windows DNS, this can be found by right-clicking the Zone -> Properties -> Zone Transfers.
-
Install
digon a unix-like system -
Find the name servers if necessary:
dig example.com -t ns -
Initiate the Zone Transfer:
dig axfr example.com @dns.example.com | grep -E -v '^;' > db.example.com -
The file
db.example.comshould now contain a RFC1035-compatible zone file.
Contributing
Contributions are welcome. Please follow conventional commit syntax.
uv is recommended to use for downloading dependencies and managing your virtual environment.
uv run black .
uv run pylint $(git ls-files '*.py' | grep -v dnspython)
uv run pytest
With pip
Install requirements for a dev environment with: pip install -r requirements/dev.txt.
Please note that linting and unit tests are run against Pull Requests. It is recommended you test at least the Python related jobs before committing:
black .
pylint $(git ls-files '*.py' | grep -v dnspython)
pytest
For GitHub Actions, pin-github-action is used to resolve tag refs to commit hashes
Credits
Special thanks to the following projects for providing essential libraries:
