Script 10 · DNS
10. Auto-Detect Interface & Force DNS (Anti-DHCP)
Forces physical interfaces to use Cloudflare or Google DNS through systemd-resolved and persists it with a systemd service.
Category: DNS
Risk: Medium
Lines: calculating
Language: Bash / Linux
What this script does
- Avoid slow DHCP-provided DNS.
- Standardize resolver behavior across network restarts.
- Disable LLMNR/mDNS on selected interfaces.
Prerequisites
- Root access
- systemd-resolved active
- Physical interface detection compatible with VPS naming
Execution flow
- Selects DNS provider
- Detects interfaces
- Applies resolvectl settings
- Creates dns-override.service
- Verifies per-interface DNS
Validation checklist
- resolvectl status
- systemctl status dns-override.service
- dig example.com
Operational cautions
- Forcing DNS can conflict with private DNS/VPN environments.
- Some VPS images do not use systemd-resolved.
Original script notes
ℹ️ Script Info: Forces physical network interfaces to use high-speed public DNS (like Cloudflare or Google), bypassing slow or restrictive default DHCP-assigned DNS servers.
cat << 'EOF' > auto_dns_override.sh && chmod +x auto_dns_override.sh && ./auto_dns_override.sh
#!/bin/bash
# --- CONFIGURATION ---
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
clear
echo -e "${BLUE}=======================================================${NC}"
echo -e "${BLUE} AUTO DNS OVERRIDE & VERIFICATION TOOL ${NC}"
echo -e "${BLUE} (Detects Interface -> Applies DNS -> Verifies) ${NC}"
echo -e "${BLUE}=======================================================${NC}"
# 1. Root Check
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}[!] Please run as root (sudo).${NC}"
exit 1
fi
# 2. User Selection
echo -e "${YELLOW}[?] Select DNS Server:${NC}"
echo -e " 1) ${GREEN}Cloudflare (1.1.1.1)${NC} -> Recommended for Gaming/Speed"
echo -e " 2) ${GREEN}Google (8.8.8.8)${NC} -> Recommended for Browsing/Stability"
read -p " Enter selection [1-2] (Default: 1): " DNS_CHOICE
# Set Variables based on choice
if [[ "$DNS_CHOICE" == "2" ]]; then
target_dns_ips="8.8.8.8 8.8.4.4"
target_dns_name="Google"
check_ip="8.8.8.8"
else
target_dns_ips="1.1.1.1 1.0.0.1"
target_dns_name="Cloudflare"
check_ip="1.1.1.1"
fi
echo -e "\n${BLUE}[+] Selected Target: $target_dns_name ($target_dns_ips)${NC}"
# 3. Auto-Detect Interfaces
# Filter: Exclude loopback, tunnels, docker, wireguard, tailscale, bridges
echo -e "${YELLOW}[1/4] Detecting Physical Interfaces...${NC}"
INTERFACES=$(ip -o link show | awk -F': ' '{print $2}' | grep -vE "lo|^wg|^tun|^docker|^tailscale|^br-|^virbr|^veth")
if [ -z "$INTERFACES" ]; then
echo -e "${RED}[!] Error: No physical interfaces detected.${NC}"
exit 1
fi
echo -e "${GREEN} -> Detected: $INTERFACES${NC}"
# 4. Apply Settings (Runtime & Persistence)
echo -e "${YELLOW}[2/4] Applying DNS Override...${NC}"
# Loop through interfaces and apply runtime config
for iface in $INTERFACES; do
echo -e " -> Configuring interface: ${GREEN}$iface${NC}..."
resolvectl dns $iface $target_dns_ips
resolvectl domain $iface "~."
# Optimization
resolvectl llmnr $iface no
resolvectl mdns $iface no
done
# Create Systemd Service for Persistence
echo -e "${YELLOW}[3/4] Creating Startup Service (Persistence)...${NC}"
SERVICE_FILE="/etc/systemd/system/dns-override.service"
cat <<SERVICE > $SERVICE_FILE
[Unit]
Description=Force $target_dns_name DNS on Physical Interfaces
After=network-online.target systemd-resolved.service
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/bin/bash -c 'for iface in \$(ip -o link show | awk -F": " "{print \$2}" | grep -vE "lo|^wg|^tun|^docker|^tailscale|^br-|^virbr|^veth"); do resolvectl dns \$iface $target_dns_ips; resolvectl domain \$iface "~."; done'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
SERVICE
systemctl daemon-reload
systemctl enable dns-override.service > /dev/null 2>&1
systemctl restart dns-override.service
# 5. Verification & Final Check
echo -e "${YELLOW}[4/4] Verifying Configuration...${NC}"
sleep 2 # Wait for settings to apply
echo -e "\n${BLUE}--- DIAGNOSTIC RESULTS ---${NC}"
OVERALL_STATUS="PASS"
for iface in $INTERFACES; do
# Get DNS status from interface
CURRENT_STATUS=$(resolvectl status $iface 2>/dev/null)
# Check if target IP exists in output
if echo "$CURRENT_STATUS" | grep -q "$check_ip"; then
echo -e "Interface ${GREEN}$iface${NC}: [ ${GREEN}MATCH / OK${NC} ]"
echo -e " -> Current DNS: $(echo "$CURRENT_STATUS" | grep "Current DNS Server" | xargs)"
else
echo -e "Interface ${RED}$iface${NC}: [ ${RED}MISMATCH / FAIL${NC} ]"
echo -e " -> Detail: Settings unchanged. Check DHCP client config."
OVERALL_STATUS="FAIL"
fi
done
echo -e "${BLUE}----------------------${NC}"
if [ "$OVERALL_STATUS" == "PASS" ]; then
echo -e "\n${GREEN}[SUCCESS] Configuration for $target_dns_name successfully applied to all interfaces.${NC}"
else
echo -e "\n${RED}[WARNING] Some interfaces failed to apply.${NC}"
fi
# Show raw status for user
echo -e "\n${YELLOW}Running 'resolvectl status' for your inspection:${NC}"
resolvectl status $INTERFACES
EOF