# 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 1. Clone the repository: ```bash git clone cd dns_service ``` 2. Build the application: ```bash go build -o dns_service ``` 3. Install the binary: ```bash sudo cp dns_service /usr/bin/ sudo chmod +x /usr/bin/dns_service ``` 4. Create configuration directory: ```bash sudo mkdir -p /etc/dns_service ``` 5. Copy configuration files: ```bash 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`: ```bash # 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: ```bash # 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 ```bash curl -X GET http://localhost:8090/api/settings ``` **Response:** ```json { "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 ```bash 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 ```bash 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 ```bash 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 ```bash # Manual start sudo /etc/init.d/dns_service.service start # Or run directly sudo /usr/bin/dns_service ``` ### Stop the Service ```bash sudo /etc/init.d/dns_service.service stop ``` ### Restart the Service ```bash sudo /etc/init.d/dns_service.service restart ``` ### Check Service Status ```bash # 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 ```bash # 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 ```bash # 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 setup - `Run.go`: Server startup with TLS/HTTP support and error handling - **api/**: REST API endpoints and frontend serving - `settings.go`: DNS settings API endpoints - `settings_file.go`: Configuration file management endpoints - `spa.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:** 1. **Environment Setup**: `utils.LoadEnv()` loads configuration 2. **Server Configuration**: `server.Configure()` sets up routes 3. **Server Startup**: `server.Run()` starts the HTTP/HTTPS server 4. **API Handling**: Individual handlers process requests 5. **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:** ```go 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:** ```go // 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 1. Configure your local domains in the web interface 2. Set upstream DNS servers (Google DNS, Cloudflare, etc.) 3. Configure cache size based on your needs 4. Apply settings and restart dnsmasq ### Home Network Setup Perfect for home labs and local development environments: ```json { "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 ```json { "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 1. **Service won't start**: - Check configuration file syntax and permissions - Verify `/etc/dns_service/dns_service.conf` exists and is readable - Check if required directories exist 2. **TLS errors**: - Verify certificate files exist and have correct permissions - Check certificate validity dates - Ensure private key matches certificate 3. **Port conflicts**: - Ensure port 8090 is not in use by another service - Use `netstat -tlnp | grep 8090` to check port usage 4. **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: ```bash # Check service logs journalctl -u dns_service # Check dnsmasq logs journalctl -u dnsmasq # Check application logs tail -f /var/log/dns_service.log ``` ## Contributing 1. Fork the repository 2. Create a feature branch (`git checkout -b feature/amazing-feature`) 3. Commit your changes (`git commit -m 'Add some amazing feature'`) 4. Push to the branch (`git push origin feature/amazing-feature`) 5. 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.