Update DNS

This commit is contained in:
2025-10-28 15:49:46 +08:00
committed by GitHub
parent dc93f35cce
commit 11673d8323

313
DNS
View File

@@ -9,272 +9,81 @@ 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}"; }
echo -e "${PURPLE}"
echo "=================================================="
echo " 🌈 智能DNS推荐系统"
echo "=================================================="
echo -e "${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}"
# 测试并推荐最佳DNS
test_and_recommend() {
declare -A dns_servers=(
["119.29.29.29"]="腾讯DNS"
["223.5.5.5"]="阿里DNS"
["114.114.114.114"]="114DNS"
["8.8.8.8"]="GoogleDNS"
["1.1.1.1"]="Cloudflare"
)
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
declare -A results
log_info "测试 $provider_name 速度..."
IFS=',' read -ra dns_array <<< "$dns_ips"
echo -e "${BLUE}🧪 测试各DNS性能...${NC}"
for dns_ip in "${dns_array[@]}"; do
if ping -c 2 -W 2 "$dns_ip" >/dev/null 2>&1; then
for dns_ip in "${!dns_servers[@]}"; do
total_time=0
success_count=0
test_domains=("baidu.com" "qq.com" "taobao.com")
for domain in "${test_domains[@]}"; do
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}"
nslookup $domain $dns_ip >/dev/null 2>&1
if [ $? -eq 0 ]; then
end_time=$(date +%s%N)
time_ms=$(( (end_time - start_time) / 1000000 ))
total_time=$(( total_time + time_ms ))
success_count=$(( success_count + 1 ))
fi
done
if [ $success_count -gt 0 ]; then
avg_time=$(( total_time / success_count ))
results[$dns_ip]=$avg_time
echo -e " ${dns_servers[$dns_ip]} ($dns_ip): ${avg_time}ms"
else
echo -e " ${RED}$dns_ip: 无法连接 ❌${NC}"
echo -e " ${RED}${dns_servers[$dns_ip]} ($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]#*:}
# 找出最快的DNS
fastest_ip=""
fastest_time=999999
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]}"
for ip in "${!results[@]}"; do
if [ ${results[$ip]} -lt $fastest_time ]; then
fastest_time=${results[$ip]}
fastest_ip=$ip
fi
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 "无效的选择"
echo -e "\n${GREEN}🎯 推荐使用: ${dns_servers[$fastest_ip]} ($fastest_ip)${NC}"
echo -e "${GREEN}📊 平均解析时间: ${fastest_time}ms${NC}"
# 设置推荐DNS
echo -e "\n${BLUE}🔧 是否设置为推荐DNS${NC}"
read -p "输入 y 确认设置: " confirm
if [ "$confirm" = "y" ]; then
echo "nameserver $fastest_ip" > /etc/resolv.conf
echo "nameserver 223.5.5.5" >> /etc/resolv.conf # 备用
echo -e "${GREEN}✅ 已设置为 ${dns_servers[$fastest_ip]}${NC}"
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
}
test_and_recommend
# 脚本入口
if [ "$(id -u)" -ne 0 ]; then
log_error "请使用root权限运行此脚本"
exit 1
fi
main
echo -e "\n${PURPLE}==================================================${NC}"
echo -e "${CYAN}💡 重要提醒:${NC}"
echo -e "${YELLOW}• DNS只影响域名解析速度${NC}"
echo -e "${YELLOW}• 不影响已经建立连接的网络延迟${NC}"
echo -e "${YELLOW}• 主要提升: 网页第一次打开速度${NC}"
echo -e "${YELLOW}• 不影响: 视频缓冲、游戏延迟、下载速度${NC}"
echo -e "${PURPLE}==================================================${NC}"