mirror of
https://github.com/fosrl/olm.git
synced 2026-03-03 17:26:45 +00:00
@@ -1,263 +0,0 @@
|
|||||||
# DNS Platform Module
|
|
||||||
|
|
||||||
A standalone Go module for managing system DNS settings across different platforms and DNS management systems.
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This module provides a unified interface for overriding system DNS servers on:
|
|
||||||
- **macOS**: Using `scutil`
|
|
||||||
- **Windows**: Using Windows Registry
|
|
||||||
- **Linux/FreeBSD**: Supporting multiple backends:
|
|
||||||
- systemd-resolved (D-Bus)
|
|
||||||
- NetworkManager (D-Bus)
|
|
||||||
- resolvconf utility
|
|
||||||
- Direct `/etc/resolv.conf` manipulation
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- ✅ Cross-platform DNS override
|
|
||||||
- ✅ Automatic detection of best DNS management method
|
|
||||||
- ✅ Backup and restore original DNS settings
|
|
||||||
- ✅ Platform-specific optimizations
|
|
||||||
- ✅ No external dependencies for basic functionality
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
### Interface
|
|
||||||
|
|
||||||
All configurators implement the `DNSConfigurator` interface:
|
|
||||||
|
|
||||||
```go
|
|
||||||
type DNSConfigurator interface {
|
|
||||||
SetDNS(servers []netip.Addr) ([]netip.Addr, error)
|
|
||||||
RestoreDNS() error
|
|
||||||
GetCurrentDNS() ([]netip.Addr, error)
|
|
||||||
Name() string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Platform-Specific Implementations
|
|
||||||
|
|
||||||
Each platform has dedicated structs instead of using build tags at the file level:
|
|
||||||
|
|
||||||
- `DarwinDNSConfigurator` - macOS using scutil
|
|
||||||
- `WindowsDNSConfigurator` - Windows using registry
|
|
||||||
- `FileDNSConfigurator` - Unix using /etc/resolv.conf
|
|
||||||
- `SystemdResolvedDNSConfigurator` - Linux using systemd-resolved
|
|
||||||
- `NetworkManagerDNSConfigurator` - Linux using NetworkManager
|
|
||||||
- `ResolvconfDNSConfigurator` - Linux using resolvconf utility
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
### Automatic Detection
|
|
||||||
|
|
||||||
```go
|
|
||||||
import "github.com/your-org/olm/dns/platform"
|
|
||||||
|
|
||||||
// On Linux/Unix - provide interface name for best results
|
|
||||||
configurator, err := platform.DetectBestConfigurator("eth0")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set DNS servers
|
|
||||||
originalServers, err := configurator.SetDNS([]netip.Addr{
|
|
||||||
netip.MustParseAddr("8.8.8.8"),
|
|
||||||
netip.MustParseAddr("8.8.4.4"),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore original DNS
|
|
||||||
defer configurator.RestoreDNS()
|
|
||||||
```
|
|
||||||
|
|
||||||
### Manual Selection
|
|
||||||
|
|
||||||
```go
|
|
||||||
// Linux - Direct file manipulation
|
|
||||||
configurator, err := platform.NewFileDNSConfigurator()
|
|
||||||
|
|
||||||
// Linux - systemd-resolved
|
|
||||||
configurator, err := platform.NewSystemdResolvedDNSConfigurator("eth0")
|
|
||||||
|
|
||||||
// Linux - NetworkManager
|
|
||||||
configurator, err := platform.NewNetworkManagerDNSConfigurator("eth0")
|
|
||||||
|
|
||||||
// Linux - resolvconf
|
|
||||||
configurator, err := platform.NewResolvconfDNSConfigurator("eth0")
|
|
||||||
|
|
||||||
// macOS
|
|
||||||
configurator, err := platform.NewDarwinDNSConfigurator()
|
|
||||||
|
|
||||||
// Windows (requires interface GUID)
|
|
||||||
configurator, err := platform.NewWindowsDNSConfigurator("{GUID-HERE}")
|
|
||||||
```
|
|
||||||
|
|
||||||
### Platform Detection Utilities
|
|
||||||
|
|
||||||
```go
|
|
||||||
// Check if systemd-resolved is available
|
|
||||||
if platform.IsSystemdResolvedAvailable() {
|
|
||||||
// Use systemd-resolved
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if NetworkManager is available
|
|
||||||
if platform.IsNetworkManagerAvailable() {
|
|
||||||
// Use NetworkManager
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if resolvconf is available
|
|
||||||
if platform.IsResolvconfAvailable() {
|
|
||||||
// Use resolvconf
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get system DNS servers
|
|
||||||
servers, err := platform.GetSystemDNS()
|
|
||||||
```
|
|
||||||
|
|
||||||
## Implementation Details
|
|
||||||
|
|
||||||
### macOS (Darwin)
|
|
||||||
|
|
||||||
Uses `scutil` to create DNS configuration states in the system configuration database. DNS settings are applied via the Network Service state hierarchy.
|
|
||||||
|
|
||||||
**Pros:**
|
|
||||||
- Native macOS API
|
|
||||||
- Proper integration with system preferences
|
|
||||||
- Supports DNS flushing
|
|
||||||
|
|
||||||
**Cons:**
|
|
||||||
- Requires elevated privileges
|
|
||||||
|
|
||||||
### Windows
|
|
||||||
|
|
||||||
Modifies registry keys under `SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{GUID}`.
|
|
||||||
|
|
||||||
**Pros:**
|
|
||||||
- Direct registry manipulation
|
|
||||||
- Immediate effect after cache flush
|
|
||||||
|
|
||||||
**Cons:**
|
|
||||||
- Requires interface GUID
|
|
||||||
- Requires administrator privileges
|
|
||||||
- May require restart of DNS client service
|
|
||||||
|
|
||||||
### Linux: systemd-resolved
|
|
||||||
|
|
||||||
Uses D-Bus API to communicate with systemd-resolved service.
|
|
||||||
|
|
||||||
**Pros:**
|
|
||||||
- Modern standard on many distributions
|
|
||||||
- Proper per-interface configuration
|
|
||||||
- No file manipulation needed
|
|
||||||
|
|
||||||
**Cons:**
|
|
||||||
- Requires D-Bus access
|
|
||||||
- Only available on systemd systems
|
|
||||||
- Interface-specific
|
|
||||||
|
|
||||||
### Linux: NetworkManager
|
|
||||||
|
|
||||||
Uses D-Bus API to modify NetworkManager connection settings.
|
|
||||||
|
|
||||||
**Pros:**
|
|
||||||
- Common on desktop Linux
|
|
||||||
- Integrates with NetworkManager GUI
|
|
||||||
- Per-interface configuration
|
|
||||||
|
|
||||||
**Cons:**
|
|
||||||
- Requires NetworkManager to be running
|
|
||||||
- D-Bus access required
|
|
||||||
- Interface-specific
|
|
||||||
|
|
||||||
### Linux: resolvconf
|
|
||||||
|
|
||||||
Uses the `resolvconf` utility to update DNS configuration.
|
|
||||||
|
|
||||||
**Pros:**
|
|
||||||
- Works on many different systems
|
|
||||||
- Handles merging of multiple DNS sources
|
|
||||||
- Supports both openresolv and Debian resolvconf
|
|
||||||
|
|
||||||
**Cons:**
|
|
||||||
- Requires resolvconf to be installed
|
|
||||||
- Interface-specific
|
|
||||||
|
|
||||||
### Linux: Direct File
|
|
||||||
|
|
||||||
Directly modifies `/etc/resolv.conf` with backup.
|
|
||||||
|
|
||||||
**Pros:**
|
|
||||||
- Works everywhere
|
|
||||||
- No dependencies
|
|
||||||
- Simple and reliable
|
|
||||||
|
|
||||||
**Cons:**
|
|
||||||
- May be overwritten by DHCP or other services
|
|
||||||
- No per-interface configuration
|
|
||||||
- Doesn't integrate with system tools
|
|
||||||
|
|
||||||
## Build Tags
|
|
||||||
|
|
||||||
The module uses build tags to compile platform-specific code:
|
|
||||||
|
|
||||||
- `//go:build darwin && !ios` - macOS (non-iOS)
|
|
||||||
- `//go:build windows` - Windows
|
|
||||||
- `//go:build (linux && !android) || freebsd` - Linux and FreeBSD
|
|
||||||
- `//go:build linux && !android` - Linux only (for systemd)
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- `github.com/godbus/dbus/v5` - D-Bus communication (Linux only)
|
|
||||||
- `golang.org/x/sys` - System calls and registry access
|
|
||||||
- Standard library
|
|
||||||
|
|
||||||
## Security Considerations
|
|
||||||
|
|
||||||
- **Elevated Privileges**: Most DNS modification operations require root/administrator privileges
|
|
||||||
- **Backup Files**: Backup files contain original DNS configuration and should be protected
|
|
||||||
- **State Persistence**: DNS state is stored in memory; unexpected termination may require manual cleanup
|
|
||||||
|
|
||||||
## Cleanup
|
|
||||||
|
|
||||||
The module properly cleans up after itself:
|
|
||||||
|
|
||||||
1. Backup files are created before modification
|
|
||||||
2. Original DNS servers are stored in memory
|
|
||||||
3. `RestoreDNS()` should be called to restore original settings
|
|
||||||
4. On Linux file-based systems, backup files are removed after restoration
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
Each configurator can be tested independently:
|
|
||||||
|
|
||||||
```go
|
|
||||||
func TestDNSOverride(t *testing.T) {
|
|
||||||
configurator, err := platform.NewFileDNSConfigurator()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
servers := []netip.Addr{
|
|
||||||
netip.MustParseAddr("1.1.1.1"),
|
|
||||||
}
|
|
||||||
|
|
||||||
original, err := configurator.SetDNS(servers)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
defer configurator.RestoreDNS()
|
|
||||||
|
|
||||||
current, err := configurator.GetCurrentDNS()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, servers, current)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Future Enhancements
|
|
||||||
|
|
||||||
- [ ] Support for search domains configuration
|
|
||||||
- [ ] Support for DNS options (timeout, attempts, etc.)
|
|
||||||
- [ ] Monitoring for external DNS changes
|
|
||||||
- [ ] Automatic restoration on process exit
|
|
||||||
- [ ] Windows NRPT (Name Resolution Policy Table) support
|
|
||||||
- [ ] IPv6 DNS server support on all platforms
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
# DNS Platform Module Refactoring Summary
|
|
||||||
|
|
||||||
## Changes Made
|
|
||||||
|
|
||||||
Successfully refactored the DNS platform directory from a NetBird-derived codebase into a standalone, simplified DNS override module.
|
|
||||||
|
|
||||||
### Files Created
|
|
||||||
|
|
||||||
**Core Interface & Types:**
|
|
||||||
- `types.go` - DNSConfigurator interface and shared types (DNSConfig, DNSState)
|
|
||||||
|
|
||||||
**Platform Implementations:**
|
|
||||||
- `darwin.go` - macOS DNS configurator using scutil (replaces host_darwin.go)
|
|
||||||
- `windows.go` - Windows DNS configurator using registry (replaces host_windows.go)
|
|
||||||
- `file.go` - Linux/Unix file-based configurator (replaces file_unix.go + file_parser_unix.go + file_repair_unix.go)
|
|
||||||
- `networkmanager.go` - NetworkManager D-Bus configurator (replaces network_manager_unix.go)
|
|
||||||
- `systemd.go` - systemd-resolved D-Bus configurator (replaces systemd_linux.go)
|
|
||||||
- `resolvconf.go` - resolvconf utility configurator (replaces resolvconf_unix.go)
|
|
||||||
|
|
||||||
**Detection & Helpers:**
|
|
||||||
- `detect_unix.go` - Automatic detection for Linux/FreeBSD
|
|
||||||
- `detect_darwin.go` - Automatic detection for macOS
|
|
||||||
- `detect_windows.go` - Automatic detection for Windows
|
|
||||||
|
|
||||||
**Documentation:**
|
|
||||||
- `README.md` - Comprehensive module documentation
|
|
||||||
- `examples/example_usage.go` - Usage examples for all platforms
|
|
||||||
|
|
||||||
### Files Removed
|
|
||||||
|
|
||||||
**Old NetBird-specific files:**
|
|
||||||
- `dbus_unix.go` - D-Bus utilities (functionality moved into platform-specific files)
|
|
||||||
- `file_parser_unix.go` - resolv.conf parser (simplified and integrated into file.go)
|
|
||||||
- `file_repair_unix.go` - File watching/repair (removed - out of scope)
|
|
||||||
- `file_unix.go` - Old file configurator (replaced by file.go)
|
|
||||||
- `host_darwin.go` - Old macOS configurator (replaced by darwin.go)
|
|
||||||
- `host_unix.go` - Old Unix manager factory (replaced by detect_unix.go)
|
|
||||||
- `host_windows.go` - Old Windows configurator (replaced by windows.go)
|
|
||||||
- `network_manager_unix.go` - Old NetworkManager (replaced by networkmanager.go)
|
|
||||||
- `resolvconf_unix.go` - Old resolvconf (replaced by resolvconf.go)
|
|
||||||
- `systemd_linux.go` - Old systemd-resolved (replaced by systemd.go)
|
|
||||||
- `unclean_shutdown_*.go` - Unclean shutdown detection (removed - out of scope)
|
|
||||||
|
|
||||||
### Key Architectural Changes
|
|
||||||
|
|
||||||
1. **Removed Build Tags for Platform Selection**
|
|
||||||
- Old: Used `//go:build` tags at top of files to compile different code per platform
|
|
||||||
- New: Named structs differently per platform (e.g., `DarwinDNSConfigurator`, `WindowsDNSConfigurator`)
|
|
||||||
- Build tags kept only where necessary for cross-platform library imports
|
|
||||||
|
|
||||||
2. **Simplified Interface**
|
|
||||||
- Removed complex domain routing, search domains, and port customization
|
|
||||||
- Focused on core functionality: Set DNS, Get DNS, Restore DNS
|
|
||||||
- Removed state manager dependencies
|
|
||||||
|
|
||||||
3. **Removed External Dependencies**
|
|
||||||
- Removed: statemanager, NetBird-specific types, logging libraries
|
|
||||||
- Kept only: D-Bus (for Linux), x/sys (for Windows registry and Unix syscalls)
|
|
||||||
- Uses standard library where possible
|
|
||||||
|
|
||||||
4. **Standalone Operation**
|
|
||||||
- No longer depends on NetBird types (HostDNSConfig, etc.)
|
|
||||||
- Uses standard library types (net/netip.Addr)
|
|
||||||
- Self-contained backup/restore logic
|
|
||||||
|
|
||||||
5. **Improved Code Organization**
|
|
||||||
- Each platform has its own clearly-named file
|
|
||||||
- Detection logic separated into detect_*.go files
|
|
||||||
- Shared types in types.go
|
|
||||||
- Examples in dedicated examples/ directory
|
|
||||||
|
|
||||||
### Feature Comparison
|
|
||||||
|
|
||||||
**Removed (out of scope for basic DNS override):**
|
|
||||||
- Search domain management
|
|
||||||
- Match-only domains
|
|
||||||
- DNS port customization (except where natively supported)
|
|
||||||
- File watching and auto-repair
|
|
||||||
- Unclean shutdown detection
|
|
||||||
- State persistence
|
|
||||||
- Integration with external state managers
|
|
||||||
|
|
||||||
**Retained (core DNS functionality):**
|
|
||||||
- Setting DNS servers
|
|
||||||
- Getting current DNS servers
|
|
||||||
- Restoring original DNS servers
|
|
||||||
- Automatic platform detection
|
|
||||||
- DNS cache flushing
|
|
||||||
- Backup and restore of original configuration
|
|
||||||
|
|
||||||
### Platform-Specific Notes
|
|
||||||
|
|
||||||
**macOS (Darwin):**
|
|
||||||
- Simplified to focus on DNS server override using scutil
|
|
||||||
- Removed complex domain routing and local DNS setup
|
|
||||||
- Removed GPO and state management
|
|
||||||
- Kept DNS cache flushing
|
|
||||||
|
|
||||||
**Windows:**
|
|
||||||
- Simplified registry manipulation to just NameServer key
|
|
||||||
- Removed NRPT (Name Resolution Policy Table) support
|
|
||||||
- Removed DNS registration and WINS management
|
|
||||||
- Kept DNS cache flushing
|
|
||||||
|
|
||||||
**Linux - File-based:**
|
|
||||||
- Direct /etc/resolv.conf manipulation with backup
|
|
||||||
- Removed file watching and auto-repair
|
|
||||||
- Removed complex search domain merging logic
|
|
||||||
- Simple nameserver-only configuration
|
|
||||||
|
|
||||||
**Linux - systemd-resolved:**
|
|
||||||
- D-Bus API for per-link DNS configuration
|
|
||||||
- Simplified to just DNS server setting
|
|
||||||
- Uses Revert method for restoration
|
|
||||||
|
|
||||||
**Linux - NetworkManager:**
|
|
||||||
- D-Bus API for connection settings modification
|
|
||||||
- Simplified to IPv4 DNS only
|
|
||||||
- Removed search/match domain complexity
|
|
||||||
|
|
||||||
**Linux - resolvconf:**
|
|
||||||
- Uses resolvconf utility (openresolv or Debian resolvconf)
|
|
||||||
- Interface-specific configuration
|
|
||||||
- Simple nameserver configuration
|
|
||||||
|
|
||||||
### Usage Pattern
|
|
||||||
|
|
||||||
```go
|
|
||||||
// Automatic detection
|
|
||||||
configurator, err := platform.DetectBestConfigurator("eth0")
|
|
||||||
|
|
||||||
// Set DNS
|
|
||||||
original, err := configurator.SetDNS([]netip.Addr{
|
|
||||||
netip.MustParseAddr("8.8.8.8"),
|
|
||||||
})
|
|
||||||
|
|
||||||
// Restore
|
|
||||||
defer configurator.RestoreDNS()
|
|
||||||
```
|
|
||||||
|
|
||||||
### Maintenance Notes
|
|
||||||
|
|
||||||
- Each platform implementation is independent
|
|
||||||
- No shared state between configurators
|
|
||||||
- Backups are file-based or in-memory only
|
|
||||||
- No external database or state management required
|
|
||||||
- Configurators can be tested independently
|
|
||||||
|
|
||||||
## Migration Guide
|
|
||||||
|
|
||||||
If you were using the old code:
|
|
||||||
|
|
||||||
1. Replace `HostDNSConfig` with simple `[]netip.Addr` for DNS servers
|
|
||||||
2. Replace `newHostManager()` with `platform.DetectBestConfigurator()`
|
|
||||||
3. Replace `applyDNSConfig()` with `SetDNS()`
|
|
||||||
4. Replace `restoreHostDNS()` with `RestoreDNS()`
|
|
||||||
5. Remove state manager dependencies
|
|
||||||
6. Remove search domain configuration (can be added back if needed)
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
Required:
|
|
||||||
- `github.com/godbus/dbus/v5` - For Linux D-Bus configurators
|
|
||||||
- `golang.org/x/sys` - For Windows registry and Unix syscalls
|
|
||||||
- Standard library
|
|
||||||
|
|
||||||
## Testing Recommendations
|
|
||||||
|
|
||||||
Each configurator should be tested on its target platform:
|
|
||||||
- macOS: Test darwin.go with scutil
|
|
||||||
- Windows: Test windows.go with actual interface GUID
|
|
||||||
- Linux: Test all variants (file, systemd, networkmanager, resolvconf)
|
|
||||||
- Verify backup/restore functionality
|
|
||||||
- Test with invalid input (empty servers, bad interface names)
|
|
||||||
@@ -1,236 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/netip"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/your-org/olm/dns/platform"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Example 1: Automatic detection and DNS override
|
|
||||||
exampleAutoDetection()
|
|
||||||
|
|
||||||
// Example 2: Manual platform selection
|
|
||||||
// exampleManualSelection()
|
|
||||||
|
|
||||||
// Example 3: Get current system DNS
|
|
||||||
// exampleGetCurrentDNS()
|
|
||||||
}
|
|
||||||
|
|
||||||
// exampleAutoDetection demonstrates automatic detection of the best DNS configurator
|
|
||||||
func exampleAutoDetection() {
|
|
||||||
fmt.Println("=== Example 1: Automatic Detection ===")
|
|
||||||
|
|
||||||
// On Linux/Unix, provide an interface name for better detection
|
|
||||||
// On macOS, the interface name is ignored
|
|
||||||
// On Windows, provide the interface GUID
|
|
||||||
ifaceName := "eth0" // Change this to your interface name
|
|
||||||
|
|
||||||
configurator, err := platform.DetectBestConfigurator(ifaceName)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to detect DNS configurator: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Using DNS configurator: %s\n", configurator.Name())
|
|
||||||
|
|
||||||
// Get current DNS servers before changing
|
|
||||||
currentDNS, err := configurator.GetCurrentDNS()
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Warning: Could not get current DNS: %v", err)
|
|
||||||
} else {
|
|
||||||
fmt.Printf("Current DNS servers: %v\n", currentDNS)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set new DNS servers
|
|
||||||
newDNS := []netip.Addr{
|
|
||||||
netip.MustParseAddr("1.1.1.1"), // Cloudflare
|
|
||||||
netip.MustParseAddr("8.8.8.8"), // Google
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Setting DNS servers to: %v\n", newDNS)
|
|
||||||
originalDNS, err := configurator.SetDNS(newDNS)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to set DNS: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Original DNS servers (backed up): %v\n", originalDNS)
|
|
||||||
|
|
||||||
// Set up signal handling for graceful shutdown
|
|
||||||
sigChan := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
|
||||||
|
|
||||||
// Run for 30 seconds or until interrupted
|
|
||||||
fmt.Println("\nDNS override active. Press Ctrl+C to restore original DNS.")
|
|
||||||
fmt.Println("Waiting 30 seconds...")
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-time.After(30 * time.Second):
|
|
||||||
fmt.Println("\nTimeout reached.")
|
|
||||||
case sig := <-sigChan:
|
|
||||||
fmt.Printf("\nReceived signal: %v\n", sig)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore original DNS
|
|
||||||
fmt.Println("Restoring original DNS servers...")
|
|
||||||
if err := configurator.RestoreDNS(); err != nil {
|
|
||||||
log.Fatalf("Failed to restore DNS: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("DNS restored successfully!")
|
|
||||||
}
|
|
||||||
|
|
||||||
// exampleManualSelection demonstrates manual selection of DNS configurator
|
|
||||||
func exampleManualSelection() {
|
|
||||||
fmt.Println("=== Example 2: Manual Selection ===")
|
|
||||||
|
|
||||||
// Linux - systemd-resolved
|
|
||||||
configurator, err := platform.NewSystemdResolvedDNSConfigurator("eth0")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to create systemd-resolved configurator: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Using: %s\n", configurator.Name())
|
|
||||||
|
|
||||||
newDNS := []netip.Addr{
|
|
||||||
netip.MustParseAddr("1.1.1.1"),
|
|
||||||
}
|
|
||||||
|
|
||||||
originalDNS, err := configurator.SetDNS(newDNS)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to set DNS: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Changed from %v to %v\n", originalDNS, newDNS)
|
|
||||||
|
|
||||||
// Restore after 10 seconds
|
|
||||||
time.Sleep(10 * time.Second)
|
|
||||||
configurator.RestoreDNS()
|
|
||||||
}
|
|
||||||
|
|
||||||
// exampleGetCurrentDNS demonstrates getting current system DNS
|
|
||||||
func exampleGetCurrentDNS() {
|
|
||||||
fmt.Println("=== Example 3: Get Current DNS ===")
|
|
||||||
|
|
||||||
configurator, err := platform.DetectBestConfigurator("eth0")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to detect configurator: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
servers, err := configurator.GetCurrentDNS()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to get DNS: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Current DNS servers (%s):\n", configurator.Name())
|
|
||||||
for i, server := range servers {
|
|
||||||
fmt.Printf(" %d. %s\n", i+1, server)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Platform-specific examples
|
|
||||||
|
|
||||||
// exampleLinuxFile demonstrates direct file manipulation on Linux
|
|
||||||
func exampleLinuxFile() {
|
|
||||||
configurator, err := platform.NewFileDNSConfigurator()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
newDNS := []netip.Addr{
|
|
||||||
netip.MustParseAddr("8.8.8.8"),
|
|
||||||
}
|
|
||||||
|
|
||||||
originalDNS, err := configurator.SetDNS(newDNS)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer configurator.RestoreDNS()
|
|
||||||
|
|
||||||
fmt.Printf("Changed from %v to %v\n", originalDNS, newDNS)
|
|
||||||
time.Sleep(10 * time.Second)
|
|
||||||
}
|
|
||||||
|
|
||||||
// exampleLinuxNetworkManager demonstrates NetworkManager on Linux
|
|
||||||
func exampleLinuxNetworkManager() {
|
|
||||||
if !platform.IsNetworkManagerAvailable() {
|
|
||||||
fmt.Println("NetworkManager is not available")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
configurator, err := platform.NewNetworkManagerDNSConfigurator("eth0")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
newDNS := []netip.Addr{
|
|
||||||
netip.MustParseAddr("1.1.1.1"),
|
|
||||||
}
|
|
||||||
|
|
||||||
originalDNS, err := configurator.SetDNS(newDNS)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer configurator.RestoreDNS()
|
|
||||||
|
|
||||||
fmt.Printf("Changed from %v to %v\n", originalDNS, newDNS)
|
|
||||||
time.Sleep(10 * time.Second)
|
|
||||||
}
|
|
||||||
|
|
||||||
// exampleMacOS demonstrates macOS DNS override
|
|
||||||
func exampleMacOS() {
|
|
||||||
configurator, err := platform.NewDarwinDNSConfigurator()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
newDNS := []netip.Addr{
|
|
||||||
netip.MustParseAddr("1.1.1.1"),
|
|
||||||
netip.MustParseAddr("1.0.0.1"),
|
|
||||||
}
|
|
||||||
|
|
||||||
originalDNS, err := configurator.SetDNS(newDNS)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer configurator.RestoreDNS()
|
|
||||||
|
|
||||||
fmt.Printf("Changed from %v to %v\n", originalDNS, newDNS)
|
|
||||||
time.Sleep(10 * time.Second)
|
|
||||||
}
|
|
||||||
|
|
||||||
// exampleWindows demonstrates Windows DNS override
|
|
||||||
func exampleWindows() {
|
|
||||||
// You need to get the interface GUID first
|
|
||||||
// This can be obtained from:
|
|
||||||
// - ipconfig /all (look for the interface's GUID)
|
|
||||||
// - registry: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces
|
|
||||||
guid := "{YOUR-INTERFACE-GUID-HERE}"
|
|
||||||
|
|
||||||
configurator, err := platform.NewWindowsDNSConfigurator(guid)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
newDNS := []netip.Addr{
|
|
||||||
netip.MustParseAddr("1.1.1.1"),
|
|
||||||
}
|
|
||||||
|
|
||||||
originalDNS, err := configurator.SetDNS(newDNS)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer configurator.RestoreDNS()
|
|
||||||
|
|
||||||
fmt.Printf("Changed from %v to %v\n", originalDNS, newDNS)
|
|
||||||
time.Sleep(10 * time.Second)
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user