增加vps-xray部署相关脚本
This commit is contained in:
433
vps-xray/deploy.sh
Normal file
433
vps-xray/deploy.sh
Normal file
@@ -0,0 +1,433 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user