Last active
May 20, 2025 03:14
-
-
Save xjoker/5fe9fdc7f08b2bb48ff4dac4245920ba to your computer and use it in GitHub Desktop.
xray_auto_install
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# 函数:显示绿色信息 | |
log_info() { | |
echo -e "\033[32m[INFO] $1\033[0m" | |
} | |
# 函数:显示黄色警告 | |
log_warn() { | |
echo -e "\033[33m[WARN] $1\033[0m" | |
} | |
# 函数:显示红色错误并退出 | |
log_error_exit() { | |
echo -e "\033[31m[ERROR] $1\033[0m" >&2 | |
exit 1 | |
} | |
# 检查是否为 root 用户 | |
if [ "$(id -u)" -ne 0 ]; then | |
log_error_exit "此脚本需要 root 权限运行。请使用 sudo 执行。" | |
fi | |
# --- 用户输入 --- | |
DEFAULT_REALITY_DEST_DOMAIN="www.yahoo.com" # 一个常见且高可用的域名 | |
echo "欢迎使用 Xray (VLESS + Reality) 服务端部署脚本。" | |
echo "-----------------------------------------------------" | |
read -r -p "请输入 Xray 监听的端口 (范围 1-65535,留空则随机生成 10000-65535 之间的端口): " LISTENING_PORT | |
if [[ -z "$LISTENING_PORT" ]]; then | |
LISTENING_PORT=$(shuf -i 10000-65535 -n 1) | |
log_info "未指定端口,已随机生成端口: $LISTENING_PORT" | |
else | |
if ! [[ "$LISTENING_PORT" =~ ^[0-9]+$ ]] || [ "$LISTENING_PORT" -lt 1 ] || [ "$LISTENING_PORT" -gt 65535 ]; then | |
log_error_exit "无效的端口号: $LISTENING_PORT. 必须是 1-65535 之间的数字。" | |
fi | |
log_info "将使用端口: $LISTENING_PORT" | |
fi | |
read -r -p "请输入 Reality 'dest' 和 'serverNames' 使用的目标域名 (例如: one.one.one.one, 默认: ${DEFAULT_REALITY_DEST_DOMAIN}): " REALITY_DOMAIN | |
if [[ -z "$REALITY_DOMAIN" ]]; then | |
REALITY_DOMAIN="$DEFAULT_REALITY_DEST_DOMAIN" | |
fi | |
# Reality 'dest' 通常包含端口 443 | |
REALITY_DEST="${REALITY_DOMAIN}:443" | |
# Reality 'serverNames' (用于SNI) | |
REALITY_SERVER_NAME="$REALITY_DOMAIN" | |
log_info "Reality 'dest' 将设置为: $REALITY_DEST" | |
log_info "Reality 'serverName' (SNI) 将设置为: $REALITY_SERVER_NAME" | |
echo "-----------------------------------------------------" | |
# --- 安装依赖 --- | |
log_info "正在更新软件包列表并安装依赖 (curl, unzip, jq, openssl, uuid-runtime)..." | |
export DEBIAN_FRONTEND=noninteractive | |
if ! apt-get update -y > /dev/null 2>&1; then | |
log_warn "apt-get update 失败,请检查网络或软件源。" | |
fi | |
if ! apt-get install -y curl unzip jq openssl uuid-runtime > /dev/null 2>&1; then | |
log_error_exit "依赖安装失败。请检查错误信息并手动安装 curl, unzip, jq, openssl, uuid-runtime。" | |
fi | |
log_info "依赖安装完成。" | |
echo "-----------------------------------------------------" | |
# --- 安装 Xray-core --- | |
log_info "正在安装/更新 Xray-core..." | |
# 使用 --without-logfiles 参数,让 Xray 使用 journald 记录日志 | |
if bash <(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh) install --without-logfiles; then | |
log_info "Xray-core 安装/更新成功。" | |
else | |
log_error_exit "Xray-core 安装失败。" | |
fi | |
echo "-----------------------------------------------------" | |
# --- 生成 Xray Keys 和 IDs --- | |
log_info "正在生成 Reality 密钥对和客户端 ID..." | |
XRAY_BIN="/usr/local/bin/xray" # 确认 xray 执行文件路径 | |
if [ ! -f "$XRAY_BIN" ]; then | |
log_error_exit "Xray 执行文件未找到: $XRAY_BIN" | |
fi | |
xray_key_output=$("$XRAY_BIN" x25519) | |
XRAY_PRIVATE_KEY=$(echo "$xray_key_output" | grep 'Private key:' | awk '{print $3}') | |
XRAY_PUBLIC_KEY=$(echo "$xray_key_output" | grep 'Public key:' | awk '{print $3}') | |
if [[ -z "$XRAY_PRIVATE_KEY" || -z "$XRAY_PUBLIC_KEY" ]]; then | |
log_error_exit "生成 Reality 密钥对失败。请确保 Xray 命令 ($XRAY_BIN x25519) 能正常工作。" | |
fi | |
CLIENT_UUID=$(uuidgen) | |
# 生成两个 shortId (16进制字符串) | |
SHORT_ID_1=$(openssl rand -hex 4) # 8 字符 | |
SHORT_ID_2=$(openssl rand -hex 4) # 8 字符 | |
SHORT_ID_3=$(openssl rand -hex 4) # 8 字符 | |
log_info "密钥和 ID 生成完毕。" | |
log_info " 公钥 (Public Key): $XRAY_PUBLIC_KEY" | |
log_info " 客户端 UUID: $CLIENT_UUID" | |
log_info " Short ID 1: $SHORT_ID_1" | |
log_info " Short ID 2: $SHORT_ID_2" | |
log_info " Short ID 3: $SHORT_ID_3" | |
# 私钥不直接显示给用户,只写入配置文件 | |
echo "-----------------------------------------------------" | |
# --- 创建 Xray 配置 --- | |
log_info "正在创建 Xray 配置文件..." | |
XRAY_CONFIG_DIR="/usr/local/etc/xray" | |
XRAY_CONFIG_PATH="${XRAY_CONFIG_DIR}/config.json" | |
mkdir -p "$XRAY_CONFIG_DIR" | |
# 使用 cat 和 EOF 创建 JSON 配置文件 | |
cat > "$XRAY_CONFIG_PATH" <<EOL | |
{ | |
"log": { | |
"loglevel": "warning" | |
}, | |
"routing": { | |
"domainStrategy": "AsIs", | |
"rules": [ | |
{ | |
"type": "field", | |
"ip": ["geoip:private"], | |
"outboundTag": "blocked" | |
}, | |
{ | |
"type": "field", | |
"protocol": ["bittorrent"], | |
"outboundTag": "blocked" | |
} | |
] | |
}, | |
"inbounds": [ | |
{ | |
"listen": "0.0.0.0", | |
"port": ${LISTENING_PORT}, | |
"protocol": "vless", | |
"settings": { | |
"clients": [ | |
{ | |
"id": "${CLIENT_UUID}", | |
"flow": "xtls-rprx-vision" | |
} | |
], | |
"decryption": "none" | |
}, | |
"tag":"inbound-${LISTENING_PORT}", | |
"mux": { | |
"enabled": true, | |
"concurrency": 8 | |
}, | |
"streamSettings": { | |
"network": "tcp", | |
"security": "reality", | |
"realitySettings": { | |
"show": false, | |
"dest": "${REALITY_DEST}", | |
"xver": 0, | |
"serverNames": ["${REALITY_SERVER_NAME}"], | |
"privateKey": "${XRAY_PRIVATE_KEY}", | |
"minClientVer": "", | |
"maxClientVer": "", | |
"maxTimeDiff": 0, | |
"shortIds": ["${SHORT_ID_1}", "${SHORT_ID_2}", "${SHORT_ID_3}"] | |
} | |
}, | |
"sniffing": { | |
"enabled": true, | |
"destOverride": ["http", "tls", "quic"], | |
"metadataOnly": false | |
} | |
} | |
], | |
"outbounds": [ | |
{ | |
"protocol": "freedom", | |
"settings": {} | |
}, | |
{ | |
"protocol": "blackhole", | |
"settings": {}, | |
"tag": "blocked" | |
} | |
] | |
} | |
EOL | |
# 验证 JSON 配置文件格式 (需要 jq) | |
if command -v jq > /dev/null && jq . "$XRAY_CONFIG_PATH" > /dev/null 2>&1; then | |
log_info "Xray 配置文件创建成功: $XRAY_CONFIG_PATH" | |
else | |
# 如果 jq 不可用或 JSON 无效,给出警告,但不一定退出,Xray 自身也会校验 | |
log_warn "Xray 配置文件已创建,但无法使用 jq进行 JSON 格式校验。" | |
log_warn "请在启动服务后检查 Xray 日志确认配置是否正确。" | |
cat "$XRAY_CONFIG_PATH" # 打印配置内容供检查 | |
fi | |
echo "-----------------------------------------------------" | |
# --- 重启并设置 Xray 服务 --- | |
log_info "正在启动/重启 Xray 服务并设置为开机自启..." | |
systemctl enable xray > /dev/null 2>&1 | |
if systemctl restart xray; then | |
log_info "Xray 服务启动/重启成功。" | |
# 等待服务稳定 | |
sleep 3 | |
if systemctl is-active --quiet xray; then | |
log_info "Xray 服务当前状态: active (running)" | |
else | |
log_warn "Xray 服务启动后未能保持运行状态。请检查日志:" | |
log_warn " systemctl status xray -l --no-pager" | |
log_warn " journalctl -u xray --no-pager -l -n 50" # 显示最近50条日志 | |
# 不要在此处退出,允许用户查看输出的配置信息 | |
fi | |
else | |
log_warn "Xray 服务启动/重启失败。请检查配置文件和日志。" | |
log_warn " 配置文件路径: $XRAY_CONFIG_PATH" | |
log_warn " 查看 Xray 状态: systemctl status xray -l --no-pager" | |
log_warn " 查看 Xray 日志: journalctl -u xray --no-pager -l -n 50" | |
# 不要在此处退出,允许用户查看输出的配置信息 | |
fi | |
echo "-----------------------------------------------------" | |
# --- 输出客户端连接参数 --- | |
# 尝试自动获取服务器公网 IP | |
SERVER_IP=$(curl -s https://api.ipify.org || curl -s https://checkip.amazonaws.com || curl -s http://v4.ident.me || hostname -I | awk '{print $1}') | |
if [[ -z "$SERVER_IP" ]]; then | |
log_warn "未能自动获取服务器公网 IP 地址。请手动替换下面的 <服务器IP地址>。" | |
SERVER_IP="<服务器IP地址>" | |
fi | |
# TLS 指纹,'chrome' 是一个常见的 Reality 默认值 | |
CLIENT_FINGERPRINT="chrome" | |
# 构建 VLESS URI | |
# 格式: vless://<uuid>@<address>:<port>?type=tcp&security=reality&sni=<serverName>&fp=<fingerprint>&pbk=<publicKey>&sid=<shortId>&flow=xtls-rprx-vision | |
VLESS_LINK_1="vless://${CLIENT_UUID}@${SERVER_IP}:${LISTENING_PORT}?type=tcp&security=reality&sni=${REALITY_SERVER_NAME}&fp=${CLIENT_FINGERPRINT}&pbk=${XRAY_PUBLIC_KEY}&sid=${SHORT_ID_1}&flow=xtls-rprx-vision" | |
VLESS_LINK_2="vless://${CLIENT_UUID}@${SERVER_IP}:${LISTENING_PORT}?type=tcp&security=reality&sni=${REALITY_SERVER_NAME}&fp=${CLIENT_FINGERPRINT}&pbk=${XRAY_PUBLIC_KEY}&sid=${SHORT_ID_2}&flow=xtls-rprx-vision" | |
VLESS_LINK_3="vless://${CLIENT_UUID}@${SERVER_IP}:${LISTENING_PORT}?type=tcp&security=reality&sni=${REALITY_SERVER_NAME}&fp=${CLIENT_FINGERPRINT}&pbk=${XRAY_PUBLIC_KEY}&sid=${SHORT_ID_3}&flow=xtls-rprx-vision" | |
echo "" | |
echo -e "\033[1;32m==================================================================\033[0m" | |
echo -e "\033[1;32m ✅ Xray 服务端部署完成! \033[0m" | |
echo -e "\033[1;32m==================================================================\033[0m" | |
echo "" | |
echo -e "\033[1;34m📋 客户端连接参数:\033[0m" | |
echo "------------------------------------------------------------------" | |
echo -e " \033[33m协议 (Protocol):\033[0m VLESS" | |
echo -e " \033[33m地址 (Address):\033[0m $SERVER_IP" | |
echo -e " \033[33m端口 (Port):\033[0m $LISTENING_PORT" | |
echo -e " \033[33m用户 ID (UUID):\033[0m $CLIENT_UUID" | |
echo -e " \033[33m流控 (Flow):\033[0m xtls-rprx-vision" | |
echo -e " \033[33m传输方式 (Network):\033[0m tcp" | |
echo -e " \033[33m安全类型 (Security):\033[0m reality" | |
echo -e " \033[33mSNI (Server Name):\033[0m $REALITY_SERVER_NAME" | |
echo -e " \033[33m公钥 (PublicKey/pbk):\033[0m $XRAY_PUBLIC_KEY" | |
echo -e " \033[33mShort ID (sid):\033[0m $SHORT_ID_1 or $SHORT_ID_2 or $SHORT_ID_3" | |
echo -e " \033[33m指纹 (Fingerprint/fp):\033[0m $CLIENT_FINGERPRINT (客户端可选: chrome, firefox, safari, ios, android, random等)" | |
echo -e " \033[33m目标域名 (SpiderX/dest):\033[0m $REALITY_DEST (此参数通常在客户端的 Reality 设置中填写,而不是直接在链接中)" | |
echo "------------------------------------------------------------------" | |
echo "" | |
echo -e "\033[1;34m🔗 VLESS 链接 (使用 Short ID: ${SHORT_ID_1}):\033[0m" | |
echo -e "\033[36m$VLESS_LINK_1\033[0m" | |
echo "" | |
echo -e "\033[1;34m🔗 VLESS 链接 (使用 Short ID: ${SHORT_ID_2}):\033[0m" | |
echo -e "\033[36m$VLESS_LINK_2\033[0m" | |
echo "" | |
echo -e "\033[1;34m🔗 VLESS 链接 (使用 Short ID: ${SHORT_ID_3}):\033[0m" | |
echo -e "\033[36m$VLESS_LINK_3\033[0m" | |
echo "" | |
echo "------------------------------------------------------------------" | |
echo -e "\033[1;31m⚠️ 重要提示:\033[0m" | |
echo -e "1. 如果您启用了防火墙 (如 ufw), 请确保开放 TCP 端口 \033[33m${LISTENING_PORT}\033[0m。" | |
echo -e " 例如: \033[33msudo ufw allow ${LISTENING_PORT}/tcp\033[0m 然后 \033[33msudo ufw reload\033[0m" | |
echo -e "2. Reality 的 'dest' (目标域名) 设置为 \033[33m${REALITY_DEST}\033[0m,'serverNames' (SNI) 设置为 \033[33m${REALITY_SERVER_NAME}\033[0m。" | |
echo " 客户端的 SNI、PublicKey、ShortID 必须与服务器配置严格匹配。" | |
echo "3. 客户端的 TLS 指纹 (Fingerprint) 可以根据需要选择,如 'chrome', 'firefox', 'safari', 'ios', 'random'。" | |
echo "4. 如果服务启动失败或运行不正常,请检查 Xray 日志:" | |
echo -e " \033[33msystemctl status xray -l --no-pager\033[0m" | |
echo -e " \033[33mjournalctl -u xray --no-pager -l -n 100\033[0m (查看最近100条日志)" | |
echo -e "\033[1;32m==================================================================\033[0m" | |
echo "" | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment