Files
server-deploy/vps-xray/deploy.sh

434 lines
11 KiB
Bash
Raw Permalink 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.
#!/usr/bin/env bash
set -euo pipefail
# ============================================
# Xray VPS 一键部署脚本
# 支持模式reality (VLESS-Reality) / fast (VLESS TCP 无 TLS)
# 适用于 Debian 11+ / Ubuntu 20.04+
# ============================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
log() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
step() { echo -e "\n${CYAN}========== $* ==========${NC}"; }
# ===== 使用说明 =====
usage() {
echo "用法: bash deploy.sh [选项]"
echo ""
echo "选项:"
echo " --mode reality VLESS-Reality 模式(默认,推荐,抗封锁)"
echo " --mode fast VLESS TCP 模式(无 TLS极速但易被检测"
echo " -h, --help 显示帮助"
exit 0
}
# ===== 解析参数 =====
MODE="reality"
while [[ $# -gt 0 ]]; do
case $1 in
--mode) MODE="$2"; shift 2 ;;
-h|--help) usage ;;
*) error "未知参数: $1"; usage ;;
esac
done
if [[ "$MODE" != "reality" && "$MODE" != "fast" ]]; then
error "无效模式: $MODE(支持 reality / fast"
exit 1
fi
# ===== 检查 root =====
if [ "$(id -u)" -ne 0 ]; then
error "请使用 root 用户运行: sudo bash deploy.sh"
exit 1
fi
# ===== 加载现有配置(如存在)=====
if [ -f .env ]; then
sed -i 's/\r$//' .env
set -a; source .env; set +a
fi
XRAY_PORT="${XRAY_PORT:-443}"
# ===== 1. 安装 Xray =====
install_xray() {
step "1/5 安装 Xray"
if command -v xray &>/dev/null || [ -x /usr/local/bin/xray ]; then
log "Xray 已安装: $(/usr/local/bin/xray version | head -1)"
log "将更新到最新版本..."
fi
bash <(curl -fsSL https://raw.githubusercontent.com/XTLS/Xray-install/main/install-release.sh)
log "Xray 安装完成: $(/usr/local/bin/xray version | head -1)"
}
# ===== 2. 生成密钥 =====
generate_keys() {
step "2/5 生成密钥"
XRAY_UUID=$(cat /proc/sys/kernel/random/uuid)
log "UUID: ${XRAY_UUID}"
if [ "$MODE" = "reality" ]; then
local keys
keys=$(/usr/local/bin/xray x25519 2>&1)
XRAY_PRIVATE_KEY=$(echo "$keys" | grep -i 'private' | awk -F': ' '{print $2}' | tr -d '[:space:]')
XRAY_PUBLIC_KEY=$(echo "$keys" | grep -i 'public' | awk -F': ' '{print $2}' | tr -d '[:space:]')
XRAY_SHORT_ID=$(openssl rand -hex 8)
if [ -z "$XRAY_PRIVATE_KEY" ] || [ -z "$XRAY_PUBLIC_KEY" ]; then
error "密钥生成失败xray x25519 输出:"
echo "$keys"
exit 1
fi
log "x25519 密钥对已生成"
log "ShortId: ${XRAY_SHORT_ID}"
fi
}
# ===== 3. 选择 Reality 伪装目标 =====
select_reality_dest() {
if [ "$MODE" != "reality" ]; then
return
fi
step "3/5 选择 Reality 伪装目标"
local candidates=("www.microsoft.com" "dl.google.com" "www.apple.com" "www.amazon.com")
REALITY_DEST="${REALITY_DEST:-}"
REALITY_SNI="${REALITY_SNI:-}"
if [ -n "$REALITY_DEST" ] && [ -n "$REALITY_SNI" ]; then
log "使用 .env 中指定的伪装目标: ${REALITY_DEST}"
return
fi
local best_dest="www.microsoft.com"
local best_ms=9999
for site in "${candidates[@]}"; do
local ms
ms=$(curl -so /dev/null -w '%{time_connect}' --max-time 3 "https://${site}" 2>/dev/null \
| awk '{printf "%d", $1*1000}') || true
if [ -n "$ms" ] && [ "$ms" -lt "$best_ms" ] 2>/dev/null; then
best_ms=$ms
best_dest=$site
fi
done
REALITY_DEST="$best_dest"
REALITY_SNI="$best_dest"
log "伪装目标: ${REALITY_DEST} (延迟 ${best_ms}ms)"
}
# ===== 4. 写入 Xray 配置 =====
write_config() {
if [ "$MODE" = "reality" ]; then
write_config_reality
else
write_config_fast
fi
}
write_config_reality() {
step "3/5 写入 Xray 配置 (Reality)"
cat > /usr/local/etc/xray/config.json << EOF
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"listen": "0.0.0.0",
"port": ${XRAY_PORT},
"protocol": "vless",
"settings": {
"clients": [
{
"id": "${XRAY_UUID}",
"flow": "xtls-rprx-vision"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": false,
"dest": "${REALITY_DEST}:443",
"xver": 0,
"serverNames": [
"${REALITY_SNI}"
],
"privateKey": "${XRAY_PRIVATE_KEY}",
"shortIds": [
"${XRAY_SHORT_ID}"
]
}
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls", "quic"],
"routeOnly": true
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct"
},
{
"protocol": "blackhole",
"tag": "block"
}
],
"routing": {
"rules": [
{
"type": "field",
"outboundTag": "block",
"protocol": ["bittorrent"]
}
]
}
}
EOF
log "配置已写入: /usr/local/etc/xray/config.json"
}
write_config_fast() {
step "3/5 写入 Xray 配置 (Fast TCP)"
cat > /usr/local/etc/xray/config.json << EOF
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"listen": "0.0.0.0",
"port": ${XRAY_PORT},
"protocol": "vless",
"settings": {
"clients": [
{
"id": "${XRAY_UUID}"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "none"
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls", "quic"],
"routeOnly": true
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct"
},
{
"protocol": "blackhole",
"tag": "block"
}
],
"routing": {
"rules": [
{
"type": "field",
"outboundTag": "block",
"protocol": ["bittorrent"]
}
]
}
}
EOF
log "配置已写入: /usr/local/etc/xray/config.json"
}
# ===== 5. 防火墙 =====
configure_firewall() {
step "4/5 配置防火墙"
if command -v ufw &>/dev/null; then
ufw allow "${XRAY_PORT}/tcp"
ufw allow 22/tcp
ufw --force enable
log "ufw 已放行端口 ${XRAY_PORT}/tcp"
elif command -v firewall-cmd &>/dev/null; then
firewall-cmd --permanent --add-port="${XRAY_PORT}/tcp"
firewall-cmd --reload
log "firewalld 已放行端口 ${XRAY_PORT}/tcp"
else
warn "未检测到防火墙工具,请手动放行端口 ${XRAY_PORT}/tcp"
fi
}
# ===== 6. BBR + 网络调优 =====
tune_network() {
step "5/5 BBR + 网络调优"
cat > /etc/sysctl.d/99-xray-turbo.conf << 'SYSEOF'
# BBR 拥塞控制
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
# TCP 缓冲区(提升大文件 / 视频流吞吐量)
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
# 连接优化
net.ipv4.tcp_fastopen=3
net.ipv4.tcp_slow_start_after_idle=0
net.ipv4.tcp_mtu_probing=1
net.ipv4.tcp_fin_timeout=15
net.ipv4.tcp_keepalive_time=300
net.ipv4.tcp_keepalive_intvl=30
net.ipv4.tcp_keepalive_probes=5
net.ipv4.tcp_max_tw_buckets=5000
net.ipv4.tcp_max_syn_backlog=8192
net.core.somaxconn=8192
net.core.netdev_max_backlog=8192
SYSEOF
sysctl --system > /dev/null 2>&1
log "BBR 已启用,网络参数已优化"
}
# ===== 7. 启动服务 =====
start_service() {
systemctl daemon-reload
systemctl restart xray
systemctl enable xray
sleep 2
if systemctl is-active --quiet xray; then
log "Xray 服务已启动 ✅"
else
error "Xray 启动失败,请检查: journalctl -u xray -f"
exit 1
fi
}
# ===== 8. 保存配置到 .env =====
save_env() {
cat > "$SCRIPT_DIR/.env" << EOF
# Xray 部署配置(由 deploy.sh 自动生成)
# 生成时间: $(date '+%Y-%m-%d %H:%M:%S')
XRAY_MODE=${MODE}
XRAY_PORT=${XRAY_PORT}
XRAY_UUID=${XRAY_UUID}
EOF
if [ "$MODE" = "reality" ]; then
cat >> "$SCRIPT_DIR/.env" << EOF
XRAY_PRIVATE_KEY=${XRAY_PRIVATE_KEY}
XRAY_PUBLIC_KEY=${XRAY_PUBLIC_KEY}
XRAY_SHORT_ID=${XRAY_SHORT_ID}
REALITY_DEST=${REALITY_DEST}
REALITY_SNI=${REALITY_SNI}
EOF
fi
chmod 600 "$SCRIPT_DIR/.env"
log "配置已保存到 .env权限 600"
}
# ===== 9. 输出连接信息 =====
print_result() {
local server_ip
server_ip=$(curl -s --max-time 5 ipv4.ip.sb || curl -s --max-time 5 ifconfig.me || echo "获取失败")
echo ""
echo "=========================================================="
if [ "$MODE" = "reality" ]; then
echo " Xray VLESS-Reality 部署完成 ✅"
echo "=========================================================="
echo ""
echo " IP : ${server_ip}"
echo " 端口 : ${XRAY_PORT}"
echo " 协议 : VLESS"
echo " UUID : ${XRAY_UUID}"
echo " 流控 : xtls-rprx-vision"
echo " 传输 : tcp"
echo " 安全 : reality"
echo " SNI : ${REALITY_SNI}"
echo " Fingerprint : chrome"
echo " PublicKey : ${XRAY_PUBLIC_KEY}"
echo " ShortId : ${XRAY_SHORT_ID}"
echo ""
echo "=========================================================="
echo ""
echo ">>> VLESS 分享链接(可直接导入客户端):"
echo ""
echo "vless://${XRAY_UUID}@${server_ip}:${XRAY_PORT}?encryption=none&flow=xtls-rprx-vision&security=reality&sni=${REALITY_SNI}&fp=chrome&pbk=${XRAY_PUBLIC_KEY}&sid=${XRAY_SHORT_ID}&type=tcp#VPS-Reality"
else
echo " Xray VLESS TCP 部署完成 ✅"
echo "=========================================================="
echo ""
echo " IP : ${server_ip}"
echo " 端口 : ${XRAY_PORT}"
echo " 协议 : VLESS"
echo " UUID : ${XRAY_UUID}"
echo " 传输 : tcp"
echo " 安全 : none"
fi
echo ""
echo "=========================================================="
echo ""
echo "⚠️ 请妥善保存以上信息!"
echo " 配置文件: /usr/local/etc/xray/config.json"
echo " 凭据备份: ${SCRIPT_DIR}/.env"
echo " 查看日志: journalctl -u xray -f"
echo " 重启服务: systemctl restart xray"
echo "=========================================================="
}
# ===== 主流程 =====
main() {
echo ""
log "部署模式: ${MODE}"
[ "$MODE" = "reality" ] && log "VLESS-Reality推荐抗封锁" || log "VLESS TCP极速无 TLS"
echo ""
install_xray
generate_keys
select_reality_dest
write_config
configure_firewall
tune_network
start_service
save_env
print_result
}
main