A modern, web-based interface for managing multiple BIND DNS servers with comprehensive zone management and detailed service configuration.
- π₯οΈ Manage Multiple BIND Servers: Add unlimited DNS servers, switch between them with one click
- βοΈ BIND Service Configuration: Configure recursion, forwarding, caching, access control, and more
- π― Server-Specific Settings: Each server has independent BIND options and zone configurations
- π Automatic Migration: Legacy single-server configs automatically migrate to multi-server format
- π Separate Pages: "Edit Connection" for server setup, "BIND Config" for service settings
- Manage unlimited BIND DNS servers from a single interface
- Quick server switching with active server selection
- Independent configuration for each server
- Automatic legacy configuration migration
- οΏ½ Auto-Discovery: Zones and zone files automatically detected from named.conf
- π― Zone Selector: Easy dropdown to switch between different DNS zones
- β Add new DNS records (A, AAAA, CNAME, MX, TXT, NS, etc.)
- βοΈ Edit existing DNS records
- ποΈ Delete DNS records
- β
Automatic zone validation with
named-checkzone
- β‘ Zone reload via
rndc
after changes - πΎ Remembers your last selected zone
- Recursion & Forwarding: Configure recursive DNS with upstream forwarders (Google, Cloudflare, etc.)
- Caching: Set TTLs for positive and negative responses
- Access Control: Define allow-query and allow-recursion ACLs
- DNSSEC: Enable validation for enhanced security
- Rate Limiting: Configure query limits and client connections
- Logging: Enable query logging for troubleshooting
- Network Settings: Configure IPv4/IPv6 listen addresses
- π¨ Modern, responsive web interface with dark mode
- π Advanced search and filtering by record type
- οΏ½ Secure SSH authentication (key-based or password)
- π Real-time BIND installation progress
- π³ Docker support for easy deployment
Server β BIND Options β DNS Zones β DNS Records
- Server Level: Connection settings, BIND service options
- Zone Level: Zone configurations per server
- Record Level: DNS records within each zone
- Main Page (
/
): Manage zones and records for active server - Manage Servers (
/servers.html
): Add, edit, activate servers - BIND Config (
/bind-options.html
): Configure BIND service settings per server - Edit Connection (
/settings.html
): Edit server connection details
See ARCHITECTURE.md and PAGE_STRUCTURE.md for detailed documentation.
The easiest way to run BIND DNS Manager is using Docker:
docker run -d -p 5000:5000 \
-e BIND_HOST=your-dns-server.com \
-e BIND_USER=root \
-e BIND_SSH_KEY=/root/.ssh/id_rsa \
-e BIND_CONFIG_PATH=/etc/bind/named.conf \
-v ~/.ssh/id_rsa:/root/.ssh/id_rsa:ro \
--name bind-dns-manager \
yourusername/bind-dns-gui:latest
Then open http://localhost:5000
in your browser. The application will automatically discover all zones from your BIND configuration.
- Backend: Python Flask REST API connecting via SSH to BIND server
- Frontend: Vanilla HTML/CSS/JavaScript with zone selector
- Authentication: SSH key-based or password authentication
- DNS Management: Direct zone file manipulation with validation and reload
- Zone Discovery: Automatic parsing of named.conf and included configuration files
βββββββββββββββββββ
β Web Browser β
ββββββββββ¬βββββββββ
β HTTP
βΌ
βββββββββββββββββββ
β Flask Server β
ββββββββββ¬βββββββββ
β SSH (Paramiko)
βΌ
βββββββββββββββββββ
β BIND Server β
β ββ Zone Files β
β ββ rndc β
β ββ named-check β
βββββββββββββββββββ
- Python 3.11 or higher (for local development)
- Docker (optional, for containerized deployment)
- BIND DNS Server with SSH access
- SSH Credentials (private key or password)
- BIND Server Requirements:
- SSH access to the server
- Read/write permissions to zone files
- Ability to execute
named-checkzone
command - Ability to execute
rndc reload
command
- Generate an SSH key pair (if you don't have one):
ssh-keygen -t rsa -b 4096 -f ~/.ssh/bind_dns_key
- Copy your public key to the BIND server:
ssh-copy-id -i ~/.ssh/bind_dns_key.pub user@your-bind-server.com
- Test the connection:
ssh -i ~/.ssh/bind_dns_key user@your-bind-server.com
Simply use your SSH username and password in the configuration.
The SSH user needs proper permissions on the BIND server:
# On your BIND server, ensure the user can read zone files
sudo usermod -a -G bind your-ssh-user
# Set proper permissions on zone files
sudo chmod 640 /etc/bind/zones/db.example.com
sudo chown root:bind /etc/bind/zones/db.example.com
# Test if user can read zone files
cat /etc/bind/zones/db.example.com
# Test if user can run rndc
rndc reload example.com
# Pull the latest image
docker pull yourusername/bind-dns-gui:latest
# Run with environment variables (SSH key authentication)
docker run -d \
--name bind-dns-manager \
-p 5000:5000 \
-e BIND_HOST=dns.example.com \
-e BIND_PORT=22 \
-e BIND_USER=root \
-e BIND_SSH_KEY=/root/.ssh/id_rsa \
-e BIND_CONFIG_PATH=/etc/bind/named.conf \
-v ~/.ssh/id_rsa:/root/.ssh/id_rsa:ro \
yourusername/bind-dns-gui:latest
# Or use password authentication
docker run -d \
--name bind-dns-manager \
-p 5000:5000 \
-e BIND_HOST=dns.example.com \
-e BIND_USER=root \
-e BIND_PASSWORD=your-password \
-e BIND_CONFIG_PATH=/etc/bind/named.conf \
yourusername/bind-dns-gui:latest
# Or use a .env file
docker run -d \
--name bind-dns-manager \
-p 5000:5000 \
--env-file .env \
-v ~/.ssh/id_rsa:/root/.ssh/id_rsa:ro \
yourusername/bind-dns-gui:latest
All zones configured in your BIND server will be automatically discovered and available in the zone selector dropdown.
# Clone the repository
git clone https://github.com/awkto/bind-frontend.git
cd bind-frontend
# Build the image
docker build -t bind-dns-manager .
# Run the container
docker run -d -p 5000:5000 \
--env-file .env \
-v ~/.ssh/id_rsa:/root/.ssh/id_rsa:ro \
bind-dns-manager
Create a docker-compose.yml
:
version: '3.8'
services:
bind-dns-manager:
image: yourusername/bind-dns-gui:latest
container_name: bind-dns-manager
ports:
- "5000:5000"
environment:
- BIND_HOST=${BIND_HOST}
- BIND_PORT=${BIND_PORT:-22}
- BIND_USER=${BIND_USER}
- BIND_SSH_KEY=${BIND_SSH_KEY}
- DNS_ZONE=${DNS_ZONE}
- ZONE_FILE_PATH=${ZONE_FILE_PATH}
volumes:
- ~/.ssh/id_rsa:/root/.ssh/id_rsa:ro
restart: unless-stopped
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:5000/api/health')"]
interval: 30s
timeout: 10s
retries: 3
Then run:
docker-compose up -d
git clone https://github.com/awkto/bind-frontend.git
cd bind-frontend
pip install -r requirements.txt
Copy the example environment file and fill in your BIND server details:
cp .env.example .env
Edit .env
with your values:
# BIND Server Connection
BIND_HOST=dns.example.com
BIND_PORT=22
BIND_USER=root
# Authentication (choose ONE)
BIND_SSH_KEY=/root/.ssh/id_rsa
# BIND_PASSWORD=your-ssh-password
# BIND Configuration (zones will be auto-discovered)
BIND_CONFIG_PATH=/etc/bind/named.conf
Important: Never commit the .env
file to version control!
Note: The application will automatically discover all zones from your BIND configuration file. You no longer need to specify individual zone names or file paths.
python test_connection.py
python app.py
The application will start on http://localhost:5000
Open your web browser and navigate to:
http://localhost:5000
When you first access the application:
- If BIND credentials are not configured, you'll be automatically redirected to the Settings page
- Enter your BIND server connection details:
- BIND Server Host: Hostname or IP address of your DNS server
- SSH Port: SSH port (default: 22)
- SSH User: Username with access to BIND zone files
- SSH Private Key Path: Path to SSH key OR password
- DNS Zone: Domain name (e.g., example.com)
- Zone File Path: Full path to zone file (e.g.,
/etc/bind/zones/db.example.com
)
- Click Test Connection to verify your credentials
- Click Save Configuration to persist the settings
- You'll be redirected to the main page with your DNS records
To update your BIND server credentials later:
- Click the βοΈ Settings button in the header
- Update the required fields
- Test and save the new configuration
All configuration can be provided via environment variables (useful for Docker):
BIND_HOST=dns.example.com
BIND_PORT=22
BIND_USER=root
BIND_SSH_KEY=/root/.ssh/id_rsa
# BIND_PASSWORD=your-password
DNS_ZONE=example.com
ZONE_FILE_PATH=/etc/bind/zones/db.example.com
The main page displays all DNS records from your BIND zone file in a table format showing:
- Record name and FQDN
- Record type (A, AAAA, CNAME, MX, TXT, NS, etc.)
- TTL (Time To Live)
- Record values
-
Click Add New Record button
-
Fill in the form:
- Record Name: Enter the subdomain name (e.g.,
www
,mail
) or@
for the root domain - Record Type: Select from A, AAAA, CNAME, MX, or TXT
- TTL: Set Time To Live in seconds (default: 3600)
- Values: Enter record values (one per line)
- For A records: IP addresses (e.g.,
192.168.1.1
) - For AAAA records: IPv6 addresses
- For CNAME: Target domain (e.g.,
target.example.com
) - For MX: Priority and exchange (e.g.,
10 mail.example.com
) - For TXT: Text values (e.g.,
v=spf1 include:_spf.google.com ~all
)
- For A records: IP addresses (e.g.,
- Record Name: Enter the subdomain name (e.g.,
-
Click Add Record
-
The zone file will be validated and reloaded automatically
- Click the βοΈ Edit button next to any record
- Modify the TTL or values in the modal dialog
- Click Update Record
- Zone will be validated and reloaded
Note: Update/Delete functionality is partially implemented. For now, you may need to edit the zone file directly for complex changes.
- Click the ποΈ Delete button next to any record
- Confirm the deletion in the dialog
Note: Delete functionality returns 501 (coming soon). Use the BIND server directly for deletions.
Click the π Refresh button in the header to reload all records from the BIND server.
The backend provides the following REST API endpoints:
Method | Endpoint | Description |
---|---|---|
GET | /api/health |
Health check and zone info |
GET | /api/config/status |
Check if configuration is complete |
GET | /api/config |
Get current configuration (masked) |
POST | /api/config |
Save BIND server configuration |
POST | /api/config/test |
Test BIND server connection |
GET | /api/records |
List all DNS records from zone file |
POST | /api/records |
Create a new DNS record |
PUT | /api/records/<type>/<name> |
Update a DNS record (501 - coming soon) |
DELETE | /api/records/<type>/<name> |
Delete a DNS record (501 - coming soon) |
bind-frontend/
βββ static/
β βββ index.html # Main DNS records page
β βββ settings.html # Configuration page
β βββ app.js # Main page JavaScript
β βββ settings.js # Settings page JavaScript (needs update)
β βββ styles.css # Modern CSS with dark mode
βββ app.py # Flask backend with SSH/BIND integration
βββ test_connection.py # Connection test script
βββ requirements.txt # Python dependencies (paramiko, dnspython)
βββ Dockerfile # Docker image definition
βββ docker-compose.yml # Docker Compose configuration
βββ .dockerignore # Docker build exclusions
βββ .env.example # Example environment variables
βββ .env # Your configuration (not in git)
βββ .gitignore # Git ignore rules
βββ CONVERSION_SUMMARY.md # Conversion notes from DigitalOcean
βββ README.md # This file
β οΈ This application does not include user authentication for the web interface- π SSH credentials are stored in environment variables (never commit
.env
to git) - π SSH key-based authentication is strongly recommended over passwords
- π By default, the app runs on all interfaces (
0.0.0.0
) - consider restricting this in production - π Ensure your SSH user has minimal required permissions
- π« Do not expose this application directly to the internet without proper security measures
- π‘οΈ Consider using a reverse proxy (nginx/traefik) with authentication
- π All zone changes are validated with
named-checkzone
before applying - π Failed zone validations are rejected to prevent breaking DNS
Container won't start
# Check container logs
docker logs bind-dns-manager
# Check if port is already in use
netstat -an | grep 5000 # Linux/Mac
netstat -ano | findstr :5000 # Windows
SSH key mount issues
# Ensure SSH key has correct permissions
chmod 600 ~/.ssh/id_rsa
# Check if key is mounted correctly in container
docker exec bind-dns-manager ls -la /root/.ssh/
Configuration not persisting
- For Docker: Use environment variables or mount a volume for the .env file
docker run -d -p 5000:5000 -v $(pwd)/.env:/app/.env bind-dns-manager
"Module not found" errors
pip install -r requirements.txt
"Missing required environment variables" error
Make sure you've created a .env
file with all required values or configured via the Settings page.
"Authentication failed" error
- Verify SSH credentials are correct
- Test SSH connection manually:
ssh -i /path/to/key user@host
- Ensure SSH key has correct permissions (600)
- Check if password authentication is enabled on server if using password
"Zone file not found" error
- Verify the zone file path is correct on the BIND server
- Check if SSH user has read permissions to the zone file
- Common locations:
- Debian/Ubuntu:
/etc/bind/zones/db.example.com
- RHEL/CentOS:
/var/named/example.com.zone
- Debian/Ubuntu:
"Permission denied" when updating records
- SSH user needs write permissions to zone files
- User must be able to execute
rndc reload
- Consider adding user to
bind
group:sudo usermod -a -G bind your-user
"named-checkzone command not found"
- Ensure BIND is installed on the server
- Verify the SSH user's PATH includes BIND binaries
- Try full path:
/usr/sbin/named-checkzone
- Check that the application is running on port 5000
- Verify no firewall is blocking the connection
- Try accessing via
http://127.0.0.1:5000
instead
- Update/Delete records: Currently returns 501 (Not Implemented)
- Records can be added, but updates/deletes require zone file editing
- Full implementation coming in future release
- SOA Serial: Serial number is not automatically incremented
- Manual increment required after changes
- Single Zone: Currently supports one zone at a time
- Multi-zone support planned for future
- No DNSSEC UI: DNSSEC records can be viewed but not managed via UI
- Complete update/delete record functionality
- Auto-increment SOA serial number on changes
- Multi-zone support (manage multiple domains)
- DNSSEC record management
- Zone file backup before changes
- Change history and audit logging
- User authentication and authorization
- HTTPS/TLS support
- Batch operations
- Record import/export (CSV, JSON, BIND format)
- Zone transfer functionality
- Support for views and split-horizon DNS
- Kubernetes deployment manifests
- Webhook notifications for changes
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature
) - Commit your changes (
git commit -m 'Add some AmazingFeature'
) - Push to the branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
This project is open source and available under the MIT License.
- Built with Flask
- SSH connectivity via Paramiko
- DNS parsing with dnspython
- Inspired by the need for a modern BIND management interface
- π Documentation
- π Issue Tracker
- π¬ Discussions
Note: This is primarily a development/management tool. For production use, implement proper security measures including user authentication, HTTPS, access controls, and consider running it on an isolated management network.