DNS-MNS OpenWrt Integration Guide
This guide covers the comprehensive OpenWrt integration features available in DNS-MNS v6.4.0.
Overview
DNS-MNS provides native OpenWrt router support with advanced features including:
- Split-Horizon DNS - Different DNS servers based on domain
- Per-Device Policies - Custom DNS rules per MAC/VLAN/Subnet
- Auto-Benchmarking - Automatic DNS performance monitoring and failover
- Metrics & Logging - Prometheus export and structured query logging
- ubus Integration - Native OpenWrt system bus support
- Hot-Reload - Configuration changes without restart
Architecture
┌─────────────────────────────────────────────────────────────┐
│ DNS-MNS OpenWrt │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Split-Horizon│ │ Per-Device │ │ Scheduler │ │
│ │ DNS │ │ Policy │ │ (Auto-DNS) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ └─────────────────┴─────────────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ DNS Proxy │ │
│ └──────┬──────┘ │
│ │ │
│ ┌─────────────┐ ┌──────┴──────┐ ┌─────────────┐ │
│ │ Metrics │ │ Service │ │ ubus │ │
│ │ (Prometheus)│ │ Manager │ │ Server │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
Installation
Prerequisites
- OpenWrt 19.07+ or 21.02+ or 23.05+
- Architecture: x86_64, MIPS, MIPSel, ARMv7, ARM64
Method 1: Install via .ipk package (recommended)
Starting with v9.0.1, every release ships pre-built .ipk packages that can be
installed directly with opkg — no manual extraction or chmod required.
# Detect architecture
ARCH=$(uname -m)
case "$ARCH" in
x86_64) PKG_ARCH="x86_64" ;;
mips) PKG_ARCH="mips" ;;
mipsel) PKG_ARCH="mipsel" ;;
armv7l) PKG_ARCH="armv7" ;;
aarch64) PKG_ARCH="aarch64" ;;
esac
VERSION="9.0.1"
# Download the .ipk for your architecture
curl -L "https://gitlab.com/E-Gurl/dns-mns/-/releases/v${VERSION}/download/dns-mns_${VERSION}_${PKG_ARCH}.ipk" \
-o /tmp/dns-mns.ipk
# Install — opkg handles binary, init script, and default config automatically
opkg install /tmp/dns-mns.ipk
# Enable and start
/etc/init.d/dns-mns enable
/etc/init.d/dns-mns start
The .ipk installs the binary to /usr/bin/dns-mns, the init script to
/etc/init.d/dns-mns, and a default UCI config to /etc/config/dns-mns.
Existing /etc/config/dns-mns files are preserved on upgrade.
Method 2: Manual binary install
# Detect architecture
ARCH=$(uname -m)
case "$ARCH" in
x86_64) DOWNLOAD_ARCH="x86_64" ;;
mips) DOWNLOAD_ARCH="mips" ;;
mipsel) DOWNLOAD_ARCH="mipsel" ;;
armv7l) DOWNLOAD_ARCH="armv7" ;;
aarch64) DOWNLOAD_ARCH="aarch64" ;;
esac
# Download
curl -L "https://gitlab.com/E-Gurl/dns-mns/-/releases/latest/download/dns-mns-openwrt-${DOWNLOAD_ARCH}" \
-o /tmp/dns-mns
# Install
mv /tmp/dns-mns /usr/bin/dns-mns
chmod +x /usr/bin/dns-mns
Install Init Script (manual install only)
# Copy init script
curl -L https://gitlab.com/E-Gurl/dns-mns/-/raw/main/scripts/openwrt/dns-mns.init \
-o /etc/init.d/dns-mns
chmod +x /etc/init.d/dns-mns
# Create UCI config
cat > /etc/config/dns-mns << 'EOF'
config dns-mns 'main'
option enabled '1'
option mode 'upstream'
option listen_addr '127.0.0.1'
option listen_port '5353'
option primary_dns '1.1.1.1'
option secondary_dns '8.8.8.8'
option protocol 'auto'
option scheduler_enabled '1'
option benchmark_interval '6h'
option logging_enabled '1'
option log_path '/var/log/dns-mns.log'
EOF
# Enable service
/etc/init.d/dns-mns enable
/etc/init.d/dns-mns start
Configuration
Main Configuration (/etc/config/dns-mns)
config dns-mns 'main'
# Basic settings
option enabled '1'
option mode 'upstream' # upstream or direct
option listen_addr '127.0.0.1'
option listen_port '5353'
# DNS servers
option primary_dns '1.1.1.1'
option secondary_dns '8.8.8.8'
list backup_dns '9.9.9.9'
list backup_dns '94.140.14.14'
# Protocol settings
option protocol 'auto' # auto, doh, dot, dnscrypt
option enable_fragment '1'
option fragment_mode 'sni'
# Scheduler settings
option scheduler_enabled '1'
option benchmark_interval '6h'
option health_check_interval '60'
option auto_switch_threshold '20'
# Logging settings
option logging_enabled '1'
option log_level 'info' # error, warn, info, debug
option log_path '/var/log/dns-mns.log'
option log_max_size '1024'
option log_max_files '3'
option log_anonymize_ips '0'
option log_queries '1'
option log_responses '0'
# Cache settings
option cache_enabled '1'
option cache_size '10000'
option cache_ttl_min '60'
option cache_ttl_max '86400'
Split-Horizon DNS Rules
# /etc/config/dns-mns
config rule 'iranian'
option name 'Iranian Domains'
option domain '.ir'
list dns_server '178.22.122.100'
list dns_server '185.51.200.2'
option protocol 'plain'
option enabled '1'
option priority '50'
config rule 'local'
option name 'Local Domains'
option domain '.local'
list dns_server '127.0.0.1'
option protocol 'plain'
option enabled '1'
option priority '100'
config rule 'ads'
option name 'Ad Blocking'
option domain 'doubleclick.net'
list dns_server '0.0.0.0'
option enabled '1'
option priority '200'
Per-Device Policies
# Gaming device - low latency
config policy 'gaming_pc'
option name 'Gaming PC'
option type 'device'
option match_value 'AA:BB:CC:DD:EE:FF'
option primary_dns '178.22.122.100'
option secondary_dns '185.51.200.2'
option bypass_censorship '1'
option enabled '1'
option priority '100'
# Kids device - safe browsing
config policy 'kids_tablet'
option name 'Kids Tablet'
option type 'device'
option match_value '11:22:33:44:55:66'
option primary_dns '1.1.1.3'
option secondary_dns '1.0.0.3'
option block_ads '1'
option safe_search '1'
option enabled '1'
option priority '100'
# Guest VLAN
config policy 'guest_network'
option name 'Guest Network'
option type 'vlan'
option match_value '100'
option primary_dns '1.1.1.1'
option secondary_dns '8.8.8.8'
option block_ads '1'
option enabled '1'
option priority '50'
# IoT subnet
config policy 'iot_devices'
option name 'IoT Devices'
option type 'subnet'
option match_value '192.168.100.0/24'
option primary_dns '94.140.14.14'
option block_ads '1'
option enable_logging '1'
option enabled '1'
option priority '75'
CLI Commands
Service Management
# Start/stop/restart
/etc/init.d/dns-mns start
/etc/init.d/dns-mns stop
/etc/init.d/dns-mns restart
/etc/init.d/dns-mns reload
# Check status
/etc/init.d/dns-mns status
# View logs
logread -f | grep dns-mns
tail -f /var/log/dns-mns.log
DNS-MNS CLI
# Show OpenWrt status
dns-mns openwrt status
# Configure mode
dns-mns openwrt setup --mode upstream --listen 127.0.0.1 --port 5353
dns-mns openwrt setup --mode direct
# Restore original dnsmasq config
dns-mns openwrt restore
# Test DNS servers
dns-mns test --json
dns-mns test regional --top 5
# Start proxy with monitoring
dns-mns proxy --listen 127.0.0.1:5353 --protocol auto
# Show dashboard
dns-mns dashboard
# Export metrics
dns-mns metrics --format json
dns-mns metrics --format prometheus
# View logs
dns-mns logs --tail 100
dns-mns logs --follow
ubus Commands
# Check if DNS-MNS is running
ubus call dns-mns status
# Get statistics
ubus call dns-mns stats
# Reload configuration
ubus call dns-mns reload
# Ping test
ubus call dns-mns ping
Features
1. Split-Horizon DNS
Routes DNS queries to different servers based on domain:
.ir domains → Iranian DNS (Shecan, etc.)
.local domains → Local resolver
- International → Encrypted DNS with DPI evasion
Benefits:
- Faster local domain resolution
- Bypass international censorship for foreign sites
- Keep local traffic local
2. Per-Device Policies
Apply different DNS settings per device:
Policy Types:
device - Match by MAC address
vlan - Match by VLAN ID
subnet - Match by IP subnet
group - Match multiple devices
Preset Policies:
kids-safe - Cloudflare Family DNS with safe search
gaming-optimized - Shecan with DPI evasion
iot-restricted - AdGuard with logging
guest-network - Standard DNS for guests
3. Auto-Benchmarking Scheduler
Automatically tests DNS servers and switches to the best:
Features:
- Periodic benchmarking (default: every 6 hours)
- Health checking (default: every 60 seconds)
- Automatic failover on consecutive failures
- Performance-based switching (20% improvement threshold)
- Switch history tracking
4. Metrics & Monitoring
Prometheus Metrics:
dns_mns_total_queries - Total query counter
dns_mns_cached_queries - Cache hit counter
dns_mns_blocked_queries - Blocked query counter
dns_mns_failed_queries - Failed query counter
dns_mns_unique_clients - Active clients gauge
dns_mns_unique_domains - Unique domains gauge
dns_mns_avg_response_time - Response time gauge
dns_mns_server_queries{server="..."} - Per-server queries
Access:
# Local access
curl http://localhost:9090/metrics
# For Prometheus scraping
cat > /etc/prometheus/targets/dns-mns.yml << 'EOF'
- targets:
- 192.168.1.1:9090
labels:
job: dns-mns
EOF
5. Structured Logging
JSON-formatted logs with rotation:
Log Format:
{
"timestamp": "2026-02-13T12:00:00Z",
"level": "INFO",
"client_ip": "192.168.1.100",
"domain": "google.com",
"query_type": "A",
"server_used": "1.1.1.1",
"response_time_ms": 15,
"cached": false
}
Log Rotation:
- Default size: 1MB per file
- Default retention: 3 files
- Automatic compression of old logs
6. Hot-Reload
Reload configuration without restart:
# Via signal
kill -HUP $(pgrep dns-mns)
# Via ubus
ubus call dns-mns reload
# Via CLI
dns-mns reload
What can be reloaded:
- DNS server lists
- Split-horizon rules
- Policy configurations
- Logging settings
- Scheduler intervals
Advanced Configuration
Custom DNS List
# Edit DNS list
vi /etc/dns-mns/dns-list.conf
# Format: NAME|PRIMARY_IP|SECONDARY_IP|LOCATION
MyDNS|1.2.3.4|5.6.7.8|Custom
# Reload
dns-mns reload
Firewall Rules (Direct Mode)
When using direct mode, ensure DNS traffic reaches DNS-MNS:
# Redirect port 53 to DNS-MNS
iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-port 5353
iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-port 5353
# For IPv6
ip6tables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-port 5353
Integration with AdGuard Home
# Run AdGuard Home on different port
# Configure DNS-MNS upstream to AdGuard
uci set dns-mns.@main[0].primary_dns='127.0.0.1'
uci set dns-mns.@main[0].listen_port='5353'
uci commit dns-mns
# Configure AdGuard to listen on 127.0.0.1:5300
# Set DNS-MNS upstream to 127.0.0.1:5300
Troubleshooting
Check Service Status
/etc/init.d/dns-mns status
ps | grep dns-mns
logread | grep dns-mns
dns-mns openwrt status
Verify DNS Resolution
# Test local DNS
nslookup google.com 127.0.0.1:5353
# Test system DNS
nslookup google.com
# Check which DNS is used
dns-mns diagnose
Common Issues
Permission Denied:
# Fix log directory permissions
mkdir -p /var/log
chown nobody:nogroup /var/log/dns-mns.log
Port Already in Use:
# Find process using port
netstat -tlnp | grep 5353
# Change DNS-MNS port
uci set dns-mns.@main[0].listen_port='5354'
uci commit dns-mns
/etc/init.d/dns-mns restart
High Memory Usage:
# Enable low memory mode
uci set dns-mns.@main[0].low_mem_mode='1'
uci set dns-mns.@main[0].cache_size='1000'
uci commit dns-mns
/etc/init.d/dns-mns restart
API Reference
ubus API
| Method | Parameters | Description |
|---|
status | - | Get full status |
stats | - | Get statistics |
reload | - | Reload configuration |
ping | - | Health check |
set_config | {key: value} | Update setting |
REST API (when enabled)
| Endpoint | Method | Description |
|---|
/metrics | GET | Prometheus metrics |
/api/status | GET | JSON status |
/api/stats | GET | Statistics |
/api/logs | GET | Recent logs |
/api/config | GET/POST | Configuration |
Migration from Legacy
If upgrading from DNS-MNS < 6.4.0:
# Backup old config
cp /etc/config/dns-mns /etc/config/dns-mns.backup
# Upgrade package
opkg upgrade dns-mns
# Migrate configuration
dns-mns migrate-config
# Restart
/etc/init.d/dns-mns restart
Best Practices
- Start with Upstream Mode - Safer for initial deployment
- Enable Logging - Helps with troubleshooting
- Set Up Monitoring - Use Prometheus/Grafana for visibility
- Test Policies - Verify per-device rules work as expected
- Regular Backups - Backup
/etc/config/dns-mns
- Monitor Memory - On routers with < 64MB RAM, use low memory mode
Support