DNS Service
A Go-based web frontend for managing dnsmasq DNS server configurations. This service provides a RESTful API and web interface for dynamically managing DNS settings, host mappings, and resolver configurations. The application features a modular architecture with separate packages for server management, API handling, and utility functions.
Features
- Web Interface: Clean, responsive frontend for managing DNS settings
- RESTful API: JSON-based API for programmatic configuration management
- Dynamic Configuration: Real-time updates to dnsmasq configuration
- Host Management: Easy management of hostname-to-IP mappings
- Resolver Configuration: Flexible DNS resolver settings
- TLS Support: Optional HTTPS/TLS encryption
- Service Integration: Systemd-compatible service management
- Cache Control: Configurable DNS cache size settings
- Modular Architecture: Clean separation of concerns with dedicated packages
- Error Handling: Comprehensive error handling and logging
Prerequisites
- Go 1.24.4 or higher
- dnsmasq installed and configured
- Linux system with systemd (for service management)
- SSL certificates (for TLS mode)
Installation
From Source
- Clone the repository:
git clone <repository-url>
cd dns_service
- Build the application:
go build -o dns_service
- Install the binary:
sudo cp dns_service /usr/bin/
sudo chmod +x /usr/bin/dns_service
- Create configuration directory:
sudo mkdir -p /etc/dns_service
- Copy configuration files:
sudo cp dns_service.conf /etc/dns_service/
sudo cp dns_service.service /etc/init.d/
sudo chmod +x /etc/init.d/dns_service.service
Configuration
Environment Variables
The service is configured via environment variables in /etc/dns_service/dns_service.conf:
# dnsmasq configuration file path
DNSMASQ_CONFIG=/etc/dnsmasq.conf
# TLS configuration
ENABLE_TLS=true
CERT_FILE=/etc/dns_service/dns.home.com.crt
KEY_FILE=/etc/dns_service/dns.home.com.key
# Server configuration
SERVER_ADDRESS=0.0.0.0
SERVER_PORT=8090
# System initialization type
SYSTEM_INITIALIZATION=rc
Configuration Parameters
| Parameter | Description | Default | Required |
|---|---|---|---|
DNSMASQ_CONFIG |
Path to dnsmasq configuration file | /etc/dnsmasq.conf |
Yes |
ENABLE_TLS |
Enable HTTPS/TLS encryption | false |
No |
CERT_FILE |
Path to SSL certificate file | - | If TLS enabled |
KEY_FILE |
Path to SSL private key file | - | If TLS enabled |
SERVER_ADDRESS |
Server bind address | 0.0.0.0 |
No |
SERVER_PORT |
Server port | 8090 |
No |
SYSTEM_INITIALIZATION |
Init system type | rc |
No |
TLS Setup
For TLS mode, ensure you have valid SSL certificates:
# Generate self-signed certificate (for testing)
sudo openssl req -x509 -newkey rsa:4096 -keyout /etc/dns_service/dns.home.com.key \
-out /etc/dns_service/dns.home.com.crt -days 365 -nodes
# Set proper permissions
sudo chmod 600 /etc/dns_service/dns.home.com.key
sudo chmod 644 /etc/dns_service/dns.home.com.crt
API Documentation
Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Web frontend interface |
GET |
/api/settings |
Get current DNS settings |
POST |
/api/settings |
Update DNS settings |
GET |
/api/settings/file |
Get raw dnsmasq configuration |
POST |
/api/settings/file |
Update raw dnsmasq configuration |
API Examples
Get Current Settings
curl -X GET http://localhost:8090/api/settings
Response:
{
"cache_size": 10000,
"hosts": {
"185.130.83.26": "gitea.home.com",
"192.168.3.1": "router.home.com",
"192.168.3.113": [
"samba.home.com",
"gitea.home.com",
"navidrome.home.com"
],
"192.168.3.119": [
"immich.home.com",
"jellyfin.home.com",
"portainer.home.com"
],
"192.168.3.155": "dns.home.com"
},
"resolv": [
"192.168.3.1",
"109.194.32.1",
"5.3.3.3",
"8.8.8.8"
]
}
Update Settings
curl -X POST -H "Content-Type: application/json" \
-d '{"cache_size": 15000, "hosts": {"192.168.1.100": "server.local"}, "resolv": ["8.8.8.8", "8.8.4.4"]}' \
http://localhost:8090/api/settings
Get Configuration File
curl -X GET http://localhost:8090/api/settings/file
Response:
resolv-file=/etc/dnsmasq.conf.d/resolv.conf
addn-hosts=/etc/dnsmasq.conf.d/hosts
cache-size=10000
Update Configuration File
curl -X POST -H "Content-Type: text/plain" \
-d "resolv-file=/etc/dnsmasq.conf.d/resolv.conf
addn-hosts=/etc/dnsmasq.conf.d/hosts
cache-size=15000" \
http://localhost:8090/api/settings/file
Service Management
Start the Service
# Manual start
sudo /etc/init.d/dns_service.service start
# Or run directly
sudo /usr/bin/dns_service
Stop the Service
sudo /etc/init.d/dns_service.service stop
Restart the Service
sudo /etc/init.d/dns_service.service restart
Check Service Status
# Check if process is running
ps aux | grep dns_service
# Check process ID
cat /var/run/dns_service.pid
Development
Project Structure
dns_service/
├── api/ # API handlers and frontend
│ ├── frontend/ # Web frontend assets
│ ├── settings.go # Settings API handler
│ ├── settings_file.go # Configuration file handler
│ └── spa.go # Single-page application handler
├── server/ # Server configuration and startup
│ ├── Configure.go # HTTP routes configuration
│ └── Run.go # Server startup and TLS handling
├── settings/ # Settings management
│ ├── get_settings.go # Get settings functionality
│ └── set_settings.go # Set settings functionality
├── utils/ # Utility functions
│ ├── LoadEnd.go # Environment loading utilities
│ ├── decode_hosts.go # Host parsing utilities
│ ├── decode_resolvs.go # Resolver parsing utilities
│ ├── decode_settings.go # Settings parsing utilities
│ ├── response_json.go # JSON response utilities
│ └── restart_dnsmasq.go # dnsmasq restart functionality
├── main.go # Application entry point
├── go.mod # Go module definition
├── go.sum # Go module checksums
├── dns_service.conf # Configuration file
├── dns_service.service # Init script
├── LICENSE # MIT License
└── README.md # This file
Building
# Build for current platform
go build -o dns_service
# Build for Linux (cross-compilation)
GOOS=linux GOARCH=amd64 go build -o dns_service
# Build with version information
go build -ldflags "-X main.version=1.0.0" -o dns_service
Testing
# Run tests
go test ./...
# Test with coverage
go test -cover ./...
# Test specific package
go test ./api
Dependencies
The project uses minimal external dependencies:
github.com/joho/godotenv- Environment variable loading from configuration files
Architecture
The application follows a clean modular architecture with clear separation of concerns:
- main.go: Application entry point that orchestrates startup sequence
- server/: Server configuration and HTTP handling
Configure.go: HTTP routes and middleware setupRun.go: Server startup with TLS/HTTP support and error handling
- api/: REST API endpoints and frontend serving
settings.go: DNS settings API endpointssettings_file.go: Configuration file management endpointsspa.go: Single-page application serving
- utils/: Shared utility functions and environment management
LoadEnd.go: Environment variable loading and validation- Various decode utilities for parsing DNS configurations
- settings/: DNS settings management and persistence
- Configuration reading and writing functionality
Modular Development Approach
The codebase is designed with modularity in mind:
Benefits:
- Maintainability: Each package has a single responsibility
- Testability: Individual components can be tested in isolation
- Reusability: Utility functions can be shared across packages
- Scalability: New features can be added without affecting existing code
- Code Organization: Clear structure makes onboarding easier
Development Workflow:
- Environment Setup:
utils.LoadEnv()loads configuration - Server Configuration:
server.Configure()sets up routes - Server Startup:
server.Run()starts the HTTP/HTTPS server - API Handling: Individual handlers process requests
- Settings Management: Dedicated package manages DNS configurations
Adding New Features:
- Add new API endpoints in
api/package - Implement business logic in appropriate packages
- Add utility functions in
utils/package - Update server configuration if needed
Code Examples
Basic Server Setup:
package main
import (
"dns_service/server"
"dns_service/utils"
)
func main() {
utils.LoadEnv() // Load environment variables
server.Configure() // Configure HTTP routes
server.Run() // Start the server
}
Adding Custom Middleware:
// In server/Configure.go
func Configure() {
// Add custom middleware
http.Handle("/", middleware(api.SpaHandler(http.FS(api.Frontend))))
http.HandleFunc("/api/settings", api.Settings)
http.HandleFunc("/api/settings/file", api.SettingsFile)
}
Usage Examples
Basic DNS Setup
- Configure your local domains in the web interface
- Set upstream DNS servers (Google DNS, Cloudflare, etc.)
- Configure cache size based on your needs
- Apply settings and restart dnsmasq
Home Network Setup
Perfect for home labs and local development environments:
{
"cache_size": 10000,
"hosts": {
"192.168.1.100": ["homelab.local", "api.homelab.local"],
"192.168.1.101": "nas.local",
"192.168.1.102": "router.local"
},
"resolv": ["192.168.1.1", "8.8.8.8", "1.1.1.1"]
}
Corporate/Enterprise Network Setup
{
"cache_size": 50000,
"hosts": {
"10.0.1.100": ["intranet.corp.local", "wiki.corp.local"],
"10.0.1.101": "mail.corp.local",
"10.0.1.102": "files.corp.local"
},
"resolv": ["10.0.1.1", "8.8.8.8"]
}
Security Considerations
- Always use TLS in production environments
- Restrict access to the management interface (firewall rules, VPN, etc.)
- Use strong SSL certificates from a trusted CA (avoid self-signed in production)
- Regularly update the service and dependencies
- Monitor logs for suspicious activity
- Consider firewall rules to limit access to port 8090
- Use strong file permissions on configuration files
- Regular security audits of the system configuration
Troubleshooting
Common Issues
-
Service won't start:
- Check configuration file syntax and permissions
- Verify
/etc/dns_service/dns_service.confexists and is readable - Check if required directories exist
-
TLS errors:
- Verify certificate files exist and have correct permissions
- Check certificate validity dates
- Ensure private key matches certificate
-
Port conflicts:
- Ensure port 8090 is not in use by another service
- Use
netstat -tlnp | grep 8090to check port usage
-
dnsmasq integration:
- Verify dnsmasq is installed and properly configured
- Check if dnsmasq service is running
- Verify dnsmasq configuration file paths
Logs
Check system logs for error messages:
# Check service logs
journalctl -u dns_service
# Check dnsmasq logs
journalctl -u dnsmasq
# Check application logs
tail -f /var/log/dns_service.log
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
For support and questions:
- Create an issue in the repository
- Check the documentation
- Review existing issues and discussions
Note: This service is designed to work with dnsmasq. Ensure dnsmasq is properly installed and configured before using this frontend.