Add proxy protocol installer mirror
This commit is contained in:
438
scripts/reality.sh
Executable file
438
scripts/reality.sh
Executable file
@@ -0,0 +1,438 @@
|
||||
#!/bin/bash
|
||||
|
||||
# =================================================================
|
||||
# Xray (xtls-rprx-vision Reality) 服务器端管理脚本
|
||||
# =================================================================
|
||||
|
||||
# 定义输出颜色
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # 无颜色
|
||||
|
||||
XRAY_CONFIG_FILE="/usr/local/etc/xray/config.json"
|
||||
XRAY_KEYS_FILE="/usr/local/etc/xray/reality.keys"
|
||||
|
||||
# --- 通用函数 ---
|
||||
check_root() {
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo -e "${RED}错误:此脚本需要以 root 权限运行。${NC}" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# --- 函数: 确保 jq 已安装 ---
|
||||
ensure_jq() {
|
||||
if ! command -v jq &> /dev/null; then
|
||||
echo "--> 检测到依赖工具 jq 未安装,正在尝试自动安装..."
|
||||
if command -v apt-get &> /dev/null; then
|
||||
apt-get update >/dev/null && apt-get install -y jq
|
||||
elif command -v yum &> /dev/null; then
|
||||
yum install -y jq
|
||||
else
|
||||
echo -e "${RED}无法自动安装 jq。请手动安装 (sudo apt install jq / sudo yum install jq) 后再试。${NC}"
|
||||
return 1
|
||||
fi
|
||||
if ! command -v jq &> /dev/null; then
|
||||
echo -e "${RED}jq 安装失败,请检查包管理器或手动安装。${NC}"
|
||||
return 1
|
||||
fi
|
||||
echo " jq 安装成功。"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# --- 函数: 检查 Xray 安装和运行状态 ---
|
||||
check_xray_status() {
|
||||
if [ -f /usr/local/bin/xray ]; then
|
||||
echo -e "${GREEN}Xray 核心: 已安装${NC}"
|
||||
else
|
||||
echo -e "${RED}Xray 核心: 未安装${NC}"
|
||||
fi
|
||||
|
||||
if [ -f "${XRAY_CONFIG_FILE}" ]; then
|
||||
echo -e "${GREEN}配置状态 : 已配置${NC}"
|
||||
if systemctl is-active --quiet xray; then
|
||||
echo -e "${GREEN}服务状态 : 运行中${NC}"
|
||||
else
|
||||
echo -e "${RED}服务状态 : 未运行${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}配置状态 : 未配置${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# --- 函数: 生成 Reality 配置 ---
|
||||
generate_reality_simple_config() {
|
||||
echo "--> 正在配置 Reality 配置..."
|
||||
read -p "请输入监听端口 (例如 443, 留空随机): " PORT
|
||||
[ -z "$PORT" ] && PORT=$((RANDOM % 55536 + 10000))
|
||||
|
||||
read -p "请输入伪装域名 (留空则默认为 icloud.com): " SNI_DOMAIN
|
||||
[ -z "$SNI_DOMAIN" ] && SNI_DOMAIN="icloud.com"
|
||||
|
||||
local sni_domain_cleaned=$(echo "${SNI_DOMAIN}" | cut -d':' -f1)
|
||||
|
||||
echo "--> 正在生成 UUID 和 Reality 密钥对..."
|
||||
local uuid=$(/usr/local/bin/xray uuid)
|
||||
local key_pair=$(/usr/local/bin/xray x25519)
|
||||
local private_key=$(echo "$key_pair" | grep 'PrivateKey' | awk '{print $2}')
|
||||
local public_key=$(echo "$key_pair" | grep 'Password' | awk '{print $2}')
|
||||
|
||||
echo "PrivateKey: ${private_key}" > "${XRAY_KEYS_FILE}"
|
||||
echo "PublicKey: ${public_key}" >> "${XRAY_KEYS_FILE}"
|
||||
|
||||
echo "--> 正在创建配置文件 ${XRAY_CONFIG_FILE}..."
|
||||
cat > "${XRAY_CONFIG_FILE}" <<EOF
|
||||
{
|
||||
"log": {
|
||||
"loglevel": "warning"
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"port": ${PORT},
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "${uuid}",
|
||||
"flow": "xtls-rprx-vision"
|
||||
}
|
||||
],
|
||||
"decryption": "none"
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"dest": "${sni_domain_cleaned}:443",
|
||||
"serverNames": [ "${sni_domain_cleaned}" ],
|
||||
"privateKey": "${private_key}",
|
||||
"shortIds": [ "", "0123456789abcdef" ]
|
||||
}
|
||||
},
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": [ "http", "tls", "quic" ],
|
||||
"routeOnly": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"protocol": "freedom",
|
||||
"tag": "direct"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
# --- 函数: 生成 Reality (防偷) 配置 ---
|
||||
generate_reality_dokodemo_config() {
|
||||
echo "--> 正在配置 Reality (防偷)..."
|
||||
read -p "请输入外部监听端口 (例如 443, 留空随机): " EXT_PORT
|
||||
[ -z "$EXT_PORT" ] && EXT_PORT=$((RANDOM % 55536 + 10000))
|
||||
|
||||
read -p "请输入内部 VLESS 端口 (留空随机): " INT_PORT
|
||||
[ -z "$INT_PORT" ] && INT_PORT=$((RANDOM % 55536 + 10000))
|
||||
|
||||
read -p "请输入伪装域名 (留空则默认为 icloud.com): " SNI_DOMAIN
|
||||
[ -z "$SNI_DOMAIN" ] && SNI_DOMAIN="icloud.com"
|
||||
|
||||
local sni_domain_cleaned=$(echo "${SNI_DOMAIN}" | cut -d':' -f1)
|
||||
|
||||
echo "--> 正在生成 UUID 和 Reality 密钥对..."
|
||||
local uuid=$(/usr/local/bin/xray uuid)
|
||||
local key_pair=$(/usr/local/bin/xray x25519)
|
||||
local private_key=$(echo "$key_pair" | grep 'PrivateKey' | awk '{print $2}')
|
||||
local public_key=$(echo "$key_pair" | grep 'Password' | awk '{print $2}')
|
||||
|
||||
echo "PrivateKey: ${private_key}" > "${XRAY_KEYS_FILE}"
|
||||
echo "PublicKey: ${public_key}" >> "${XRAY_KEYS_FILE}"
|
||||
|
||||
echo "--> 正在创建配置文件 ${XRAY_CONFIG_FILE}..."
|
||||
cat > "${XRAY_CONFIG_FILE}" <<EOF
|
||||
{
|
||||
"log": {
|
||||
"loglevel": "warning"
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"tag": "dokodemo-in",
|
||||
"port": ${EXT_PORT},
|
||||
"protocol": "dokodemo-door",
|
||||
"settings": {
|
||||
"address": "127.0.0.1",
|
||||
"port": ${INT_PORT},
|
||||
"network": "tcp"
|
||||
},
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": [ "tls" ],
|
||||
"routeOnly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"listen": "127.0.0.1",
|
||||
"port": ${INT_PORT},
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "${uuid}",
|
||||
"flow": "xtls-rprx-vision"
|
||||
}
|
||||
],
|
||||
"decryption": "none"
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"dest": "${sni_domain_cleaned}:443",
|
||||
"serverNames": [ "${sni_domain_cleaned}" ],
|
||||
"privateKey": "${private_key}",
|
||||
"shortIds": [ "", "0123456789abcdef" ]
|
||||
}
|
||||
},
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": [ "http", "tls", "quic" ],
|
||||
"routeOnly": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{ "protocol": "freedom", "tag": "direct" },
|
||||
{ "protocol": "blackhole", "tag": "block" }
|
||||
],
|
||||
"routing": {
|
||||
"rules": [
|
||||
{
|
||||
"inboundTag": [ "dokodemo-in" ],
|
||||
"domain": [ "${sni_domain_cleaned}" ],
|
||||
"outboundTag": "direct"
|
||||
},
|
||||
{
|
||||
"inboundTag": [ "dokodemo-in" ],
|
||||
"outboundTag": "block"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
# --- 函数: 安装 Xray 核心 ---
|
||||
install_xray_core() {
|
||||
if [ -f /usr/local/bin/xray ]; then
|
||||
echo -e "${GREEN}Xray 核心已安装,无需重复操作。${NC}"
|
||||
return 0
|
||||
fi
|
||||
echo "--> 正在使用官方脚本安装 Xray 核心..."
|
||||
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install -u root
|
||||
if [ ! -f /usr/local/bin/xray ]; then
|
||||
echo -e "${RED}Xray 核心安装失败。${NC}"
|
||||
return 1
|
||||
else
|
||||
echo -e "${GREEN}Xray 核心安装成功。${NC}"
|
||||
echo "--> 正在清理旧的配置文件..."
|
||||
systemctl stop xray >/dev/null 2>&1
|
||||
rm -f "${XRAY_CONFIG_FILE}"
|
||||
rm -f "${XRAY_KEYS_FILE}"
|
||||
echo " 旧配置已清理。"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# --- 函数: (包装器) 配置 Reality ---
|
||||
configure_reality_simple() {
|
||||
if ! [ -f /usr/local/bin/xray ]; then
|
||||
echo "--> Xray 核心未安装,正在自动安装..."
|
||||
install_xray_core || return
|
||||
fi
|
||||
|
||||
if [ -f "${XRAY_CONFIG_FILE}" ]; then
|
||||
read -p "检测到现有配置,继续将覆盖它。确定吗?[y/N]: " confirm
|
||||
if [[ ! "$confirm" =~ ^[yY] ]]; then echo "操作已取消。"; return; fi
|
||||
fi
|
||||
|
||||
generate_reality_simple_config
|
||||
|
||||
echo "--> 正在测试配置并启动 Xray..."
|
||||
/usr/local/bin/xray -test -config "${XRAY_CONFIG_FILE}"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}配置文件测试失败,请检查。配置未应用。${NC}"; return; fi
|
||||
|
||||
systemctl restart xray
|
||||
systemctl enable xray > /dev/null 2>&1
|
||||
echo -e "${GREEN}🎉 Xray Reality 配置成功!${NC}"
|
||||
view_config_xray
|
||||
}
|
||||
|
||||
# --- 函数: (包装器) 配置 Reality (防偷) ---
|
||||
configure_reality_dokodemo() {
|
||||
if ! [ -f /usr/local/bin/xray ]; then
|
||||
echo "--> Xray 核心未安装,正在自动安装..."
|
||||
install_xray_core || return
|
||||
fi
|
||||
|
||||
if [ -f "${XRAY_CONFIG_FILE}" ]; then
|
||||
read -p "检测到现有配置,继续将覆盖它。确定吗?[y/N]: " confirm
|
||||
if [[ ! "$confirm" =~ ^[yY] ]]; then echo "操作已取消。"; return; fi
|
||||
fi
|
||||
|
||||
generate_reality_dokodemo_config
|
||||
|
||||
echo "--> 正在测试配置并启动 Xray..."
|
||||
/usr/local/bin/xray -test -config "${XRAY_CONFIG_FILE}"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}配置文件测试失败,请检查。配置未应用。${NC}"; return; fi
|
||||
|
||||
systemctl restart xray
|
||||
systemctl enable xray > /dev/null 2>&1
|
||||
echo -e "${GREEN}🎉 Xray Reality (防偷) 配置成功!${NC}"
|
||||
view_config_xray
|
||||
}
|
||||
|
||||
|
||||
# --- 函数: 卸载 Xray ---
|
||||
uninstall_xray() {
|
||||
if [ ! -f /usr/local/bin/xray ]; then
|
||||
echo -e "${RED}Xray 未安装。${NC}"; return; fi
|
||||
|
||||
read -p "警告:确定要卸载 Xray 吗?这将删除所有数据。[y/N]: " confirm
|
||||
if [[ ! "$confirm" =~ ^[yY]([eE][sS])?$ ]]; then
|
||||
echo "卸载操作已取消。"; return; fi
|
||||
|
||||
systemctl stop xray
|
||||
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ remove --purge
|
||||
rm -f "${XRAY_KEYS_FILE}"
|
||||
echo -e "${GREEN}Xray 已成功卸载。${NC}"
|
||||
}
|
||||
|
||||
# --- 函数: 查看 Xray 配置 ---
|
||||
view_config_xray() {
|
||||
if [ ! -f "${XRAY_CONFIG_FILE}" ]; then
|
||||
echo -e "${RED}Xray 未配置。请先选择一个配置方案。${NC}"; return; fi
|
||||
ensure_jq || return
|
||||
|
||||
if ! jq . "${XRAY_CONFIG_FILE}" >/dev/null 2>&1; then
|
||||
echo -e "${RED}错误:配置文件 ${XRAY_CONFIG_FILE} 格式无效。${NC}"; return; fi
|
||||
|
||||
local ip_address=$(curl -s https://ipv4.icanhazip.com || echo "<您的服务器IP>")
|
||||
local public_key="<未找到>"
|
||||
if [ -f "${XRAY_KEYS_FILE}" ]; then
|
||||
public_key=$(grep 'PublicKey' "${XRAY_KEYS_FILE}" | awk '{print $2}')
|
||||
fi
|
||||
|
||||
echo "------------------------------------------"
|
||||
echo " Xray (Reality) 当前配置信息"
|
||||
echo "------------------------------------------"
|
||||
|
||||
# 通过 tag 判断配置类型
|
||||
if jq -e '.inbounds[] | select(.tag=="dokodemo-in")' "${XRAY_CONFIG_FILE}" >/dev/null 2>&1; then
|
||||
# 防偷配置
|
||||
local ext_port=$(jq '.inbounds[] | select(.tag=="dokodemo-in") | .port' "${XRAY_CONFIG_FILE}")
|
||||
local vless_inbound=$(jq '.inbounds[] | select(.protocol=="vless")' "${XRAY_CONFIG_FILE}")
|
||||
local uuid=$(echo "$vless_inbound" | jq -r '.settings.clients[0].id')
|
||||
local flow=$(echo "$vless_inbound" | jq -r '.settings.clients[0].flow')
|
||||
local sni=$(echo "$vless_inbound" | jq -r '.streamSettings.realitySettings.serverNames[0]')
|
||||
local short_id=$(echo "$vless_inbound" | jq -r '.streamSettings.realitySettings.shortIds[0]')
|
||||
|
||||
echo -e "配置类型 : ${GREEN}Reality (防偷)${NC}"
|
||||
echo -e "监听地址 : ${GREEN}${ip_address}${NC}"
|
||||
echo -e "外部端口 : ${GREEN}${ext_port}${NC}"
|
||||
echo -e "UUID : ${GREEN}${uuid}${NC}"
|
||||
echo -e "Flow : ${GREEN}${flow}${NC}"
|
||||
echo -e "伪装域名 : ${GREEN}${sni}${NC}"
|
||||
echo -e "Short ID : ${GREEN}${short_id}${NC}"
|
||||
echo -e "公钥 (pbk) : ${GREEN}${public_key}${NC}"
|
||||
echo "------------------------------------------"
|
||||
echo "VLESS 分享链接:"
|
||||
local vless_link="vless://${uuid}@${ip_address}:${ext_port}?encryption=none&flow=${flow}&security=reality&sni=${sni}&fp=random&pbk=${public_key}&sid=${short_id}&allowInsecure=1&type=tcp&headerType=none#VPS_防偷"
|
||||
echo -e "${GREEN}${vless_link}${NC}"
|
||||
|
||||
else
|
||||
# Reality 配置
|
||||
local vless_inbound=$(jq '.inbounds[] | select(.protocol=="vless")' "${XRAY_CONFIG_FILE}")
|
||||
local port=$(echo "$vless_inbound" | jq -r '.port')
|
||||
local uuid=$(echo "$vless_inbound" | jq -r '.settings.clients[0].id')
|
||||
local flow=$(echo "$vless_inbound" | jq -r '.settings.clients[0].flow')
|
||||
local sni=$(echo "$vless_inbound" | jq -r '.streamSettings.realitySettings.serverNames[0]')
|
||||
local short_id=$(echo "$vless_inbound" | jq -r '.streamSettings.realitySettings.shortIds[0]')
|
||||
|
||||
echo -e "配置类型 : ${GREEN}Reality 配置${NC}"
|
||||
echo -e "监听地址 : ${GREEN}${ip_address}${NC}"
|
||||
echo -e "端口 : ${GREEN}${port}${NC}"
|
||||
echo -e "UUID : ${GREEN}${uuid}${NC}"
|
||||
echo -e "Flow : ${GREEN}${flow}${NC}"
|
||||
echo -e "伪装域名 : ${GREEN}${sni}${NC}"
|
||||
echo -e "Short ID : ${GREEN}${short_id}${NC}"
|
||||
echo -e "公钥 (pbk) : ${GREEN}${public_key}${NC}"
|
||||
echo "------------------------------------------"
|
||||
echo "VLESS 分享链接:"
|
||||
local vless_link="vless://${uuid}@${ip_address}:${port}?encryption=none&flow=${flow}&security=reality&sni=${sni}&fp=random&pbk=${public_key}&sid=${short_id}&allowInsecure=1&type=tcp&headerType=none#VPS_Reality"
|
||||
echo -e "${GREEN}${vless_link}${NC}"
|
||||
fi
|
||||
echo "------------------------------------------"
|
||||
}
|
||||
|
||||
# --- 函数: Xray 服务管理 ---
|
||||
manage_xray_service() {
|
||||
if ! systemctl list-units --type=service | grep -q "xray.service"; then
|
||||
echo -e "${RED}Xray 服务未安装。${NC}"; return; fi
|
||||
case $1 in
|
||||
start) systemctl start xray && echo -e "${GREEN}服务启动成功。${NC}" || echo -e "${RED}服务启动失败。${NC}" ;;
|
||||
stop) systemctl stop xray && echo -e "${GREEN}服务已停止。${NC}" || echo -e "${RED}服务停止失败。${NC}" ;;
|
||||
restart) systemctl restart xray && echo -e "${GREEN}服务重启成功。${NC}" || echo -e "${RED}服务重启失败。${NC}" ;;
|
||||
status) systemctl status xray ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# --- 函数: Xray 主菜单 ---
|
||||
xray_menu() {
|
||||
while true; do
|
||||
clear
|
||||
echo "=================================================="
|
||||
echo " XTLS-RPRX-VISION Reality 管理脚本"
|
||||
echo "=================================================="
|
||||
check_xray_status
|
||||
echo "--------------------------------------------------"
|
||||
echo "1. 安装 Xray 核心"
|
||||
echo "2. 配置 Reality"
|
||||
echo "3. 配置 Reality (防偷)"
|
||||
echo "4. 卸载 Xray"
|
||||
echo "5. 查看 Xray 配置"
|
||||
echo "6. 启动 Xray"
|
||||
echo "7. 停止 Xray"
|
||||
echo "8. 重启 Xray"
|
||||
echo "9. 查看运行状态"
|
||||
echo "0. 退出脚本"
|
||||
echo "=================================================="
|
||||
read -p "请输入选项 [0-9]: " choice
|
||||
|
||||
case $choice in
|
||||
1) install_xray_core ;;
|
||||
2) configure_reality_simple ;;
|
||||
3) configure_reality_dokodemo ;;
|
||||
4) uninstall_xray ;;
|
||||
5) view_config_xray ;;
|
||||
6) manage_xray_service start ;;
|
||||
7) manage_xray_service stop ;;
|
||||
8) manage_xray_service restart ;;
|
||||
9) manage_xray_service status ;;
|
||||
0) break ;;
|
||||
*) echo -e "${RED}无效选项,请重试。${NC}" ;;
|
||||
esac
|
||||
[ "$choice" != "0" ] && [ "$choice" != "9" ] && read -p "按 Enter 键返回..."
|
||||
done
|
||||
}
|
||||
|
||||
# --- 脚本入口 ---
|
||||
check_root
|
||||
xray_menu
|
||||
echo "脚本已退出。"
|
||||
|
||||
Reference in New Issue
Block a user