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
Back to index

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

  1. Selects DNS provider
  2. Detects interfaces
  3. Applies resolvectl settings
  4. Creates dns-override.service
  5. 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.

Script source
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
Done