Files
dock/DNS
2025-10-28 15:41:35 +08:00

281 lines
8.7 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m'
# 日志函数
log_info() { echo -e "${BLUE}📦 $1${NC}"; }
log_success() { echo -e "${GREEN}$1${NC}"; }
log_warning() { echo -e "${YELLOW}⚠️ $1${NC}"; }
log_error() { echo -e "${RED}$1${NC}"; }
log_result() { echo -e "${CYAN}📊 $1${NC}"; }
# DNS提供商配置
declare -A DNS_PROVIDERS=(
["1"]="腾讯DNS:119.29.29.29,119.28.28.28"
["2"]="阿里DNS:223.5.5.5,223.6.6.6"
["3"]="114DNS:114.114.114.114,114.114.115.115"
["4"]="Cloudflare:1.1.1.1,1.0.0.1"
["5"]="GoogleDNS:8.8.8.8,8.8.4.4"
["6"]="OpenDNS:208.67.222.222,208.67.220.220"
["7"]="百度DNS:180.76.76.76"
["8"]="CNNICSDNS:1.2.4.8,210.2.4.8"
)
# 检测当前DNS
detect_current_dns() {
echo -e "${PURPLE}"
echo "=================================================="
echo " 🌈 当前DNS检测结果"
echo "=================================================="
echo -e "${NC}"
if [ -f /etc/resolv.conf ]; then
current_dns=$(grep -E '^nameserver' /etc/resolv.conf | awk '{print $2}' | tr '\n' ' ')
if [ -n "$current_dns" ]; then
log_result "当前DNS服务器: $current_dns"
# 识别DNS提供商
for provider in "${!DNS_PROVIDERS[@]}"; do
dns_ips=${DNS_PROVIDERS[$provider]#*:}
primary_dns=${dns_ips%,*}
if [[ "$current_dns" == *"$primary_dns"* ]]; then
provider_name=${DNS_PROVIDERS[$provider]%:*}
log_success "识别为: $provider_name"
break
fi
done
else
log_warning "未检测到DNS配置"
fi
else
log_error "未找到 resolv.conf 文件"
fi
echo ""
}
# 测试DNS速度
test_dns_speed() {
local dns_ips=$1
local provider_name=$2
log_info "测试 $provider_name 速度..."
IFS=',' read -ra dns_array <<< "$dns_ips"
for dns_ip in "${dns_array[@]}"; do
if ping -c 2 -W 2 "$dns_ip" >/dev/null 2>&1; then
start_time=$(date +%s%N)
nslookup baidu.com "$dns_ip" >/dev/null 2>&1
end_time=$(date +%s%N)
time_ms=$(( (end_time - start_time) / 1000000 ))
if [ $time_ms -lt 50 ]; then
echo -e " ${GREEN}$dns_ip: ${time_ms}ms ✅${NC}"
elif [ $time_ms -lt 100 ]; then
echo -e " ${YELLOW}$dns_ip: ${time_ms}ms ⚠️${NC}"
else
echo -e " ${RED}$dns_ip: ${time_ms}ms ❌${NC}"
fi
else
echo -e " ${RED}$dns_ip: 无法连接 ❌${NC}"
fi
done
}
# 显示DNS菜单
show_dns_menu() {
echo -e "${PURPLE}"
echo "=================================================="
echo " 🌈 主流DNS提供商"
echo "=================================================="
echo -e "${NC}"
for key in "${!DNS_PROVIDERS[@]}"; do
provider_name=${DNS_PROVIDERS[$key]%:*}
dns_ips=${DNS_PROVIDERS[$key]#*:}
echo -e " ${CYAN}$key. $provider_name${NC}"
echo -e " ${BLUE}$dns_ips${NC}"
done
echo ""
}
# 临时设置DNS
set_dns_temporary() {
local provider_key=$1
local provider_name=${DNS_PROVIDERS[$provider_key]%:*}
local dns_ips=${DNS_PROVIDERS[$provider_key]#*:}
log_info "临时设置为: $provider_name"
# 备份当前配置
cp /etc/resolv.conf /etc/resolv.conf.backup.$(date +%Y%m%d_%H%M%S)
# 生成新的resolv.conf
echo "# 临时设置 - $provider_name ($(date))" > /etc/resolv.conf
IFS=',' read -ra dns_array <<< "$dns_ips"
for dns_ip in "${dns_array[@]}"; do
echo "nameserver $dns_ip" >> /etc/resolv.conf
done
echo "options timeout:2 attempts:3" >> /etc/resolv.conf
log_success "临时DNS设置完成 (重启后恢复)"
}
# 永久设置DNS
set_dns_permanent() {
local provider_key=$1
local provider_name=${DNS_PROVIDERS[$provider_key]%:*}
local dns_ips=${DNS_PROVIDERS[$provider_key]#*:}
log_info "永久设置为: $provider_name"
# 备份当前配置
cp /etc/resolv.conf /etc/resolv.conf.backup.$(date +%Y%m%d_%H%M%S)
# 检查并禁用systemd-resolved
if systemctl is-active systemd-resolved >/dev/null 2>&1; then
log_warning "检测到systemd-resolved正在禁用..."
systemctl stop systemd-resolved
systemctl disable systemd-resolved
fi
# 生成永久配置
echo "# 永久设置 - $provider_name ($(date))" > /etc/resolv.conf
IFS=',' read -ra dns_array <<< "$dns_ips"
for dns_ip in "${dns_array[@]}"; do
echo "nameserver $dns_ip" >> /etc/resolv.conf
done
echo "options timeout:2 attempts:3" >> /etc/resolv.conf
# 防止NetworkManager覆盖
if command -v NetworkManager >/dev/null 2>&1; then
log_info "配置NetworkManager..."
nmcli connection show | grep -v NAME | awk '{print $1}' | while read conn; do
nmcli connection modify "$conn" ipv4.ignore-auto-dns yes
for dns_ip in "${dns_array[@]}"; do
nmcli connection modify "$conn" ipv4.dns "$dns_ip"
done
done
fi
# 设置文件属性防止被覆盖
chattr +i /etc/resolv.conf 2>/dev/null || true
log_success "永久DNS设置完成"
}
# 恢复备份
restore_backup() {
local backup_files=($(ls -t /etc/resolv.conf.backup.* 2>/dev/null))
if [ ${#backup_files[@]} -eq 0 ]; then
log_error "未找到备份文件"
return 1
fi
echo -e "${YELLOW}可用的备份文件:${NC}"
for i in "${!backup_files[@]}"; do
echo " $((i+1)). ${backup_files[$i]}"
done
read -p "选择要恢复的备份编号 (1-${#backup_files[@]}): " backup_choice
if [[ $backup_choice =~ ^[0-9]+$ ]] && [ $backup_choice -ge 1 ] && [ $backup_choice -le ${#backup_files[@]} ]; then
selected_backup="${backup_files[$((backup_choice-1))]}"
# 解除文件锁定
chattr -i /etc/resolv.conf 2>/dev/null || true
cp "$selected_backup" /etc/resolv.conf
log_success "已从 $selected_backup 恢复DNS设置"
else
log_error "无效的选择"
fi
}
# 主函数
main() {
# 检测当前DNS
detect_current_dns
while true; do
echo -e "${PURPLE}"
echo "=================================================="
echo " 🌈 DNS切换管理脚本"
echo "=================================================="
echo -e "${NC}"
echo -e "${CYAN}请选择操作:${NC}"
echo " 1. 切换DNS提供商"
echo " 2. 测试所有DNS速度"
echo " 3. 恢复DNS备份"
echo " 4. 显示当前DNS"
echo " 5. 退出"
echo ""
read -p "请输入选择 (1-5): " main_choice
case $main_choice in
1)
show_dns_menu
read -p "选择DNS提供商 (1-8): " dns_choice
if [[ -n "${DNS_PROVIDERS[$dns_choice]}" ]]; then
echo ""
echo -e "${CYAN}请选择设置方式:${NC}"
echo " 1. 临时设置 (重启后失效)"
echo " 2. 永久设置"
read -p "请输入选择 (1-2): " set_type
case $set_type in
1) set_dns_temporary "$dns_choice" ;;
2) set_dns_permanent "$dns_choice" ;;
*) log_error "无效的选择" ;;
esac
else
log_error "无效的DNS选择"
fi
;;
2)
echo ""
log_info "测试所有DNS提供商速度..."
for key in "${!DNS_PROVIDERS[@]}"; do
provider_name=${DNS_PROVIDERS[$key]%:*}
dns_ips=${DNS_PROVIDERS[$key]#*:}
test_dns_speed "$dns_ips" "$provider_name"
echo ""
done
;;
3)
restore_backup
;;
4)
detect_current_dns
;;
5)
log_success "再见!"
exit 0
;;
*)
log_error "无效的选择"
;;
esac
echo ""
read -p "按回车键继续..."
clear
done
}
# 脚本入口
if [ "$(id -u)" -ne 0 ]; then
log_error "请使用root权限运行此脚本"
exit 1
fi
main