AC2100/vless-reality-setup.sh

444 lines
13 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
# ============================================================
# VLESS + Reality 直连一键部署脚本
# 专为 Debian 系统优化,无需域名/证书/Nginx
# ============================================================
set -e
# 自检:去除 Windows CRLF 换行符
if grep -qP '\r' "$0" 2>/dev/null; then
sed -i 's/\r//' "$0"
exec bash "$0" "$@"
fi
# 预设标准化配置(直接回车使用以下默认值)
PRESET_UUID="0ad7d003-8e79-4529-8b55-09610947c09b"
PRESET_PORT="443"
PRESET_SNI="www.apple.com"
PRESET_SHORT_ID=""
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
info() { echo -e "${CYAN}[INFO]${NC} $1"; }
success() { echo -e "${GREEN}[OK]${NC} $1"; }
warning() { echo -e "${YELLOW}[!]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
ask() {
echo -e "${BLUE}[?]${NC} $1"
read INPUT_VAR
eval "$2=\$INPUT_VAR"
}
ask_enter() {
echo -e "${BLUE}[?]${NC} $1"
read DUMMY
}
# ============================================================
# 检查 root 权限
# ============================================================
check_root() {
if [ "$EUID" -ne 0 ]; then
error "请使用 root 用户运行此脚本"
fi
}
# ============================================================
# 检查 Debian 系统
# ============================================================
check_debian() {
if [ ! -f /etc/debian_version ]; then
error "此脚本仅支持 Debian 系统"
fi
DEBIAN_VER=$(cat /etc/debian_version | cut -d. -f1)
info "检测到 Debian 版本:$(cat /etc/debian_version)"
if [ "$DEBIAN_VER" -lt 10 ] 2>/dev/null; then
warning "建议使用 Debian 10 或更高版本,当前版本可能存在兼容性问题"
fi
}
# ============================================================
# 欢迎信息
# ============================================================
print_banner() {
clear
echo -e "${CYAN}"
echo "======================================================"
echo " VLESS + Reality 直连一键部署脚本"
echo " (无需域名/证书/Nginx)"
echo "======================================================"
echo -e "${NC}"
echo ""
info "Reality 直连特点:"
echo " · 无需域名、无需 SSL 证书"
echo " · 伪装成真实网站的 TLS 流量,抗封锁能力强"
echo " · 不依赖 Cloudflare CDN直接连接服务器 IP"
echo ""
ask_enter "按 Enter 继续Ctrl+C 退出..."
}
# ============================================================
# 收集用户输入
# ============================================================
collect_info() {
echo ""
echo -e "${CYAN}------------------------------------------------------${NC}"
info "开始收集配置信息..."
echo ""
# UUID
ask "请输入 UUID直接回车使用预设值${PRESET_UUID}" INPUT_UUID
UUID=${INPUT_UUID:-$PRESET_UUID}
# 监听端口
ask "请输入监听端口(直接回车使用预设值:${PRESET_PORT}" INPUT_PORT
PORT=${INPUT_PORT:-$PRESET_PORT}
# Reality 伪装目标域名 (SNI)
ask "请输入 Reality 伪装域名 SNI直接回车使用预设值${PRESET_SNI}" INPUT_SNI
SNI=${INPUT_SNI:-$PRESET_SNI}
# 确认信息
echo ""
echo -e "${CYAN}------------------------------------------------------${NC}"
info "配置信息确认:"
echo ""
echo " UUID $UUID"
echo " 监听端口: $PORT"
echo " 伪装域名(SNI) $SNI"
echo ""
ask "确认以上信息正确?直接回车继续,输入 n 重新填写:" CONFIRM
if [ "$CONFIRM" = "n" ] || [ "$CONFIRM" = "N" ]; then
collect_info
fi
}
# ============================================================
# 修复 APT 源(兼容 Debian 11/12
# ============================================================
fix_apt_sources() {
echo ""
info "检查并修复 APT 源..."
DEBIAN_VER=$(cat /etc/debian_version | cut -d. -f1)
if [ "$DEBIAN_VER" = "11" ]; then
warning "检测到 Debian 11修复 backports 源..."
sed -i 's|deb.debian.org/debian bullseye-backports|archive.debian.org/debian bullseye-backports|g' \
/etc/apt/sources.list 2>/dev/null || true
if ls /etc/apt/sources.list.d/*.list >/dev/null 2>&1; then
sed -i '/bullseye-backports/s/^/#/' /etc/apt/sources.list.d/*.list 2>/dev/null || true
fi
success "Debian 11 源修复完成"
elif [ "$DEBIAN_VER" = "12" ]; then
success "Debian 12 源正常,无需修复"
else
info "Debian 版本:$DEBIAN_VER,跳过源修复"
fi
}
# ============================================================
# 安装依赖
# ============================================================
install_deps() {
echo ""
echo -e "${CYAN}------------------------------------------------------${NC}"
info "更新系统并安装依赖..."
rm -f /var/lib/dpkg/lock-frontend
rm -f /var/lib/apt/lists/lock
apt-get update -qq
apt-get install -y -qq \
curl \
wget \
openssl \
python3
success "依赖安装完成"
}
# ============================================================
# 安装 sing-box
# ============================================================
install_singbox() {
echo ""
echo -e "${CYAN}------------------------------------------------------${NC}"
info "安装 sing-box..."
if command -v sing-box >/dev/null 2>&1; then
CURRENT_VER=$(sing-box version | head -1)
warning "sing-box 已安装:$CURRENT_VER"
ask "是否重新安装最新版?(y/N)" REINSTALL
if [ "$REINSTALL" != "y" ] && [ "$REINSTALL" != "Y" ]; then
success "跳过安装,使用现有版本"
return
fi
fi
ARCH=$(uname -m)
case "$ARCH" in
x86_64) SB_ARCH="amd64" ;;
aarch64) SB_ARCH="arm64" ;;
armv7l) SB_ARCH="armv7" ;;
*) SB_ARCH="amd64" ;;
esac
SB_VER=$(curl -fsSL https://api.github.com/repos/SagerNet/sing-box/releases/latest \
| grep '"tag_name"' | cut -d'"' -f4 | sed 's/^v//')
if [ -z "$SB_VER" ]; then
error "无法获取 sing-box 最新版本,请检查网络连接"
fi
info "下载 sing-box v${SB_VER} (${SB_ARCH})..."
DEB_URL="https://github.com/SagerNet/sing-box/releases/download/v${SB_VER}/sing-box_${SB_VER}_linux_${SB_ARCH}.deb"
TMP_DEB="/tmp/sing-box.deb"
if ! curl -fsSL -o "$TMP_DEB" "$DEB_URL"; then
error "sing-box 下载失败,请检查网络或手动安装"
fi
dpkg -i "$TMP_DEB"
rm -f "$TMP_DEB"
if command -v sing-box >/dev/null 2>&1; then
success "sing-box 安装成功:$(sing-box version | head -1)"
else
error "sing-box 安装失败,请检查网络连接"
fi
}
# ============================================================
# 生成 Reality 密钥对 + Short ID
# ============================================================
generate_reality_keys() {
echo ""
echo -e "${CYAN}------------------------------------------------------${NC}"
info "生成 Reality 密钥对..."
KEY_OUTPUT=$(sing-box generate reality-keypair)
PRIVATE_KEY=$(echo "$KEY_OUTPUT" | grep "PrivateKey" | awk '{print $2}')
PUBLIC_KEY=$(echo "$KEY_OUTPUT" | grep "PublicKey" | awk '{print $2}')
if [ -z "$PRIVATE_KEY" ] || [ -z "$PUBLIC_KEY" ]; then
error "Reality 密钥对生成失败"
fi
success "私钥:$PRIVATE_KEY"
success "公钥:$PUBLIC_KEY"
info "生成 Short ID..."
SHORT_ID=$(openssl rand -hex 8)
success "Short ID$SHORT_ID"
}
# ============================================================
# 配置 sing-box
# ============================================================
configure_singbox() {
echo ""
echo -e "${CYAN}------------------------------------------------------${NC}"
info "配置 sing-box..."
mkdir -p /etc/sing-box
cat > /etc/sing-box/config.json << EOF
{
"log": {
"level": "error",
"timestamp": true
},
"inbounds": [
{
"type": "vless",
"tag": "vless-in",
"listen": "::",
"listen_port": ${PORT},
"users": [
{
"uuid": "${UUID}",
"flow": "xtls-rprx-vision"
}
],
"tls": {
"enabled": true,
"server_name": "${SNI}",
"reality": {
"enabled": true,
"handshake": {
"server": "${SNI}",
"server_port": 443
},
"private_key": "${PRIVATE_KEY}",
"short_id": [
"${SHORT_ID}"
]
}
}
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct"
}
]
}
EOF
success "sing-box 配置文件已生成:/etc/sing-box/config.json"
info "校验配置文件..."
if sing-box check -c /etc/sing-box/config.json; then
success "配置文件校验通过"
else
error "配置文件校验失败,请检查 /etc/sing-box/config.json"
fi
}
# ============================================================
# 启动 sing-box 服务
# ============================================================
start_singbox() {
echo ""
echo -e "${CYAN}------------------------------------------------------${NC}"
info "启动 sing-box 服务..."
systemctl enable sing-box >/dev/null 2>&1 || true
systemctl restart sing-box
sleep 2
if systemctl is-active --quiet sing-box; then
success "sing-box 启动成功 ✓"
else
error "sing-box 启动失败:$(systemctl status sing-box --no-pager | tail -10)"
fi
}
# ============================================================
# 最终验证
# ============================================================
verify_services() {
echo ""
echo -e "${CYAN}------------------------------------------------------${NC}"
info "验证服务状态..."
if systemctl is-active --quiet sing-box; then
success "sing-box 运行中 ✓"
else
warning "sing-box 未运行"
fi
if ss -tlnp | grep -q ":${PORT}"; then
success "端口 ${PORT} 监听正常 ✓"
else
warning "端口 ${PORT} 未监听,请检查配置"
fi
}
# ============================================================
# 打印最终结果
# ============================================================
print_result() {
SERVER_IP=$(curl -s --max-time 5 https://api.ipify.org || curl -s --max-time 5 https://ifconfig.me || echo "你的服务器IP")
VLESS_LINK="vless://${UUID}@${SERVER_IP}:${PORT}?encryption=none&flow=xtls-rprx-vision&security=reality&sni=${SNI}&fp=chrome&pbk=${PUBLIC_KEY}&sid=${SHORT_ID}&type=tcp&headerType=none#VLESS-Reality"
echo ""
echo -e "${GREEN}"
echo "======================================================"
echo " 部署完成!"
echo "======================================================"
echo -e "${NC}"
echo -e "${CYAN}------------------------------------------------------${NC}"
echo -e "${GREEN}客户端配置参数:${NC}"
echo ""
echo " 协议: VLESS"
echo " 地址: $SERVER_IP"
echo " 端口: $PORT"
echo " UUID $UUID"
echo " Flow xtls-rprx-vision"
echo " 传输方式: TCP"
echo " 安全类型: Reality"
echo " SNI $SNI"
echo " 指纹: chrome"
echo " Public Key $PUBLIC_KEY"
echo " Short ID $SHORT_ID"
echo ""
echo -e "${CYAN}------------------------------------------------------${NC}"
echo -e "${YELLOW}VLESS 链接(可直接导入客户端):${NC}"
echo ""
echo "$VLESS_LINK"
echo ""
echo -e "${CYAN}------------------------------------------------------${NC}"
echo -e "${YELLOW}常用管理命令:${NC}"
echo " 查看 sing-box 状态: systemctl status sing-box"
echo " 查看 sing-box 日志: journalctl -u sing-box -f"
echo " 重启 sing-box systemctl restart sing-box"
echo " 配置文件位置: /etc/sing-box/config.json"
echo ""
echo -e "${CYAN}------------------------------------------------------${NC}"
warning "注意事项:"
echo " 1. 服务器 IP 若有变动,需重新生成客户端链接"
echo " 2. 私钥/公钥/UUID 务必妥善保管,泄露需重新生成"
echo " 3. 伪装域名(SNI)需保证服务器能正常访问到该域名"
echo ""
CONFIG_FILE="/root/vless-reality-config.txt"
cat > "$CONFIG_FILE" << EOF
VLESS + Reality 直连配置
生成时间:$(date)
系统Debian $(cat /etc/debian_version)
服务器 IP $SERVER_IP
端口: $PORT
UUID $UUID
Flow xtls-rprx-vision
传输方式: TCP
安全类型: Reality
SNI $SNI
指纹: chrome
Public Key $PUBLIC_KEY
Private Key $PRIVATE_KEY
Short ID $SHORT_ID
VLESS 链接:
$VLESS_LINK
配置文件路径:
sing-box: /etc/sing-box/config.json
EOF
success "配置已保存至 $CONFIG_FILE"
}
# ============================================================
# 主流程
# ============================================================
main() {
check_root
check_debian
print_banner
collect_info
fix_apt_sources
install_deps
install_singbox
generate_reality_keys
configure_singbox
start_singbox
verify_services
print_result
}
main