# DNS Service [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) A lightweight DNS management service written in C with a web-based interface for configuring DNS settings and managing dnsmasq configuration. ## Features - **Web Interface**: Modern responsive web UI for DNS configuration - **DNS Settings Management**: Configure upstream DNS servers, local domains, and cache settings - **DHCP Configuration**: Enable/disable DHCP with range configuration - **File Management**: Direct editing of configuration files - **SSL/TLS Support**: Optional HTTPS with certificate configuration - **JSON Configuration**: Easy-to-manage JSON-based configuration - **Cross-platform**: Supports multiple build systems (Make, CMake, Meson) ## Architecture The service consists of: - **HTTP/HTTPS Server**: Built on Mongoose web server - **REST API**: JSON-based API for configuration management - **Web Interface**: Bootstrap-based responsive UI - **Configuration Parser**: Custom dnsmasq config parser - **File Operations**: Safe file reading/writing utilities - **Settings Management**: Direct manipulation of dnsmasq configuration files - Updates dnsmasq main configuration (`/etc/dnsmasq.conf`) - Manages hosts file (`/etc/dnsmasq.conf.d/hosts`) - Manages resolv.conf (`/etc/dnsmasq.conf.d/resolv.conf`) - Automatically restarts dnsmasq service after configuration changes ## API Endpoints | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/settings` | Get current DNS settings | | POST | `/api/settings` | Update DNS settings (cache_size, resolv servers, hosts) and restart dnsmasq | | GET | `/api/settings/file` | Get raw configuration file | | POST | `/api/settings/file` | Update configuration file | | GET | `/#` | Serve web interface | ## Requirements ### Build Dependencies - GCC compiler with C23 support - OpenSSL development libraries - pthread library ### System Dependencies - dnsmasq (for DNS service functionality) - SSL certificates (for HTTPS support) - System initialization service (systemd, openrc, rc, finit, or init) - Appropriate privileges to restart system services ## Installation ### Using Make ```bash make ``` ### Using CMake ```bash mkdir build && cd build cmake .. make ``` ### Using Meson ```bash meson setup builddir meson compile -C builddir ``` ## Configuration Edit `config.json` to configure the service: ```json { "address": "0.0.0.0:8321", "tls_address": "0.0.0.0:8322", "web": "./web", "tls_enabled": true, "tls_cert": "/path/to/certificate.crt", "tls_key": "/path/to/private.key", "system_initialization": "systemd", "dnsmasq_config": "/etc/dnsmasq.conf" } ``` ### Configuration Parameters - `address`: HTTP server bind address and port - `tls_address`: HTTPS server bind address and port - `web`: Path to web interface files - `tls_enabled`: Enable/disable HTTPS support - `tls_cert`: Path to SSL certificate file - `tls_key`: Path to SSL private key file - `system_initialization`: System initialization type for restarting dnsmasq service - `"systemd"`: Uses `systemctl restart dnsmasq` - `"rc"` or `"openrc"`: Uses `rc restart dnsmasq` - `"finit"`: Uses `initctl restart dnsmasq` - `"init"`: Uses `/etc/init.d/dnsmasq restart` - `dnsmasq_config`: Path to dnsmasq configuration file ## Usage ### Starting the Service ```bash ./dns_service ``` The service will start HTTP server on the configured address (default: `0.0.0.0:8321`) and optionally HTTPS server if TLS is enabled. ### Web Interface Navigate to `http://localhost:8321` (or your configured address) to access the web interface where you can: - Configure upstream DNS servers (resolv) - Manage local domain mappings (hosts) - Enable/disable DHCP with range settings - Adjust DNS cache size - Edit configuration files directly - Save settings directly to dnsmasq configuration - Automatic dnsmasq service restart after configuration changes ### API Usage #### Get Current Settings ```bash curl -X GET http://localhost:8321/api/settings ``` #### Update Settings ```bash curl -X POST http://localhost:8321/api/settings \ -H "Content-Type: application/json" \ -d '{ "cache_size": 1000, "resolv": ["8.8.8.8", "8.8.4.4"], "hosts": { "192.168.1.1": "router.local", "192.168.1.100": ["server1.local", "server1"] } }' ``` The POST `/api/settings` endpoint accepts the following parameters: - `cache_size` (integer): DNS cache size for dnsmasq - `resolv` (array of strings): Upstream DNS servers - `hosts` (object): Local DNS mappings where keys are IP addresses and values are either single hostnames (string) or arrays of hostnames **Note**: After successfully updating the configuration files, the service automatically restarts dnsmasq to apply the changes. The restart method depends on the `system_initialization` setting in `config.json`. #### Settings Configuration Details **Cache Size (`cache_size`)** - Configures the DNS cache size in dnsmasq - Updates the `cache-size` parameter in `/etc/dnsmasq.conf` - Accepts integer values (recommended: 150-10000 depending on system resources) **Upstream DNS Servers (`resolv`)** - Array of DNS server IP addresses to use for upstream resolution - Creates/updates `/etc/dnsmasq.conf.d/resolv.conf` with `nameserver` entries - Example: `["8.8.8.8", "1.1.1.1", "8.8.4.4"]` **Local Hosts (`hosts`)** - Object mapping IP addresses to hostnames for local DNS resolution - Creates/updates `/etc/dnsmasq.conf.d/hosts` file - Supports both single hostnames and multiple hostnames per IP - Format: - Single hostname: `"192.168.1.1": "router.local"` - Multiple hostnames: `"192.168.1.100": ["server1.local", "server1"]` ## Development ### Project Structure ``` dns_service_c/ ├── src/ │ ├── lib/ # Third-party libraries │ │ ├── mongoose.c # HTTP server │ │ ├── cJSON.c # JSON parser │ │ └── ... │ ├── main.c # Application entry point │ ├── config.c # Configuration management │ ├── settings.c # DNS settings handlers (GET) │ ├── set_settings.c # DNS settings handlers (POST) │ ├── set_dnsmasq_settings_field.c # Update dnsmasq config fields │ ├── set_hosts.c # Manage hosts file │ ├── set_resolvs.c # Manage resolv.conf │ ├── restart_dnsmasq.c # Restart dnsmasq service │ ├── settings.h # Settings function declarations │ ├── restart_dnsmasq.h # Restart function declarations │ └── ... ├── web/ # Web interface files │ ├── index.html │ ├── css/ │ └── js/ ├── config.json # Service configuration └── README.md ``` ### Building for Development ```bash # With debug symbols make CFLAGS="-Wall -g -std=gnu2x -DDEBUG" # Clean build make clean && make ``` ### Code Style The project uses `.clang-format` for consistent code formatting: ```bash clang-format -i src/*.c src/*.h ``` ## Security Considerations - The service runs with system privileges to modify DNS configuration files - HTTPS is strongly recommended for production deployments - Ensure proper file permissions on certificate files - The service directly modifies system files (`/etc/dnsmasq.conf`, `/etc/dnsmasq.conf.d/hosts`, `/etc/dnsmasq.conf.d/resolv.conf`) - Consider firewall rules to restrict access to management interface - Validate all input data to prevent configuration file corruption - Backup configuration files before making changes - Ensure the service has appropriate write permissions to dnsmasq configuration directories - The service requires privileges to restart the dnsmasq service via system commands ## Troubleshooting ### Common Issues 1. **Permission denied when accessing dnsmasq config** - Ensure the service has read/write permissions to the dnsmasq configuration file - Run with appropriate privileges or adjust file permissions - Check permissions for `/etc/dnsmasq.conf.d/` directory 3. **Failed to write settings** - Verify write permissions to `/etc/dnsmasq.conf`, `/etc/dnsmasq.conf.d/hosts`, and `/etc/dnsmasq.conf.d/resolv.conf` - Ensure the `/etc/dnsmasq.conf.d/` directory exists - Check disk space availability 4. **Failed to restart dnsmasq** - Ensure the service has appropriate privileges to restart system services - Verify the `system_initialization` parameter in `config.json` matches your system - Supported initialization systems: rc, openrc, systemd, finit, init - Check that dnsmasq service is properly installed and configured on the system 5. **SSL/TLS certificate errors** - Verify certificate and key file paths in `config.json` - Ensure certificate files have correct permissions - Check certificate validity and format 6. **Port binding errors** - Verify ports are not already in use - Check firewall settings - Ensure proper privileges for binding to privileged ports 7. **Settings not persisting after dnsmasq restart** - Ensure dnsmasq is configured to read from `/etc/dnsmasq.conf.d/` directory - Verify the main dnsmasq configuration includes the conf-dir directive - Check that temporary files are properly cleaned up after configuration updates ### Logging The service uses Mongoose's built-in logging. Set log level in code or use debug build for verbose output. ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes following the existing code style 4. Test your changes thoroughly 5. Submit a pull request ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ### Third-party Libraries This project includes the following third-party libraries: - **Mongoose**: HTTP/WebSocket server library - **cJSON**: JSON parser library Please refer to their respective licenses for usage terms. ## Support For issues and questions, please check the project's issue tracker or documentation.