1 parent
49f6415c30
commit
f01755caa8
5 files changed
+168
-42
No files matched your search
@@ -1,6 +1,6 @@
|
|||||||
# DNS Service
|
# 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.
|
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
|
## Features
|
||||||
|
|
||||||
@@ -12,6 +12,8 @@ A Go-based web frontend for managing dnsmasq DNS server configurations. This ser
|
|||||||
- **TLS Support**: Optional HTTPS/TLS encryption
|
- **TLS Support**: Optional HTTPS/TLS encryption
|
||||||
- **Service Integration**: Systemd-compatible service management
|
- **Service Integration**: Systemd-compatible service management
|
||||||
- **Cache Control**: Configurable DNS cache size settings
|
- **Cache Control**: Configurable DNS cache size settings
|
||||||
|
- **Modular Architecture**: Clean separation of concerns with dedicated packages
|
||||||
|
- **Error Handling**: Comprehensive error handling and logging
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@@ -226,10 +228,14 @@ dns_service/
|
|||||||
│ ├── settings.go # Settings API handler
|
│ ├── settings.go # Settings API handler
|
||||||
│ ├── settings_file.go # Configuration file handler
|
│ ├── settings_file.go # Configuration file handler
|
||||||
│ └── spa.go # Single-page application 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
|
├── settings/ # Settings management
|
||||||
│ ├── get_settings.go # Get settings functionality
|
│ ├── get_settings.go # Get settings functionality
|
||||||
│ └── set_settings.go # Set settings functionality
|
│ └── set_settings.go # Set settings functionality
|
||||||
├── utils/ # Utility functions
|
├── utils/ # Utility functions
|
||||||
|
│ ├── LoadEnd.go # Environment loading utilities
|
||||||
│ ├── decode_hosts.go # Host parsing utilities
|
│ ├── decode_hosts.go # Host parsing utilities
|
||||||
│ ├── decode_resolvs.go # Resolver parsing utilities
|
│ ├── decode_resolvs.go # Resolver parsing utilities
|
||||||
│ ├── decode_settings.go # Settings parsing utilities
|
│ ├── decode_settings.go # Settings parsing utilities
|
||||||
@@ -240,6 +246,7 @@ dns_service/
|
|||||||
├── go.sum # Go module checksums
|
├── go.sum # Go module checksums
|
||||||
├── dns_service.conf # Configuration file
|
├── dns_service.conf # Configuration file
|
||||||
├── dns_service.service # Init script
|
├── dns_service.service # Init script
|
||||||
|
├── LICENSE # MIT License
|
||||||
└── README.md # This file
|
└── README.md # This file
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -273,7 +280,78 @@ go test ./api
|
|||||||
|
|
||||||
The project uses minimal external dependencies:
|
The project uses minimal external dependencies:
|
||||||
|
|
||||||
- `github.com/joho/godotenv` - Environment variable loading
|
- `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
|
## Usage Examples
|
||||||
|
|
||||||
@@ -286,7 +364,7 @@ The project uses minimal external dependencies:
|
|||||||
|
|
||||||
### Home Network Setup
|
### Home Network Setup
|
||||||
|
|
||||||
Perfect for home labs and local development:
|
Perfect for home labs and local development environments:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -300,7 +378,7 @@ Perfect for home labs and local development:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Corporate Network Setup
|
### Corporate/Enterprise Network Setup
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -316,21 +394,37 @@ Perfect for home labs and local development:
|
|||||||
|
|
||||||
## Security Considerations
|
## Security Considerations
|
||||||
|
|
||||||
- Always use TLS in production environments
|
- **Always use TLS in production environments**
|
||||||
- Restrict access to the management interface
|
- **Restrict access to the management interface** (firewall rules, VPN, etc.)
|
||||||
- Use strong SSL certificates from a trusted CA
|
- **Use strong SSL certificates from a trusted CA** (avoid self-signed in production)
|
||||||
- Regularly update the service and dependencies
|
- **Regularly update the service and dependencies**
|
||||||
- Monitor logs for suspicious activity
|
- **Monitor logs for suspicious activity**
|
||||||
- Consider firewall rules to limit access
|
- **Consider firewall rules to limit access** to port 8090
|
||||||
|
- **Use strong file permissions** on configuration files
|
||||||
|
- **Regular security audits** of the system configuration
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Common Issues
|
### Common Issues
|
||||||
|
|
||||||
1. **Service won't start**: Check configuration file syntax and permissions
|
1. **Service won't start**:
|
||||||
2. **TLS errors**: Verify certificate files and permissions
|
- Check configuration file syntax and permissions
|
||||||
3. **Port conflicts**: Ensure port 8090 is not in use by another service
|
- Verify `/etc/dns_service/dns_service.conf` exists and is readable
|
||||||
4. **dnsmasq integration**: Verify dnsmasq is installed and properly configured
|
- 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
|
### Logs
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"dns_service/api"
|
"dns_service/server"
|
||||||
"log"
|
"dns_service/utils"
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/joho/godotenv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := godotenv.Load("/etc/dns_service/dns_service.conf")
|
utils.LoadEnv()
|
||||||
if err != nil {
|
server.Configure()
|
||||||
log.Fatal("Error loading .env file")
|
server.Run()
|
||||||
}
|
|
||||||
|
|
||||||
http.Handle("/", api.SpaHandler(http.FS(api.Frontend)))
|
|
||||||
http.HandleFunc("/api/settings", api.Settings)
|
|
||||||
http.HandleFunc("/api/settings/file", api.SettingsFile)
|
|
||||||
|
|
||||||
if os.Getenv("ENABLE_TLS") == "true" {
|
|
||||||
http.ListenAndServeTLS(
|
|
||||||
os.Getenv("SERVER_ADDRESS")+":"+os.Getenv("SERVER_PORT"),
|
|
||||||
os.Getenv("CERT_FILE"),
|
|
||||||
os.Getenv("KEY_FILE"),
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
http.ListenAndServe(
|
|
||||||
os.Getenv("SERVER_ADDRESS")+":"+os.Getenv("SERVER_PORT"),
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"dns_service/api"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Configure() {
|
||||||
|
http.Handle("/", api.SpaHandler(http.FS(api.Frontend)))
|
||||||
|
http.HandleFunc("/api/settings", api.Settings)
|
||||||
|
http.HandleFunc("/api/settings/file", api.SettingsFile)
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Run() {
|
||||||
|
if os.Getenv("ENABLE_TLS") == "true" {
|
||||||
|
err := http.ListenAndServeTLS(
|
||||||
|
os.Getenv("SERVER_ADDRESS")+":"+os.Getenv("SERVER_PORT"),
|
||||||
|
os.Getenv("CERT_FILE"),
|
||||||
|
os.Getenv("KEY_FILE"),
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := http.ListenAndServe(
|
||||||
|
os.Getenv("SERVER_ADDRESS")+":"+os.Getenv("SERVER_PORT"),
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoadEnv() {
|
||||||
|
err := godotenv.Load("/etc/dns_service/dns_service.conf")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error loading .env file")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user