646 lines
19 KiB
Bash
646 lines
19 KiB
Bash
#!/bin/bash
|
||
#
|
||
# Stream Unlock Installer
|
||
# 流媒体/AI 解锁一键脚本
|
||
#
|
||
# 解锁机:安装 sniproxy,提供 DNS 解锁服务
|
||
# 被解锁机:安装 smartdns,分流指定服务到解锁机
|
||
#
|
||
|
||
set -e
|
||
|
||
# 颜色定义
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m'
|
||
|
||
# 服务域名配置
|
||
declare -A SERVICE_DOMAINS
|
||
|
||
# 流媒体全家桶
|
||
SERVICE_DOMAINS["stream"]="netflix.com netflix.net nflximg.com nflximg.net nflxvideo.net nflxext.com nflxso.net
|
||
disneyplus.com disney-plus.net dssott.com bamgrid.com
|
||
hbomax.com hbo.com hbogo.com hbonow.com
|
||
primevideo.com amazon.com amazon.co.jp amazon.co.uk
|
||
paramountplus.com cbs.com
|
||
peacocktv.com nbc.com
|
||
apple.com apple-tv.com
|
||
crunchyroll.com funimation.com
|
||
tvb.com tvbanywhere.com
|
||
bilibili.com bilibili.tv
|
||
iq.com iqiyi.com
|
||
youku.com"
|
||
|
||
# AI 服务
|
||
SERVICE_DOMAINS["ai"]="openai.com chatgpt.com ai.com
|
||
anthropic.com claude.ai
|
||
gemini.google.com generativelanguage.googleapis.com
|
||
copilot.microsoft.com
|
||
perplexity.ai
|
||
midjourney.com
|
||
character.ai
|
||
poe.com"
|
||
|
||
# 短视频
|
||
SERVICE_DOMAINS["shorts"]="tiktok.com tiktokv.com tiktokcdn.com tiktokcdn-us.com byteoversea.com musical.ly
|
||
youtube.com youtu.be ytimg.com googlevideo.com youtubei.googleapis.com youtube-nocookie.com"
|
||
|
||
# Spotify
|
||
SERVICE_DOMAINS["spotify"]="spotify.com scdn.co spotifycdn.com spotifycdn.net"
|
||
|
||
# 游戏相关
|
||
SERVICE_DOMAINS["game"]="playstation.com playstation.net psn.com
|
||
xbox.com xboxlive.com
|
||
nintendo.com nintendo.net
|
||
steam.com steampowered.com steamcommunity.com steamstatic.com
|
||
epicgames.com epicgames.net"
|
||
|
||
# ChatGPT 详细域名
|
||
SERVICE_DOMAINS["chatgpt"]="openai.com chatgpt.com ai.com oaistatic.com oaiusercontent.com auth0.openai.com"
|
||
|
||
# Claude 详细域名
|
||
SERVICE_DOMAINS["claude"]="anthropic.com claude.ai statsig.anthropic.com sentry.io"
|
||
|
||
# ============ 工具函数 ============
|
||
|
||
print_banner() {
|
||
echo -e "${BLUE}"
|
||
echo "╔═══════════════════════════════════════════╗"
|
||
echo "║ Stream Unlock Installer v1.0 ║"
|
||
echo "║ 流媒体/AI 解锁一键脚本 ║"
|
||
echo "╚═══════════════════════════════════════════╝"
|
||
echo -e "${NC}"
|
||
}
|
||
|
||
check_root() {
|
||
if [[ $EUID -ne 0 ]]; then
|
||
echo -e "${RED}请使用 root 用户运行此脚本${NC}"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
detect_os() {
|
||
if [[ -f /etc/debian_version ]]; then
|
||
OS="debian"
|
||
PKG_MANAGER="apt"
|
||
elif [[ -f /etc/redhat-release ]]; then
|
||
OS="centos"
|
||
PKG_MANAGER="yum"
|
||
elif [[ -f /etc/arch-release ]]; then
|
||
OS="arch"
|
||
PKG_MANAGER="pacman"
|
||
else
|
||
# 尝试检测其他系统
|
||
if command -v apt &>/dev/null; then
|
||
OS="debian"
|
||
PKG_MANAGER="apt"
|
||
elif command -v yum &>/dev/null; then
|
||
OS="centos"
|
||
PKG_MANAGER="yum"
|
||
elif command -v pacman &>/dev/null; then
|
||
OS="arch"
|
||
PKG_MANAGER="pacman"
|
||
else
|
||
echo -e "${RED}不支持的系统,请手动安装 sniproxy${NC}"
|
||
echo -e "${YELLOW}支持的系统: Debian/Ubuntu, CentOS/RHEL, Arch Linux${NC}"
|
||
exit 1
|
||
fi
|
||
fi
|
||
echo -e "${GREEN}检测到系统: $OS${NC}"
|
||
}
|
||
|
||
get_public_ip() {
|
||
local ip=""
|
||
ip=$(curl -s4 ip.sb 2>/dev/null) || \
|
||
ip=$(curl -s4 ifconfig.me 2>/dev/null) || \
|
||
ip=$(curl -s4 api.ipify.org 2>/dev/null)
|
||
echo "$ip"
|
||
}
|
||
|
||
# ============ 解锁机安装 ============
|
||
|
||
install_sniproxy() {
|
||
echo -e "${GREEN}[解锁机] 安装 sniproxy...${NC}"
|
||
echo -e "${YELLOW}系统类型: $OS${NC}"
|
||
|
||
# 安装依赖
|
||
if [[ "$OS" == "debian" ]]; then
|
||
apt update
|
||
# 先尝试直接安装
|
||
if ! apt install -y sniproxy 2>/dev/null; then
|
||
echo -e "${YELLOW}sniproxy 不在默认仓库,从源码编译...${NC}"
|
||
# 安装编译依赖
|
||
apt install -y build-essential libev-dev libudns-dev pkg-config git
|
||
# 克隆并编译
|
||
cd /tmp
|
||
git clone https://github.com/dlundquist/sniproxy.git
|
||
cd sniproxy
|
||
./configure --prefix=/usr
|
||
make -j$(nproc)
|
||
make install
|
||
# 创建 systemd 服务
|
||
cat > /etc/systemd/system/sniproxy.service << 'SERVICE'
|
||
[Unit]
|
||
Description=sniproxy
|
||
After=network.target
|
||
|
||
[Service]
|
||
Type=forking
|
||
ExecStart=/usr/sbin/sniproxy -c /etc/sniproxy.conf
|
||
PIDFile=/var/run/sniproxy.pid
|
||
Restart=on-failure
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
SERVICE
|
||
systemctl daemon-reload
|
||
cd /
|
||
rm -rf /tmp/sniproxy
|
||
fi
|
||
apt install -y dnsmasq ufw
|
||
elif [[ "$OS" == "centos" ]]; then
|
||
yum install -y epel-release
|
||
yum install -y sniproxy dnsmasq firewalld
|
||
elif [[ "$OS" == "arch" ]]; then
|
||
pacman -Sy --noconfirm sniproxy dnsmasq ufw
|
||
else
|
||
echo -e "${RED}不支持的系统: $OS${NC}"
|
||
echo -e "${YELLOW}请手动安装 sniproxy 和 dnsmasq${NC}"
|
||
return 1
|
||
fi
|
||
|
||
# 备份原配置
|
||
[[ -f /etc/sniproxy.conf ]] && cp /etc/sniproxy.conf /etc/sniproxy.conf.bak
|
||
|
||
# 创建 sniproxy 配置
|
||
cat > /etc/sniproxy.conf << 'EOF'
|
||
user daemon
|
||
pidfile /var/run/sniproxy.pid
|
||
|
||
listener 80 {
|
||
proto http
|
||
access_log {
|
||
filename /var/log/sniproxy/http_access.log
|
||
}
|
||
}
|
||
|
||
listener 443 {
|
||
proto tls
|
||
access_log {
|
||
filename /var/log/sniproxy/https_access.log
|
||
}
|
||
}
|
||
|
||
table {
|
||
# 流媒体
|
||
netflix.* *
|
||
disneyplus.* *
|
||
hbo.* *
|
||
primevideo.* *
|
||
|
||
# AI
|
||
openai.* *
|
||
chatgpt.* *
|
||
anthropic.* *
|
||
claude.* *
|
||
gemini.* *
|
||
|
||
# 短视频
|
||
tiktok.* *
|
||
youtube.* *
|
||
ytimg.* *
|
||
|
||
# 默认
|
||
.* *
|
||
}
|
||
EOF
|
||
|
||
# 创建日志目录
|
||
mkdir -p /var/log/sniproxy
|
||
chmod 755 /var/log/sniproxy
|
||
|
||
# 配置防火墙
|
||
configure_firewall_unlocker
|
||
|
||
# 启动服务
|
||
systemctl enable sniproxy
|
||
systemctl restart sniproxy
|
||
|
||
echo -e "${GREEN}[解锁机] sniproxy 安装完成${NC}"
|
||
}
|
||
|
||
configure_firewall_unlocker() {
|
||
echo -e "${GREEN}[解锁机] 配置防火墙白名单...${NC}"
|
||
|
||
local allowed_ips=""
|
||
while true; do
|
||
read -p "输入要放行的被解锁机 IP(输入 done 结束): " ip
|
||
[[ "$ip" == "done" ]] && break
|
||
[[ -z "$ip" ]] && continue
|
||
|
||
if [[ "$OS" == "debian" ]]; then
|
||
ufw allow from "$ip" to any port 80
|
||
ufw allow from "$ip" to any port 443
|
||
ufw allow from "$ip" to any port 53
|
||
else
|
||
firewall-cmd --permanent --add-rich-rule="rule family=ipv4 source address=$ip port protocol=tcp port=80 accept"
|
||
firewall-cmd --permanent --add-rich-rule="rule family=ipv4 source address=$ip port protocol=tcp port=443 accept"
|
||
firewall-cmd --permanent --add-rich-rule="rule family=ipv4 source address=$ip port protocol=udp port=53 accept"
|
||
fi
|
||
|
||
allowed_ips="$allowed_ips $ip"
|
||
echo -e "${GREEN}已添加: $ip${NC}"
|
||
done
|
||
|
||
# 开放本地 DNS
|
||
if [[ "$OS" == "debian" ]]; then
|
||
ufw allow 53/udp
|
||
ufw allow 53/tcp
|
||
ufw --force enable
|
||
else
|
||
firewall-cmd --permanent --add-port=53/udp
|
||
firewall-cmd --permanent --add-port=53/tcp
|
||
firewall-cmd --reload
|
||
fi
|
||
|
||
echo -e "${GREEN}[解锁机] 防火墙配置完成,已放行:$allowed_ips${NC}"
|
||
}
|
||
|
||
add_service_to_sniproxy() {
|
||
local service_type="$1"
|
||
local domains="${SERVICE_DOMAINS[$service_type]}"
|
||
|
||
if [[ -z "$domains" ]]; then
|
||
echo -e "${RED}未知服务类型: $service_type${NC}"
|
||
return 1
|
||
fi
|
||
|
||
echo -e "${GREEN}添加服务到 sniproxy: $service_type${NC}"
|
||
|
||
# 为每个域名添加规则
|
||
for domain in $domains; do
|
||
# 提取主域名作为模式
|
||
local pattern="${domain%%.*}.*"
|
||
|
||
# 检查是否已存在
|
||
if ! grep -q "$pattern" /etc/sniproxy.conf 2>/dev/null; then
|
||
# 在 table 块中添加
|
||
sed -i "/table {/a\\ $pattern *" /etc/sniproxy.conf
|
||
echo " 添加: $pattern"
|
||
else
|
||
echo " 已存在: $pattern"
|
||
fi
|
||
done
|
||
|
||
# 重启服务
|
||
systemctl restart sniproxy
|
||
echo -e "${GREEN}sniproxy 已重启${NC}"
|
||
}
|
||
|
||
# ============ 被解锁机安装 ============
|
||
|
||
install_smartdns() {
|
||
echo -e "${GREEN}[被解锁机] 安装 smartdns...${NC}"
|
||
|
||
# 方法1: 尝试 apt 安装
|
||
if [[ "$OS" == "debian" ]]; then
|
||
# 添加 smartdns 官方源或直接安装
|
||
if apt install -y smartdns 2>/dev/null; then
|
||
echo -e "${GREEN}通过 apt 安装 smartdns 成功${NC}"
|
||
else
|
||
echo -e "${YELLOW}apt 安装失败,尝试手动下载...${NC}"
|
||
|
||
# 获取最新版本
|
||
local latest_url=$(curl -s https://api.github.com/repos/pymumu/smartdns/releases/latest | grep 'browser_download_url.*x86_64-linux-all.tar.gz' | head -1 | cut -d'"' -f4)
|
||
|
||
if [[ -z "$latest_url" ]]; then
|
||
# 备用下载地址
|
||
latest_url="https://github.com/pymumu/smartdns/releases/download/Release45/smartdns.1.2024.08.08-1827.x86_64-linux-all.tar.gz"
|
||
fi
|
||
|
||
echo -e "${YELLOW}下载: $latest_url${NC}"
|
||
local tmp_dir="/tmp/smartdns"
|
||
mkdir -p "$tmp_dir"
|
||
cd "$tmp_dir"
|
||
|
||
if curl -sL "$latest_url" -o smartdns.tar.gz && tar -xzf smartdns.tar.gz; then
|
||
chmod +x smartdns
|
||
./smartdns install -u
|
||
else
|
||
echo -e "${RED}下载安装失败,请手动安装 smartdns${NC}"
|
||
echo -e "${YELLOW}参考: https://github.com/pymumu/smartdns${NC}"
|
||
return 1
|
||
fi
|
||
|
||
cd -
|
||
rm -rf "$tmp_dir"
|
||
fi
|
||
elif [[ "$OS" == "centos" ]]; then
|
||
# CentOS 尝试 yum 或手动下载
|
||
if ! yum install -y smartdns 2>/dev/null; then
|
||
local latest_url=$(curl -s https://api.github.com/repos/pymumu/smartdns/releases/latest | grep 'browser_download_url.*x86_64-linux-all.tar.gz' | head -1 | cut -d'"' -f4)
|
||
[[ -z "$latest_url" ]] && latest_url="https://github.com/pymumu/smartdns/releases/download/Release45/smartdns.1.2024.08.08-1827.x86_64-linux-all.tar.gz"
|
||
|
||
local tmp_dir="/tmp/smartdns"
|
||
mkdir -p "$tmp_dir"
|
||
cd "$tmp_dir"
|
||
curl -sL "$latest_url" -o smartdns.tar.gz && tar -xzf smartdns.tar.gz && chmod +x smartdns && ./smartdns install -u
|
||
cd -
|
||
rm -rf "$tmp_dir"
|
||
fi
|
||
else
|
||
echo -e "${RED}不支持的系统,请手动安装 smartdns${NC}"
|
||
return 1
|
||
fi
|
||
|
||
# 备份原配置
|
||
[[ -f /etc/smartdns/smartdns.conf ]] && cp /etc/smartdns/smartdns.conf /etc/smartdns/smartdns.conf.bak
|
||
|
||
# 创建基础配置
|
||
mkdir -p /etc/smartdns
|
||
cat > /etc/smartdns/smartdns.conf << 'EOF'
|
||
# SmartDNS 配置
|
||
|
||
# 监听端口
|
||
bind :53
|
||
|
||
# 上游 DNS
|
||
server 8.8.8.8 -group default
|
||
server 1.1.1.1 -group default
|
||
server 223.5.5.5 -group default
|
||
|
||
# 缓存配置
|
||
cache-size 4096
|
||
cache-persist yes
|
||
prefetch-domain yes
|
||
|
||
# 日志
|
||
log-level info
|
||
EOF
|
||
|
||
echo -e "${GREEN}[被解锁机] smartdns 安装完成${NC}"
|
||
}
|
||
|
||
configure_smartdns_unlocker() {
|
||
local unlocker_ip="$1"
|
||
local service_type="$2"
|
||
local domains="${SERVICE_DOMAINS[$service_type]}"
|
||
|
||
if [[ -z "$domains" ]]; then
|
||
echo -e "${RED}未知服务类型: $service_type${NC}"
|
||
return 1
|
||
fi
|
||
|
||
echo -e "${GREEN}配置分流规则: $service_type -> $unlocker_ip${NC}"
|
||
|
||
local conf_file="/etc/smartdns/smartdns.conf"
|
||
|
||
# 添加注释
|
||
echo "" >> "$conf_file"
|
||
echo "# $service_type 解锁规则 - $(date)" >> "$conf_file"
|
||
|
||
# 为每个域名添加 address 规则
|
||
for domain in $domains; do
|
||
echo "address /$domain/$unlocker_ip" >> "$conf_file"
|
||
echo " 添加: $domain -> $unlocker_ip"
|
||
done
|
||
|
||
echo -e "${GREEN}分流规则已添加${NC}"
|
||
}
|
||
|
||
restart_smartdns() {
|
||
systemctl daemon-reload
|
||
systemctl enable smartdns
|
||
systemctl restart smartdns
|
||
|
||
# 设置系统 DNS
|
||
if command -v resolvconf &>/dev/null; then
|
||
echo "nameserver 127.0.0.1" | resolvconf -a lo.smartdns
|
||
else
|
||
# 备份原 DNS 配置
|
||
cp /etc/resolv.conf /etc/resolv.conf.bak 2>/dev/null || true
|
||
echo "nameserver 127.0.0.1" > /etc/resolv.conf
|
||
# 防止被覆盖
|
||
chattr +i /etc/resolv.conf 2>/dev/null || true
|
||
fi
|
||
|
||
echo -e "${GREEN}smartdns 已启动并设为系统 DNS${NC}"
|
||
}
|
||
|
||
# ============ 服务选择菜单 ============
|
||
|
||
select_services() {
|
||
local selected=()
|
||
|
||
echo ""
|
||
echo -e "${YELLOW}选择要解锁的服务(可多选,空格分隔):${NC}"
|
||
echo " 1) 流媒体全家桶 (Netflix, Disney+, HBO, Prime...)"
|
||
echo " 2) AI 服务 (ChatGPT, Claude, Gemini...)"
|
||
echo " 3) 短视频 (TikTok, YouTube)"
|
||
echo " 4) Spotify"
|
||
echo " 5) 游戏服务 (Steam, PlayStation, Xbox...)"
|
||
echo " 6) ChatGPT 详细"
|
||
echo " 7) Claude 详细"
|
||
echo " 8) 全部"
|
||
echo ""
|
||
|
||
read -p "请输入选项 (如: 1 2 3): " choices
|
||
|
||
for choice in $choices; do
|
||
case $choice in
|
||
1) selected+=("stream") ;;
|
||
2) selected+=("ai") ;;
|
||
3) selected+=("shorts") ;;
|
||
4) selected+=("spotify") ;;
|
||
5) selected+=("game") ;;
|
||
6) selected+=("chatgpt") ;;
|
||
7) selected+=("claude") ;;
|
||
8) selected=("stream" "ai" "shorts" "spotify" "game" "chatgpt" "claude"); break ;;
|
||
*) echo -e "${RED}无效选项: $choice${NC}" ;;
|
||
esac
|
||
done
|
||
|
||
echo "${selected[@]}"
|
||
}
|
||
|
||
# ============ 主菜单 ============
|
||
|
||
menu_unlocker() {
|
||
clear
|
||
print_banner
|
||
|
||
local my_ip=$(get_public_ip)
|
||
echo -e "本机 IP: ${GREEN}$my_ip${NC}"
|
||
echo ""
|
||
echo -e "${YELLOW}[解锁机模式]${NC}"
|
||
echo " 1) 安装 sniproxy(首次安装)"
|
||
echo " 2) 添加被解锁机 IP 白名单"
|
||
echo " 3) 添加解锁服务"
|
||
echo " 4) 查看当前配置"
|
||
echo " 5) 卸载 sniproxy"
|
||
echo ""
|
||
|
||
read -p "请选择: " choice
|
||
|
||
case $choice in
|
||
1)
|
||
install_sniproxy
|
||
# 解锁机不需要选服务,sniproxy 配置已包含常见域名
|
||
echo -e "${GREEN}解锁机配置完成!${NC}"
|
||
echo -e "${YELLOW}下一步:在被解锁机上运行此脚本,选择「被解锁机」模式${NC}"
|
||
;;
|
||
2)
|
||
configure_firewall_unlocker
|
||
;;
|
||
3)
|
||
local services=$(select_services)
|
||
for svc in $services; do
|
||
add_service_to_sniproxy "$svc"
|
||
done
|
||
;;
|
||
4)
|
||
echo -e "${GREEN}sniproxy 配置:${NC}"
|
||
cat /etc/sniproxy.conf 2>/dev/null || echo "配置文件不存在"
|
||
echo ""
|
||
echo -e "${GREEN}防火墙规则:${NC}"
|
||
if [[ "$OS" == "debian" ]]; then
|
||
ufw status
|
||
else
|
||
firewall-cmd --list-all
|
||
fi
|
||
;;
|
||
5)
|
||
echo -e "${RED}确定要卸载 sniproxy?(y/n): ${NC}"
|
||
read -p "" confirm
|
||
[[ "$confirm" == "y" ]] && {
|
||
systemctl stop sniproxy
|
||
systemctl disable sniproxy
|
||
apt remove -y sniproxy 2>/dev/null || yum remove -y sniproxy 2>/dev/null
|
||
rm -f /etc/sniproxy.conf
|
||
echo -e "${GREEN}sniproxy 已卸载${NC}"
|
||
}
|
||
;;
|
||
*)
|
||
echo -e "${RED}无效选项${NC}"
|
||
;;
|
||
esac
|
||
}
|
||
|
||
menu_client() {
|
||
clear
|
||
print_banner
|
||
|
||
local my_ip=$(get_public_ip)
|
||
echo -e "本机 IP: ${GREEN}$my_ip${NC}"
|
||
echo ""
|
||
echo -e "${YELLOW}[被解锁机模式]${NC}"
|
||
echo " 1) 安装 smartdns 并配置分流(首次安装)"
|
||
echo " 2) 添加新的分流服务"
|
||
echo " 3) 查看当前配置"
|
||
echo " 4) 测试解锁"
|
||
echo " 5) 卸载 smartdns"
|
||
echo ""
|
||
|
||
read -p "请选择: " choice
|
||
|
||
case $choice in
|
||
1)
|
||
install_smartdns
|
||
|
||
echo ""
|
||
read -p "输入解锁机 IP: " unlocker_ip
|
||
[[ -z "$unlocker_ip" ]] && {
|
||
echo -e "${RED}解锁机 IP 不能为空${NC}"
|
||
return 1
|
||
}
|
||
|
||
local services=$(select_services)
|
||
for svc in $services; do
|
||
configure_smartdns_unlocker "$unlocker_ip" "$svc"
|
||
done
|
||
|
||
restart_smartdns
|
||
|
||
echo ""
|
||
echo -e "${GREEN}配置完成!${NC}"
|
||
echo "解锁机: $unlocker_ip"
|
||
echo "分流服务: $services"
|
||
;;
|
||
2)
|
||
local current_unlocker=$(grep "address /netflix.com/" /etc/smartdns/smartdns.conf 2>/dev/null | head -1 | awk -F'/' '{print $3}')
|
||
|
||
if [[ -z "$current_unlocker" ]]; then
|
||
read -p "输入解锁机 IP: " unlocker_ip
|
||
else
|
||
read -p "解锁机 IP [$current_unlocker]: " unlocker_ip
|
||
unlocker_ip=${unlocker_ip:-$current_unlocker}
|
||
fi
|
||
|
||
local services=$(select_services)
|
||
for svc in $services; do
|
||
configure_smartdns_unlocker "$unlocker_ip" "$svc"
|
||
done
|
||
|
||
restart_smartdns
|
||
;;
|
||
3)
|
||
echo -e "${GREEN}smartdns 配置:${NC}"
|
||
cat /etc/smartdns/smartdns.conf 2>/dev/null || echo "配置文件不存在"
|
||
;;
|
||
4)
|
||
echo -e "${GREEN}测试 DNS 解析...${NC}"
|
||
echo ""
|
||
echo "Netflix: $(dig +short netflix.com @127.0.0.1 2>/dev/null | head -1)"
|
||
echo "ChatGPT: $(dig +short chatgpt.com @127.0.0.1 2>/dev/null | head -1)"
|
||
echo "TikTok: $(dig +short tiktok.com @127.0.0.1 2>/dev/null | head -1)"
|
||
;;
|
||
5)
|
||
echo -e "${RED}确定要卸载 smartdns?(y/n): ${NC}"
|
||
read -p "" confirm
|
||
[[ "$confirm" == "y" ]] && {
|
||
systemctl stop smartdns
|
||
systemctl disable smartdns
|
||
chattr -i /etc/resolv.conf 2>/dev/null || true
|
||
[[ -f /etc/resolv.conf.bak ]] && mv /etc/resolv.conf.bak /etc/resolv.conf
|
||
rm -rf /etc/smartdns
|
||
echo -e "${GREEN}smartdns 已卸载${NC}"
|
||
}
|
||
;;
|
||
*)
|
||
echo -e "${RED}无效选项${NC}"
|
||
;;
|
||
esac
|
||
}
|
||
|
||
# ============ 主入口 ============
|
||
|
||
main() {
|
||
check_root
|
||
detect_os
|
||
|
||
clear
|
||
print_banner
|
||
|
||
local my_ip=$(get_public_ip)
|
||
echo -e "本机 IP: ${GREEN}$my_ip${NC}"
|
||
echo ""
|
||
echo "请选择本机角色:"
|
||
echo " 1) 解锁机(我能解锁,帮别人解锁)"
|
||
echo " 2) 被解锁机(我不能解锁,用别人的解锁机)"
|
||
echo " 3) 退出"
|
||
echo ""
|
||
|
||
read -p "请选择: " mode
|
||
|
||
case $mode in
|
||
1) menu_unlocker ;;
|
||
2) menu_client ;;
|
||
3) exit 0 ;;
|
||
*) echo -e "${RED}无效选项${NC}" ;;
|
||
esac
|
||
}
|
||
|
||
main "$@"
|