secubox-openwrt/package/secubox/luci-secubox-dnsguard/root/usr/libexec/rpcd/luci.dnsguard
CyberMind-FR 5f85e76ac0 feat: Add DNS Guard app and Ollama model suggestions
DNS Guard (luci-secubox-dnsguard):
- Privacy-focused DNS manager with KISS UI
- DNS provider feed: FDN, Quad9, Cloudflare, Mullvad, AdGuard, etc.
- Smart Config auto-detects fastest DNS for location
- Category filtering (privacy, security, fast, family, adblock)
- One-click provider switching with dnsmasq integration

Ollama:
- Add suggested models grid when no models installed
- Clickable model cards to download directly
- Models: tinyllama, llama3.2, phi3, gemma2, qwen2.5, mistral, codellama

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 14:11:41 +01:00

262 lines
8.5 KiB
Bash
Executable File

#!/bin/sh
# SecuBox DNS Guard - Privacy DNS Manager
# Provides uncensored DNS feeds and smart configuration
. /usr/share/libubox/jshn.sh
# DNS Provider Feed - Uncensored & Privacy-focused
# Format: id|name|primary|secondary|dot_host|doh_url|category|country|description
DNS_PROVIDERS='
fdn|FDN (French Data Network)|80.67.169.12|80.67.169.40|ns0.fdn.fr|https://ns0.fdn.fr/dns-query|privacy|FR|French non-profit, no logs, uncensored
fdn_ipv6|FDN IPv6|2001:910:800::12|2001:910:800::40|ns0.fdn.fr|https://ns0.fdn.fr/dns-query|privacy|FR|FDN IPv6 resolvers
quad9|Quad9|9.9.9.9|149.112.112.112|dns.quad9.net|https://dns.quad9.net/dns-query|security|CH|Malware blocking, Swiss privacy
quad9_unsecured|Quad9 Unsecured|9.9.9.10|149.112.112.10|dns10.quad9.net|https://dns10.quad9.net/dns-query|privacy|CH|No blocking, Swiss privacy
cloudflare|Cloudflare|1.1.1.1|1.0.0.1|cloudflare-dns.com|https://cloudflare-dns.com/dns-query|fast|US|Fast, privacy-focused
cloudflare_family|Cloudflare Family|1.1.1.3|1.0.0.3|family.cloudflare-dns.com|https://family.cloudflare-dns.com/dns-query|family|US|Malware + adult content blocking
mullvad|Mullvad|194.242.2.2|193.19.108.2|dns.mullvad.net|https://dns.mullvad.net/dns-query|privacy|SE|No logs, Swedish privacy
mullvad_adblock|Mullvad Adblock|194.242.2.3|193.19.108.3|adblock.dns.mullvad.net|https://adblock.dns.mullvad.net/dns-query|adblock|SE|Ads + trackers blocking
adguard|AdGuard|94.140.14.14|94.140.15.15|dns.adguard-dns.com|https://dns.adguard-dns.com/dns-query|adblock|CY|Ad blocking DNS
adguard_family|AdGuard Family|94.140.14.15|94.140.15.16|family.adguard-dns.com|https://dns.adguard-dns.com/dns-query|family|CY|Family protection
opendns|OpenDNS|208.67.222.222|208.67.220.220|doh.opendns.com|https://doh.opendns.com/dns-query|security|US|Cisco security DNS
opendns_family|OpenDNS FamilyShield|208.67.222.123|208.67.220.123|doh.familyshield.opendns.com|https://doh.familyshield.opendns.com/dns-query|family|US|Family protection
google|Google|8.8.8.8|8.8.4.4|dns.google|https://dns.google/dns-query|fast|US|Fast, global anycast
cleanbrowsing|CleanBrowsing Security|185.228.168.9|185.228.169.9|security-filter-dns.cleanbrowsing.org|https://doh.cleanbrowsing.org/doh/security-filter|security|US|Security filtering
cleanbrowsing_family|CleanBrowsing Family|185.228.168.168|185.228.169.168|family-filter-dns.cleanbrowsing.org|https://doh.cleanbrowsing.org/doh/family-filter|family|US|Family + adult blocking
controld|Control D|76.76.2.0|76.76.10.0|freedns.controld.com|https://freedns.controld.com/p0|privacy|CA|Canadian, no logs
'
method_status() {
local current_dns1 current_dns2 provider mode
# Get current DNS from dnsmasq/network config
current_dns1=$(uci -q get dhcp.@dnsmasq[0].server 2>/dev/null | awk '{print $1}')
current_dns2=$(uci -q get dhcp.@dnsmasq[0].server 2>/dev/null | awk '{print $2}')
# Check if using local resolver (AdGuard Home)
if netstat -tlnp 2>/dev/null | grep -q ":53.*AdGuard"; then
mode="adguardhome"
elif netstat -tlnp 2>/dev/null | grep -q ":53.*dnsmasq"; then
mode="dnsmasq"
else
mode="unknown"
fi
# Try to identify provider
provider="custom"
echo "$DNS_PROVIDERS" | while IFS='|' read id name primary secondary rest; do
[ -z "$id" ] && continue
if [ "$current_dns1" = "$primary" ] || [ "$current_dns1" = "$secondary" ]; then
provider="$id"
break
fi
done
json_init
json_add_string "mode" "$mode"
json_add_string "provider" "$provider"
json_add_string "primary" "${current_dns1:-auto}"
json_add_string "secondary" "${current_dns2:-}"
json_add_boolean "dot_enabled" "$(uci -q get dhcp.@dnsmasq[0].dnssec 2>/dev/null | grep -q 1 && echo 1 || echo 0)"
json_dump
}
method_get_providers() {
json_init
json_add_array "providers"
echo "$DNS_PROVIDERS" | while IFS='|' read id name primary secondary dot_host doh_url category country description; do
[ -z "$id" ] && continue
json_add_object
json_add_string "id" "$id"
json_add_string "name" "$name"
json_add_string "primary" "$primary"
json_add_string "secondary" "$secondary"
json_add_string "dot_host" "$dot_host"
json_add_string "doh_url" "$doh_url"
json_add_string "category" "$category"
json_add_string "country" "$country"
json_add_string "description" "$description"
json_close_object
done
json_close_array
json_dump
}
method_get_config() {
json_init
# dnsmasq config
json_add_object "dnsmasq"
json_add_string "server1" "$(uci -q get dhcp.@dnsmasq[0].server 2>/dev/null | awk '{print $1}')"
json_add_string "server2" "$(uci -q get dhcp.@dnsmasq[0].server 2>/dev/null | awk '{print $2}')"
json_add_boolean "noresolv" "$(uci -q get dhcp.@dnsmasq[0].noresolv 2>/dev/null | grep -q 1 && echo 1 || echo 0)"
json_close_object
# AdGuard Home config (if present)
if [ -f /var/lib/adguardhome/AdGuardHome.yaml ]; then
json_add_object "adguardhome"
json_add_boolean "installed" 1
json_add_boolean "running" "$(pgrep -f AdGuardHome >/dev/null && echo 1 || echo 0)"
json_close_object
fi
json_dump
}
method_set_provider() {
local provider="$1"
local primary secondary
# Find provider in feed
echo "$DNS_PROVIDERS" | while IFS='|' read id name p1 p2 rest; do
[ -z "$id" ] && continue
if [ "$id" = "$provider" ]; then
primary="$p1"
secondary="$p2"
break
fi
done
if [ -z "$primary" ]; then
json_init
json_add_boolean "success" 0
json_add_string "error" "Unknown provider: $provider"
json_dump
return
fi
# Configure dnsmasq
uci -q delete dhcp.@dnsmasq[0].server
uci add_list dhcp.@dnsmasq[0].server="$primary"
[ -n "$secondary" ] && uci add_list dhcp.@dnsmasq[0].server="$secondary"
uci set dhcp.@dnsmasq[0].noresolv='1'
uci commit dhcp
json_init
json_add_boolean "success" 1
json_add_string "provider" "$provider"
json_add_string "primary" "$primary"
json_add_string "secondary" "$secondary"
json_dump
}
method_smart_config() {
local best_provider best_latency=9999
local test_providers="fdn quad9 cloudflare mullvad"
json_init
json_add_array "results"
for provider in $test_providers; do
local primary
primary=$(echo "$DNS_PROVIDERS" | grep "^${provider}|" | cut -d'|' -f3)
[ -z "$primary" ] && continue
# Test latency
local start end latency
start=$(date +%s%N 2>/dev/null || date +%s)
if nslookup -timeout=2 example.com "$primary" >/dev/null 2>&1; then
end=$(date +%s%N 2>/dev/null || date +%s)
latency=$(( (end - start) / 1000000 ))
[ $latency -lt 0 ] && latency=1
json_add_object
json_add_string "provider" "$provider"
json_add_string "server" "$primary"
json_add_int "latency_ms" "$latency"
json_add_boolean "reachable" 1
json_close_object
if [ "$latency" -lt "$best_latency" ]; then
best_latency="$latency"
best_provider="$provider"
fi
else
json_add_object
json_add_string "provider" "$provider"
json_add_string "server" "$primary"
json_add_int "latency_ms" 0
json_add_boolean "reachable" 0
json_close_object
fi
done
json_close_array
json_add_string "recommended" "${best_provider:-fdn}"
json_add_int "best_latency_ms" "$best_latency"
json_dump
}
method_test_dns() {
local server="$1"
local domain="${2:-example.com}"
json_init
local start end latency
start=$(date +%s%N 2>/dev/null || date +%s)
if result=$(nslookup -timeout=3 "$domain" "$server" 2>&1); then
end=$(date +%s%N 2>/dev/null || date +%s)
latency=$(( (end - start) / 1000000 ))
[ $latency -lt 0 ] && latency=1
json_add_boolean "success" 1
json_add_string "server" "$server"
json_add_string "domain" "$domain"
json_add_int "latency_ms" "$latency"
else
json_add_boolean "success" 0
json_add_string "server" "$server"
json_add_string "error" "DNS query failed"
fi
json_dump
}
method_apply() {
/etc/init.d/dnsmasq restart >/dev/null 2>&1
json_init
json_add_boolean "success" 1
json_add_string "message" "DNS configuration applied"
json_dump
}
# RPC interface
case "$1" in
list)
cat <<'EOF'
{
"status": {},
"get_providers": {},
"get_config": {},
"set_provider": { "provider": "string" },
"smart_config": {},
"test_dns": { "server": "string", "domain": "string" },
"apply": {}
}
EOF
;;
call)
case "$2" in
status) method_status ;;
get_providers) method_get_providers ;;
get_config) method_get_config ;;
set_provider)
read -r input
provider=$(echo "$input" | jsonfilter -e '@.provider')
method_set_provider "$provider"
;;
smart_config) method_smart_config ;;
test_dns)
read -r input
server=$(echo "$input" | jsonfilter -e '@.server')
domain=$(echo "$input" | jsonfilter -e '@.domain')
method_test_dns "$server" "$domain"
;;
apply) method_apply ;;
esac
;;
esac