A Unix CLI tool with a TUI for switching between DNS server profiles.
- Named DNS profiles - Define profiles like "home", "traveling", "work" with different DNS servers
- TUI interface - ncurses-style terminal UI using Bubble Tea
- Clear DNS - Revert to DHCP defaults with a single keypress
- Multiple network services - Switch between Wi-Fi, Ethernet, and other interfaces
- DNS cache flushing - Automatically flush DNS cache after changes
# Clone the repository
git clone https://github.com/nycjv321/dnsctl.git
cd dnsctl
# Build
make build
# Install to /usr/local/bin (requires sudo)
make install# Create config from example
make config
# Run the tool
make run
# or
./bin/dnsctlConfiguration is stored at ~/.config/dnsctl/config.yaml:
version: 1
default_service: "Wi-Fi"
profiles:
home:
description: "Home network with Pi-hole"
servers: ["192.168.1.100", "1.1.1.1"]
traveling:
description: "Use network's DNS (DHCP)"
dhcp: true # Clears DNS settings to use DHCP
cloudflare:
description: "Cloudflare DNS"
servers: ["1.1.1.1", "1.0.0.1"]
google:
description: "Google Public DNS"
servers: ["8.8.8.8", "8.8.4.4"]
settings:
flush_cache: trueEach profile supports these fields:
| Field | Description |
|---|---|
description |
Human-readable description shown in the TUI |
servers |
List of DNS server IP addresses |
dhcp |
Set to true to clear DNS and use DHCP (automatic) |
Use dhcp: true for profiles where you want to use the network's default DNS (useful when traveling or on networks with captive portals).
Launch the TUI:
dnsctl| Key | Action |
|---|---|
p |
Switch DNS profile |
c |
Clear DNS (use DHCP) |
s |
Change network service |
r |
Refresh status |
q |
Quit |
| Key | Action |
|---|---|
↑ / k |
Move up |
↓ / j |
Move down |
Enter |
Select |
Esc |
Go back |
q |
Quit |
Main Screen Profile Selection
┌─────────────────────┐ ┌─────────────────────┐
│ Current: Wi-Fi │ [p] │ > home │
│ DNS: 1.1.1.1 │ ───── │ traveling │
│ │ │ cloudflare │
│ [p] Switch Profile │ │ │
│ [c] Clear DNS │ │ Servers: 192.168... │
│ [s] Change Service │ └─────────────────────┘
│ [q] Quit │
└─────────────────────┘
Changing DNS settings on macOS requires appropriate permissions. You may need to:
-
Run with
sudo:sudo dnsctl
-
Or grant your terminal Full Disk Access in System Preferences > Privacy & Security > Full Disk Access
dnsctl uses macOS networksetup commands under the hood:
networksetup -listallnetworkservices # List services
networksetup -getdnsservers Wi-Fi # Get current DNS
networksetup -setdnsservers Wi-Fi 1.1.1.1 # Set DNS
networksetup -setdnsservers Wi-Fi empty # Clear (use DHCP)
dscacheutil -flushcache # Flush DNS cacheRun the test suite:
make test # Run all tests
go test -v ./... # Verbose output
go test -cover ./... # With coverage report
# View coverage in browser
go test -coverprofile=coverage.out ./... && go tool cover -html=coverage.outThe project has comprehensive test coverage:
- Config tests - Config loading, parsing, defaults, and profile helpers
- TUI tests - Model initialization, message handling, key navigation, DNS operations
- View tests - Rendering output for all views
Tests use a mock DNS client (internal/dns/mock.go) to avoid requiring system access.
- Bubble Tea - TUI framework
- Lip Gloss - Styling
- Bubbles - TUI components
- yaml.v3 - YAML parsing
local-network-management/
├── cmd/dnsctl/main.go # Entry point
├── internal/
│ ├── config/
│ │ ├── config.go # YAML config loading
│ │ └── config_test.go # Config tests
│ ├── dns/
│ │ ├── client.go # DNS client interface
│ │ ├── macos.go # networksetup wrapper
│ │ └── mock.go # Mock client for testing
│ └── tui/
│ ├── app.go # Bubble Tea model
│ ├── app_test.go # TUI logic tests
│ ├── keys.go # Keybindings
│ ├── styles.go # Lip Gloss styling
│ ├── views.go # View rendering
│ └── views_test.go # View rendering tests
├── go.mod
├── Makefile
└── config.example.yaml
This project uses Conventional Commits for commit messages, enabling automated releases and changelog generation.
<type>: <description>
| Type | Description | Example |
|---|---|---|
feat |
New feature | feat: add quad9 DNS profile |
fix |
Bug fix | fix: resolve DNS cache flush on Linux |
docs |
Documentation | docs: update installation instructions |
refactor |
Code refactoring | refactor: simplify profile loading |
test |
Adding tests | test: add TUI navigation tests |
chore |
Maintenance | chore: update dependencies |
Add ! after the type for breaking changes:
feat!: change config file formatMIT