Compare commits
77 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08ebda7617 | ||
|
|
9dc4858d2f | ||
|
|
62ec78ac54 | ||
|
|
990f42843e | ||
|
|
a03b0f397a | ||
|
|
b7d979e8a0 | ||
|
|
9e5865219b | ||
|
|
683a9a68f0 | ||
|
|
f86de491ed | ||
|
|
f1078a2ecd | ||
|
|
70f71d4b5e | ||
|
|
97686c7908 | ||
|
|
c925536970 | ||
|
|
7a847caa5c | ||
|
|
00e91414e6 | ||
|
|
0c58672c3b | ||
|
|
f45ed259cb | ||
|
|
d962dcd36e | ||
|
|
bf72ff2521 | ||
|
|
9a3e20082c | ||
|
|
f1f54ce1b5 | ||
|
|
796ac78f05 | ||
|
|
d0341d1324 | ||
|
|
3f5c3eb348 | ||
|
|
8adfd590fa | ||
|
|
5ed3434bf3 | ||
|
|
0e9714c3f0 | ||
|
|
774b5955ad | ||
|
|
f79590b229 | ||
|
|
0c884a87fc | ||
|
|
dd80d3601b | ||
|
|
f3bc373407 | ||
|
|
adca43cbba | ||
|
|
bb01321871 | ||
|
|
745e09c77f | ||
|
|
3e9a22b044 | ||
|
|
77a86350a8 | ||
|
|
6101e89a57 | ||
|
|
e9f4747a12 | ||
|
|
fdfc3b5e11 | ||
|
|
b2a81f7964 | ||
|
|
48604a2692 | ||
|
|
05bc3fb9b4 | ||
|
|
6163d72e2a | ||
|
|
18adcb65ce | ||
|
|
0319d932e3 | ||
|
|
e3801150c0 | ||
|
|
5cab57adf4 | ||
|
|
35a9f84893 | ||
|
|
9286478963 | ||
|
|
0cab56158a | ||
|
|
27e9871c8b | ||
|
|
016d4103a8 | ||
|
|
44bf650f26 | ||
|
|
2bbde50393 | ||
|
|
496eb641e6 | ||
|
|
14e6d30cd3 | ||
|
|
9d0fed291e | ||
|
|
1409916165 | ||
|
|
319ae7be6c | ||
|
|
6951d0d46f | ||
|
|
c68d16b360 | ||
|
|
d9d342437f | ||
|
|
4858bfa772 | ||
|
|
63839669ce | ||
|
|
a76a47ffab | ||
|
|
544eb665b8 | ||
|
|
b80d7dc367 | ||
|
|
26d0d36b31 | ||
|
|
305c40ab16 | ||
|
|
fa6f416c13 | ||
|
|
16184ffd47 | ||
|
|
7307383451 | ||
|
|
4ac024f8a7 | ||
|
|
c6349dba03 | ||
|
|
b2c8f5178e | ||
|
|
1fcad6d680 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
||||
conf/key.txt
|
||||
conf/config.json
|
||||
log/*
|
||||
|
||||
42
README.md
42
README.md
@ -1,59 +1,64 @@
|
||||
# 说明
|
||||
|
||||
## 前提
|
||||
|
||||
提前安装好以下软件
|
||||
|
||||
- git
|
||||
- curl
|
||||
- docker
|
||||
- docker-compose
|
||||
- jq - 用于查看json文件, 提取json文件信息. 编辑json文件
|
||||
- jq - 用于查看 json 文件, 提取 json 文件信息. 编辑 json 文件
|
||||
- qrencode - (可选, 非必要)用于生成二维码
|
||||
|
||||
## 快速开始
|
||||
|
||||
1. 下载项目
|
||||
|
||||
```bash
|
||||
git clone https://gittea.wingogo.top/William/xray_docker.git
|
||||
git clone https://gitea.9001001.xyz/William/xray_docker.git
|
||||
```
|
||||
|
||||
2. 进入项目目录
|
||||
|
||||
```bash
|
||||
cd xray_docker
|
||||
```
|
||||
|
||||
3. 初始化xray配置, 设置密钥和uuid, **第一次运行必须执行**
|
||||
```bash
|
||||
bash ./bin/init.sh
|
||||
```
|
||||
3. 执行命令生成配置并启动容器
|
||||
|
||||
4. 启动
|
||||
```
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
5. 查看分享链接
|
||||
```bash
|
||||
bash ./bin/print_share_link.sh
|
||||
bash ./bin/run.sh
|
||||
```
|
||||
|
||||
## 停止
|
||||
|
||||
如果需要停止服务, 进入项目目录, 执行以下命令
|
||||
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
## 更新镜像
|
||||
|
||||
进入项目目录, 执行以下命令
|
||||
|
||||
```bash
|
||||
bash ./bin/update_docker_images.sh
|
||||
```
|
||||
|
||||
## 查看分享链接
|
||||
|
||||
进入项目目录, 执行以下命令
|
||||
|
||||
```bash
|
||||
bash ./bin/print_share_link.sh
|
||||
```
|
||||
|
||||
## 修改端口
|
||||
修改conf/config.json
|
||||
|
||||
修改 conf/config.json
|
||||
|
||||
```json
|
||||
// ...
|
||||
|
||||
@ -70,7 +75,8 @@ bash ./bin/print_share_link.sh
|
||||
```
|
||||
|
||||
## 参考信息
|
||||
- [xray官方文档](https://xtls.github.io/)
|
||||
- [xray代码仓库](https://github.com/xtls/xray-core)
|
||||
- [xray docker镜像](https://hub.docker.com/r/teddysun/xray)
|
||||
- [xray安装命令](https://github.com/XTLS/Xray-install)
|
||||
|
||||
- [xray 官方文档](https://xtls.github.io/)
|
||||
- [xray 代码仓库](https://github.com/xtls/xray-core)
|
||||
- [xray docker 镜像](https://hub.docker.com/r/teddysun/xray)
|
||||
- [xray 安装命令](https://github.com/XTLS/Xray-install)
|
||||
|
||||
66
bin/create_config.sh
Normal file
66
bin/create_config.sh
Normal file
@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
|
||||
create_reality_config(){
|
||||
local script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
|
||||
local config_dir=$(readlink -f "$script_dir/../conf") # 配置文件绝对路径
|
||||
cp "$config_dir/template/reality_config.json" "$config_dir/config.json"
|
||||
|
||||
# 生成uui, 写入到config.json文件
|
||||
bash $script_dir/update_uuid.sh
|
||||
|
||||
# 生成密钥对, 修改config.json中的密钥属性
|
||||
bash $script_dir/update_key.sh
|
||||
|
||||
# 设置端口
|
||||
bash $script_dir/update_port.sh
|
||||
|
||||
# 设置realty_dest
|
||||
bash $script_dir/update_reality_dest.sh www.pranichealingsrilanka.com
|
||||
|
||||
echo "初始化完成"
|
||||
}
|
||||
|
||||
create_xhttp_reality_config(){
|
||||
local script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
|
||||
local config_dir=$(readlink -f "$script_dir/../conf") # 配置文件绝对路径
|
||||
cp "$config_dir/template/xhttp_reality_config.json" "$config_dir/config.json"
|
||||
|
||||
# 生成uui, 写入到config.json文件
|
||||
bash $script_dir/update_uuid.sh
|
||||
|
||||
# 生成密钥对, 修改config.json中的密钥属性
|
||||
bash $script_dir/update_key.sh
|
||||
|
||||
# 生成xhttp_path, 写入到config.json文件
|
||||
bash $script_dir/update_xhttp_path.sh
|
||||
|
||||
# 设置realty_dest
|
||||
bash $script_dir/update_reality_dest.sh www.pranichealingsrilanka.com
|
||||
|
||||
# 设置端口
|
||||
bash $script_dir/update_port.sh
|
||||
}
|
||||
|
||||
|
||||
create_config(){
|
||||
local script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
source "$script_dir/utils/base.sh"
|
||||
# 检查jq是否安装
|
||||
check_jq
|
||||
|
||||
echo "请选择配置文件类型:"
|
||||
echo "1. 创建reality配置"
|
||||
echo "2. 创建xhttp_reality配置"
|
||||
read -p "请输入选择 (1 或 2): " choice
|
||||
case $choice in
|
||||
1) create_reality_config ;;
|
||||
2) create_xhttp_reality_config ;;
|
||||
*) echo "无效选择,退出" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
create_config
|
||||
|
||||
|
||||
15
bin/init.sh
15
bin/init.sh
@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 安装xray
|
||||
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
|
||||
|
||||
script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
|
||||
# 生成uui, 写入到config.json文件
|
||||
bash $script_dir/update_uuid.sh
|
||||
|
||||
# 生成密钥对, 修改config.json中的密钥属性
|
||||
bash $script_dir/update_key.sh
|
||||
|
||||
# 打印分享链接
|
||||
bash $script_dir/print_share_link.sh
|
||||
@ -1,40 +1,96 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 检查 jq 是否安装
|
||||
if ! command -v jq &> /dev/null; then
|
||||
echo "jq 未安装"
|
||||
exit 1
|
||||
fi
|
||||
print_reality_share_link(){
|
||||
local script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
local config_dir=$(readlink -f "$script_dir/../conf") # 配置文件绝对路径
|
||||
|
||||
# 获取本机IP
|
||||
local ipv4=$(curl -4 -sSL --connect-timeout 3 --retry 2 ip.sb || echo "null")
|
||||
|
||||
script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
config_dir=$(readlink -f "$script_dir/../conf") # 配置文件绝对路径
|
||||
local uuid=$(jq -r '.inbounds[0].settings.clients[0].id' $config_dir/config.json)
|
||||
local port=$(jq -r '.inbounds[0].port' $config_dir/config.json)
|
||||
local dest=$(jq -r '.inbounds[0].streamSettings.realitySettings.dest' $config_dir/config.json)
|
||||
local sni=$(echo $dest | awk -F ':' '{print $1}')
|
||||
local network="tcp"
|
||||
local public_key=$(cat $config_dir/key.txt | grep "Password" | awk -F ': ' '{print $2}')
|
||||
|
||||
# 获取本机IP
|
||||
ipv4=$(curl -4 -sSL --connect-timeout 3 --retry 2 ip.sb || echo "null")
|
||||
# 打印配置信息
|
||||
echo -e "\033[32m" # config info with green color
|
||||
echo "ipv4: $ipv4"
|
||||
echo "port: $port"
|
||||
echo "uuid: $uuid"
|
||||
echo "dest: $dest"
|
||||
echo "sni: $sni"
|
||||
echo "publicKey/password: $public_key"
|
||||
echo "network: $network"
|
||||
if [ "$ipv4" != "null" ]; then
|
||||
sub_ipv4="vless://$uuid@$ipv4:$port?encryption=none&security=reality&type=$network&sni=$sni&fp=chrome&pbk=$public_key&flow=xtls-rprx-vision#我的最新vless机场"
|
||||
echo ""
|
||||
echo "IPV4 分享连接: $sub_ipv4"
|
||||
echo ""
|
||||
|
||||
uuid=$(jq -r '.inbounds[0].settings.clients[0].id' $config_dir/config.json)
|
||||
port=$(jq -r '.inbounds[0].port' $config_dir/config.json)
|
||||
dest=$(jq -r '.inbounds[0].streamSettings.realitySettings.dest' $config_dir/config.json)
|
||||
sni=$(echo $dest | awk -F ':' '{print $1}')
|
||||
network="tcp"
|
||||
public_key=$(cat $config_dir/key.txt | grep "Public" | awk -F ': ' '{print $2}')
|
||||
|
||||
# 打印配置信息
|
||||
echo -e "\033[32m" # config info with green color
|
||||
echo "IPV4: $ipv4"
|
||||
echo "PORT: $port"
|
||||
echo "UUID: $uuid"
|
||||
echo "DEST: $dest"
|
||||
echo "PUBLIC_KEY: $public_key"
|
||||
echo "NETWORK: $network"
|
||||
if [ "$ipv4" != "null" ]; then
|
||||
sub_ipv4="vless://$uuid@$ipv4:$port?encryption=none&security=reality&type=$network&sni=$sni&fp=chrome&pbk=$public_key&flow=xtls-rprx-vision#my_docker_vless_reality_vision"
|
||||
echo "IPV4 订阅连接: $sub_ipv4"
|
||||
# 如果qrencode安装了,则打印二维码
|
||||
if command -v qrencode &> /dev/null; then
|
||||
echo -e "IPV4 订阅二维码:\n$(echo "$sub_ipv4" | qrencode -o - -t UTF8)"
|
||||
echo -e "IPV4 分享二维码:\n$(echo "$sub_ipv4" | qrencode -o - -t UTF8)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "\033[0m"
|
||||
echo -e "\033[0m"
|
||||
}
|
||||
|
||||
|
||||
print_xhttp_reality_share_link(){
|
||||
local script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
local config_dir=$(readlink -f "$script_dir/../conf") # xray配置文件绝对路径
|
||||
|
||||
local ipv4=$(curl -4 -sSL --connect-timeout 3 --retry 2 ip.sb || echo "null") # 本机IP
|
||||
local uuid=$(jq -r '.inbounds[0].settings.clients[0].id' $config_dir/config.json)
|
||||
local port=$(jq -r '.inbounds[0].port' $config_dir/config.json)
|
||||
local dest=$(jq -r '.inbounds[0].streamSettings.realitySettings.dest' $config_dir/config.json)
|
||||
local sni=$(echo $dest | awk -F ':' '{print $1}')
|
||||
local network=$(jq -r '.inbounds[0].streamSettings.network' $config_dir/config.json)
|
||||
local xhttp_path=$(jq -r ".inbounds[0].streamSettings.xhttpSettings.path" $config_dir/config.json)
|
||||
local public_key=$(cat $config_dir/key.txt | grep "Password" | awk -F ': ' '{print $2}')
|
||||
|
||||
|
||||
# 打印配置信息
|
||||
echo -e "\033[32m" # config info with green color
|
||||
echo "ipv4: $ipv4"
|
||||
echo "port: $port"
|
||||
echo "uuid: $uuid"
|
||||
echo "dest: $dest"
|
||||
echo "sni: $sni"
|
||||
echo "publicKey/password: $public_key"
|
||||
echo "network: $network"
|
||||
echo "xhttp_path: $xhttp_path"
|
||||
if [ "$ipv4" != "null" ]; then
|
||||
sub_ipv4="vless://$uuid@$ipv4:$port?encryption=none&security=reality&type=$network&sni=$sni&fp=chrome&pbk=$public_key&path=$xhttp_path&mode=auto#${ipv4}-my_xray_xhttp_reality"
|
||||
echo ""
|
||||
echo "ipv4 分享连接: $sub_ipv4"
|
||||
echo ""
|
||||
# 如果qrencode安装了,则打印二维码
|
||||
if command -v qrencode &> /dev/null; then
|
||||
echo -e "ipv4 分享二维码:\n$(echo "$sub_ipv4" | qrencode -o - -t UTF8)"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "\033[0m"
|
||||
}
|
||||
|
||||
print_share_link(){
|
||||
local script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
local config_dir=$(readlink -f "$script_dir/../conf") # xray配置文件绝对路径
|
||||
|
||||
# 检查 jq 是否安装
|
||||
source $script_dir/utils/base.sh
|
||||
check_jq
|
||||
|
||||
local xhttp_path=$(jq -r ".inbounds[0].streamSettings.xhttpSettings.path" $config_dir/config.json)
|
||||
if [ -z $xhttp_path ] || [ "$xhttp_path" = "null" ];then
|
||||
print_reality_share_link
|
||||
else
|
||||
print_xhttp_reality_share_link
|
||||
fi
|
||||
}
|
||||
|
||||
print_share_link
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Remove Xray
|
||||
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ remove
|
||||
21
bin/run.sh
Normal file
21
bin/run.sh
Normal file
@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
config_dir=$(readlink -f "$script_dir/../conf") # 配置文件绝对路径
|
||||
|
||||
# 如果配置文件不存在或者空白
|
||||
if [ ! -e "$config_dir/config.json" ] || [ ! -s "$config_dir/config.json" ] ; then
|
||||
bash "$script_dir/create_config.sh"
|
||||
fi
|
||||
# 如果配置未初始化
|
||||
uuid=$(jq -r '.inbounds[0].settings.clients[0].id' "$config_dir/config.json")
|
||||
if [ "$uuid" = "你的UUID" ] || [ -z "$uuid" ]; then
|
||||
# 执行初始化脚本
|
||||
bash "$script_dir/create_config.sh"
|
||||
fi
|
||||
|
||||
## 启动docker容器
|
||||
docker-compose -f $script_dir/../docker-compose.yml up -d
|
||||
|
||||
# 打印分享链接
|
||||
bash $script_dir/print_share_link.sh
|
||||
@ -1,19 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
docker_compose_file="$script_dir/../docker-compose.yml" # docker-compose.yml文件路径
|
||||
|
||||
# 检查是否存在 docker-compose.yml 文件
|
||||
if [ ! -f $docker_compose_file ]; then
|
||||
update_docker_images(){
|
||||
script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
docker_compose_file="$script_dir/../docker-compose.yml" # docker-compose.yml文件路径
|
||||
|
||||
# 检查是否存在 docker-compose.yml 文件
|
||||
if [ ! -f $docker_compose_file ]; then
|
||||
echo "Error: docker-compose.yml 文件不存在."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "正在关闭容器.."
|
||||
docker-compose -f $docker_compose_file down
|
||||
echo "正在关闭容器.."
|
||||
docker-compose -f $docker_compose_file down
|
||||
|
||||
echo "正在更新镜像.."
|
||||
docker-compose -f $docker_compose_file pull
|
||||
echo "正在更新镜像.."
|
||||
docker-compose -f $docker_compose_file pull
|
||||
|
||||
echo "正在启动容器.."
|
||||
docker-compose -f $docker_compose_file up -d
|
||||
echo "正在删除未使用的镜像..."
|
||||
docker image prune -f
|
||||
|
||||
echo "正在启动容器.."
|
||||
docker-compose -f $docker_compose_file up -d
|
||||
}
|
||||
|
||||
update_docker_images
|
||||
|
||||
@ -1,15 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
config_dir="$script_dir/../conf"
|
||||
update_key(){
|
||||
|
||||
# Save keys to key.txt
|
||||
xray x25519 > $config_dir/key.txt
|
||||
script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
config_dir="$script_dir/../conf"
|
||||
source $script_dir/utils/jq_util.sh
|
||||
|
||||
private_key=$(grep "Private key" $config_dir/key.txt | awk -F ': ' '{print $2}')
|
||||
# 使用docker运行xray镜像生成密钥文件
|
||||
docker run --rm teddysun/xray:latest /usr/bin/xray x25519 > $config_dir/key.txt
|
||||
|
||||
# 修改config.json密钥属性
|
||||
jq ".inbounds[0].streamSettings.realitySettings.privateKey=\"$private_key\"" $config_dir/config.json > $config_dir/config_temp.json
|
||||
mv $config_dir/config_temp.json $config_dir/config.json
|
||||
# 获取私钥
|
||||
private_key=$(grep "Private" $config_dir/key.txt | awk -F ': ' '{print $2}')
|
||||
|
||||
echo "生成和设置密钥成功."
|
||||
# 修改config.json密钥属性
|
||||
modify_json_file "$config_dir/config.json" ".inbounds[0].streamSettings.realitySettings.privateKey" "$private_key"
|
||||
|
||||
echo "生成和设置密钥成功."
|
||||
|
||||
}
|
||||
|
||||
|
||||
update_key
|
||||
57
bin/update_port.sh
Normal file
57
bin/update_port.sh
Normal file
@ -0,0 +1,57 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 查找空闲端口
|
||||
find_free_port() {
|
||||
local start="${1:-10001}"
|
||||
local max="${2:-65535}"
|
||||
|
||||
# 收集当前监听端口(TCP + UDP)
|
||||
local used_ports raw
|
||||
if command -v ss >/dev/null 2>&1; then
|
||||
raw=$(ss -lntu 2>/dev/null || true)
|
||||
used_ports=$(printf "%s\n" "$raw" | awk '{print $5}' | sed -n '2,$p' | sed -E 's/.*[:]//g' | sed '/^$/d')
|
||||
elif command -v netstat >/dev/null 2>&1; then
|
||||
raw=$(netstat -lntu 2>/dev/null || true)
|
||||
used_ports=$(printf "%s\n" "$raw" | awk '{print $4}' | sed -n '2,$p' | sed -E 's/.*[:]//g' | sed '/^$/d')
|
||||
elif command -v lsof >/dev/null 2>&1; then
|
||||
raw=$(lsof -i -P -n 2>/dev/null || true)
|
||||
used_ports=$(printf "%s\n" "$raw" | awk '/LISTEN/ {print $9}' | sed -E 's/.*[:]//g' | sed '/^$/d')
|
||||
else
|
||||
echo "Error: neither ss, netstat nor lsof is available to check listening ports." >&2
|
||||
return 2
|
||||
fi
|
||||
|
||||
# 用关联数组记录已占用端口(需要 bash 4+)
|
||||
declare -A used_map
|
||||
local p
|
||||
for p in $used_ports; do
|
||||
# 过滤掉非数字
|
||||
if [[ $p =~ ^[0-9]+$ ]]; then
|
||||
used_map["$p"]=1
|
||||
fi
|
||||
done
|
||||
|
||||
# 从 start 到 max 逐个检查
|
||||
for ((port = start; port <= max; port++)); do
|
||||
if [[ -z "${used_map[$port]}" ]]; then
|
||||
echo "$port"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
# 没找到可用端口
|
||||
echo "Error: No available port found in range $start-$max" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
update_port(){
|
||||
local script_dir=$(cd "$(dirname "$0")"; pwd)
|
||||
local config_dir="$script_dir/../conf"
|
||||
source "$script_dir/utils/jq_util.sh"
|
||||
|
||||
local port=$(find_free_port)
|
||||
modify_json_file "$config_dir/config.json" ".inbounds[0].port" "$port"
|
||||
echo "设置端口成功"
|
||||
}
|
||||
|
||||
update_port
|
||||
12
bin/update_reality_dest.sh
Normal file
12
bin/update_reality_dest.sh
Normal file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
update_reality_dest(){
|
||||
local script_dir=$(cd "$(dirname "$0")"; pwd)
|
||||
local config_dir="$script_dir/../conf"
|
||||
|
||||
local domain=$1
|
||||
sed -i "s/你的reality_dest/$domain/g" "$config_dir/config.json"
|
||||
echo "修改realty_dest成功"
|
||||
}
|
||||
|
||||
update_reality_dest $1
|
||||
@ -1,16 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
config_dir="$script_dir/../conf"
|
||||
update_uuid(){
|
||||
|
||||
# 生成 UUID
|
||||
uuid=$(xray uuid)
|
||||
script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
config_dir="$script_dir/../conf"
|
||||
|
||||
# 使用 jq 修改 JSON 文件
|
||||
jq ".inbounds[0].settings.clients[0].id=\"$uuid\"" $config_dir/config.json > $config_dir/config.json_tmp
|
||||
source $script_dir/utils/jq_util.sh
|
||||
|
||||
# 替换原始文件
|
||||
mv $config_dir/config.json_tmp $config_dir/config.json
|
||||
# 生成 UUID
|
||||
uuid=$(docker run --rm teddysun/xray:latest xray uuid)
|
||||
|
||||
# 验证结果
|
||||
echo "设置UUID成功."
|
||||
#修改 UUID
|
||||
modify_json_file "$config_dir/config.json" ".inbounds[0].settings.clients[0].id" "$uuid"
|
||||
|
||||
echo "设置UUID成功."
|
||||
}
|
||||
|
||||
update_uuid
|
||||
|
||||
18
bin/update_xhttp_path.sh
Normal file
18
bin/update_xhttp_path.sh
Normal file
@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
update_xhttp_path(){
|
||||
|
||||
script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本文件绝对路径
|
||||
config_dir="$script_dir/../conf"
|
||||
source $script_dir/utils/jq_util.sh
|
||||
|
||||
path_length="$(( RANDOM % 4 + 8 ))"
|
||||
xhttp_path="/"$(docker run --rm teddysun/xray:latest xray uuid | tr -d '-' | cut -c 1-$path_length)
|
||||
|
||||
# 修改config.json的xhttp_path
|
||||
modify_json_file "$config_dir/config.json" ".inbounds[0].streamSettings.xhttpSettings.path" "$xhttp_path"
|
||||
|
||||
echo "设置xhttp_path成功"
|
||||
}
|
||||
|
||||
update_xhttp_path
|
||||
82
bin/utils/base.sh
Normal file
82
bin/utils/base.sh
Normal file
@ -0,0 +1,82 @@
|
||||
#!/bin/bash
|
||||
|
||||
red(){
|
||||
echo -e "\033[31m$1\033[0m"
|
||||
}
|
||||
|
||||
|
||||
# 获取系统包管理器
|
||||
get_package_manager(){
|
||||
if command -v apt-get &> /dev/null; then
|
||||
echo "apt-get"
|
||||
elif command -v yum &> /dev/null; then
|
||||
echo "yum"
|
||||
else
|
||||
echo "未知的系统包管理器"
|
||||
return 1 # 返回错误状态码
|
||||
fi
|
||||
}
|
||||
|
||||
# 检查 jq 是否已安装
|
||||
check_jq() {
|
||||
if command -v jq >/dev/null 2>&1; then
|
||||
return 0
|
||||
else
|
||||
echo "jq 未安装"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 检查 Docker 是否已安装
|
||||
check_docker() {
|
||||
if command -v docker >/dev/null 2>&1; then
|
||||
return 0
|
||||
else
|
||||
echo "Docker 未安装"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 检查 docker-compose 是否已安装
|
||||
check_docker_compose() {
|
||||
if command -v docker-compose >/dev/null 2>&1; then
|
||||
return 0
|
||||
elif docker compose version >/dev/null 2>&1; then ## Docker 内置 compose 已安装
|
||||
return 0
|
||||
else
|
||||
echo "docker-compose 未安装"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 安装jq
|
||||
install_jq(){
|
||||
local package_manager=$(get_package_manager) # 获取包管理器
|
||||
if [[ -z "$package_manager" ]]; then
|
||||
echo "无法识别系统包管理器"
|
||||
return 1 # 无法识别包管理器
|
||||
fi
|
||||
|
||||
if [[ "$package_manager" == "apt-get" ]]; then
|
||||
sudo apt-get install -y jq
|
||||
elif [[ "$package_manager" == "yum" ]]; then
|
||||
sudo yum install -y jq
|
||||
else
|
||||
echo "未知的系统包管理器"
|
||||
return 1 # 未知的包管理器
|
||||
fi
|
||||
}
|
||||
|
||||
# 安装docker
|
||||
install_docker(){
|
||||
echo 安装docker...
|
||||
curl -fsSL https://get.docker.com | bash -s docker
|
||||
}
|
||||
|
||||
# 安装docker-compose
|
||||
install_docker_compose(){
|
||||
echo 安装docker-compose...
|
||||
wget -O /usr/local/bin/docker-compose https://github.com/docker/compose/releases/download/v2.29.0/docker-compose-linux-x86_64
|
||||
chmod +x /usr/local/bin/docker-compose
|
||||
}
|
||||
|
||||
27
bin/utils/jq_util.sh
Normal file
27
bin/utils/jq_util.sh
Normal file
@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 修改json文件的属性值
|
||||
# 案例1:modify_json_file "/foo/bar.json" "person.name" "张三"
|
||||
# 案例2:modify_json_file "/foo/bar.json" "servers" '["a.com", "b.com"]'
|
||||
# 该函数能自动处理不同数据类型,包括数组、对象和数字等。
|
||||
function modify_json_file() {
|
||||
local json_file=$1 # json文件路径
|
||||
local key=$2 # 要修改的key
|
||||
local value=$3 # 要修改的value
|
||||
|
||||
#如果key的值是.开头, 则去掉.号
|
||||
if [[ ${key} == "."* ]]; then
|
||||
key=${key:1}
|
||||
fi
|
||||
|
||||
# 检查值是否为有效的 JSON 格式(如数组、对象或数字)。
|
||||
# 如果是,则直接将值传递给 jq,无需引号。
|
||||
if echo "${value}" | jq . >/dev/null 2>&1; then
|
||||
jq ".${key} = ${value}" "${json_file}" > "${json_file}.tmp"
|
||||
else
|
||||
# 否则,将值视为字符串,并添加引号。
|
||||
jq ".${key} = \"${value}\"" "${json_file}" > "${json_file}.tmp"
|
||||
fi
|
||||
|
||||
mv ${json_file}.tmp ${json_file}
|
||||
}
|
||||
@ -56,12 +56,12 @@
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": true,
|
||||
"dest": "www.expedia.com:443",
|
||||
"dest": "你的reality_dest:443",
|
||||
"xver": 0,
|
||||
"maxTimeDiff": 0,
|
||||
"minClientVer": "",
|
||||
"serverNames": [
|
||||
"www.expedia.com"
|
||||
"你的reality_dest"
|
||||
],
|
||||
"privateKey": "你的密钥",
|
||||
"shortIds": [
|
||||
182
conf/template/xhttp_reality_config.json
Normal file
182
conf/template/xhttp_reality_config.json
Normal file
@ -0,0 +1,182 @@
|
||||
{
|
||||
"log": {
|
||||
"dnsLog": false,
|
||||
"access": "/var/log/xray/access.log",
|
||||
"error": "/var/log/xray/error.log",
|
||||
"loglevel": "error",
|
||||
"maskAddress": ""
|
||||
},
|
||||
"routing": {
|
||||
"domainStrategy": "IPIfNonMatch",
|
||||
"rules": [
|
||||
{
|
||||
"inboundTag": [
|
||||
"api"
|
||||
],
|
||||
"outboundTag": "api",
|
||||
"type": "field"
|
||||
},
|
||||
{
|
||||
"domain": [
|
||||
"domain:byr.pt"
|
||||
],
|
||||
"type": "field",
|
||||
"outboundTag": "direct"
|
||||
},
|
||||
{
|
||||
"domain": [
|
||||
"domain:iqiyi.com",
|
||||
"domain:video.qq.com",
|
||||
"domain:youku.com"
|
||||
],
|
||||
"type": "field",
|
||||
"outboundTag": "blocked"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"ip": [
|
||||
"geoip:cn",
|
||||
"geoip:private"
|
||||
],
|
||||
"outboundTag": "blocked"
|
||||
},
|
||||
{
|
||||
"protocol": [
|
||||
"bittorrent"
|
||||
],
|
||||
"type": "field",
|
||||
"outboundTag": "blocked"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dns": {
|
||||
"servers": [
|
||||
"https+local://cloudflare-dns.com/dns-query",
|
||||
"1.1.1.1",
|
||||
"1.0.0.1",
|
||||
"8.8.8.8",
|
||||
"8.8.4.4",
|
||||
"localhost"
|
||||
]
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"listen": "0.0.0.0",
|
||||
"port": 8005,
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "你的UUID",
|
||||
"flow": ""
|
||||
}
|
||||
],
|
||||
"decryption": "none",
|
||||
"fallbacks": []
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "xhttp",
|
||||
"realitySettings": {
|
||||
"dest": "你的reality_dest:443",
|
||||
"maxClient": "",
|
||||
"maxTimediff": 0,
|
||||
"minClient": "",
|
||||
"privateKey": "",
|
||||
"serverNames": [
|
||||
"你的reality_dest"
|
||||
],
|
||||
"shortIds": [
|
||||
""
|
||||
],
|
||||
"show": false,
|
||||
"xver": 0
|
||||
},
|
||||
"security": "reality",
|
||||
"xhttpSettings": {
|
||||
"headers": {},
|
||||
"host": "",
|
||||
"mode": "auto",
|
||||
"noSSEHeader": false,
|
||||
"path": "/14e077b4",
|
||||
"scMaxBufferedPosts": 30,
|
||||
"scMaxEachPostBytes": "1000000",
|
||||
"scStreamUpServerSecs": "20-80",
|
||||
"xPaddingBytes": "100-1000"
|
||||
}
|
||||
},
|
||||
"tag": "inbound-xx",
|
||||
"sniffing": {
|
||||
"enabled": false,
|
||||
"destOverride": [
|
||||
"http",
|
||||
"tls",
|
||||
"quic",
|
||||
"fakedns"
|
||||
],
|
||||
"metadataOnly": false,
|
||||
"routeOnly": false
|
||||
},
|
||||
"allocate": {
|
||||
"strategy": "always",
|
||||
"refresh": 5,
|
||||
"concurrency": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"listen": "127.0.0.1",
|
||||
"port": 65432,
|
||||
"protocol": "dokodemo-door",
|
||||
"settings": {
|
||||
"address": "127.0.0.1"
|
||||
},
|
||||
"streamSettings": null,
|
||||
"tag": "api",
|
||||
"sniffing": null,
|
||||
"allocate": null
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"tag": "direct",
|
||||
"protocol": "freedom",
|
||||
"settings": {
|
||||
"domainStrategy": "AsIs",
|
||||
"redirect": "",
|
||||
"noises": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "blocked",
|
||||
"protocol": "blackhole",
|
||||
"settings": {}
|
||||
}
|
||||
],
|
||||
"transport": null,
|
||||
"policy": {
|
||||
"levels": {
|
||||
"0": {
|
||||
"statsUserDownlink": true,
|
||||
"statsUserUplink": true
|
||||
}
|
||||
},
|
||||
"system": {
|
||||
"statsInboundDownlink": true,
|
||||
"statsInboundUplink": true,
|
||||
"statsOutboundDownlink": false,
|
||||
"statsOutboundUplink": false
|
||||
}
|
||||
},
|
||||
"api": {
|
||||
"tag": "api",
|
||||
"services": [
|
||||
"HandlerService",
|
||||
"LoggerService",
|
||||
"StatsService"
|
||||
]
|
||||
},
|
||||
"stats": {},
|
||||
"reverse": null,
|
||||
"fakedns": null,
|
||||
"observatory": null,
|
||||
"burstObservatory": null
|
||||
}
|
||||
@ -1,10 +1,9 @@
|
||||
version: "3.9"
|
||||
|
||||
services:
|
||||
xray:
|
||||
image: teddysun/xray:latest
|
||||
restart: always
|
||||
container_name: xray
|
||||
container_name: "${COMPOSE_PROJECT_NAME}" # 容器名为文件夹名称
|
||||
network_mode: "host"
|
||||
volumes:
|
||||
- "./conf:/etc/xray"
|
||||
- "./log:/var/log/xray"
|
||||
|
||||
151
install.sh
Normal file
151
install.sh
Normal file
@ -0,0 +1,151 @@
|
||||
#!/bin/bash
|
||||
|
||||
restart_docker(){
|
||||
echo "正在重启容器..."
|
||||
docker-compose -f ./docker-compose.yml down
|
||||
docker-compose -f ./docker-compose.yml up -d
|
||||
}
|
||||
|
||||
|
||||
check_config(){
|
||||
local config_dir="./conf"
|
||||
# 如果配置文件不存在或者空白
|
||||
if [ ! -e "$config_dir/config.json" ] || [ ! -s "$config_dir/config.json" ];then
|
||||
echo "请先'创建配置'"
|
||||
exit 0
|
||||
fi
|
||||
# 如果配置未初始化
|
||||
uuid=$(jq -r '.inbounds[0].settings.clients[0].id' "$config_dir/config.json")
|
||||
if [ "$uuid" = "你的UUID" ] || [ -z "$uuid" ]; then
|
||||
echo "请先'创建配置'"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# 检查依赖
|
||||
check_dependencies() {
|
||||
# 内部退出函数:只在本函数作用域内有效
|
||||
exit_with_dep_error() {
|
||||
echo "请执行 安装依赖 操作"
|
||||
exit 1
|
||||
}
|
||||
|
||||
source ./bin/utils/base.sh
|
||||
check_jq || exit_with_dep_error
|
||||
check_docker || exit_with_dep_error
|
||||
check_docker_compose || exit_with_dep_error
|
||||
}
|
||||
|
||||
# 安装依赖
|
||||
install_dependencies() {
|
||||
source ./bin/utils/base.sh
|
||||
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
echo "jq 未安装,开始安装..."
|
||||
install_jq
|
||||
fi
|
||||
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "Docker 未安装,开始安装..."
|
||||
install_docker
|
||||
fi
|
||||
|
||||
if ! command -v docker-compose >/dev/null 2>&1; then
|
||||
echo "docker-compose 未安装,开始安装..."
|
||||
install_docker_compose
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
change_reality_dest(){
|
||||
local config_dir="./conf"
|
||||
|
||||
# 输入dest值
|
||||
local old_dest=$(jq -r '.inbounds[0].streamSettings.realitySettings.dest' "$config_dir/config.json")
|
||||
local dest
|
||||
read -p "请输入新的dest地址[当前地址: $old_dest]: " dest
|
||||
|
||||
local domain=$(echo "$dest" | awk -F ':' '{print $1}')
|
||||
|
||||
sed -i "s/你的reality_dest/$domain/g" "$config_dir/config.json"
|
||||
|
||||
echo "配置文件修改realty_dest成功!"
|
||||
echo "新的dest地址为: $dest"
|
||||
echo "新的serverNames数组为: [\"$domain\"]"
|
||||
}
|
||||
|
||||
main(){
|
||||
# 显示菜单
|
||||
echo "请选择一个操作:"
|
||||
echo "0. 安装依赖"
|
||||
echo "1. 创建配置 / 重置配置"
|
||||
echo "2. 启动容器"
|
||||
echo "3. 查看分享链接"
|
||||
echo "4. 停止容器"
|
||||
echo "5. 更新镜像"
|
||||
echo "6. 修改端口"
|
||||
echo "7. 修改Reality目标域名"
|
||||
echo "8. 退出"
|
||||
|
||||
# 读取用户选择
|
||||
read -p "输入您的选择: " choice
|
||||
|
||||
# 根据用户选择执行相应的操作
|
||||
case $choice in
|
||||
0)
|
||||
# 安装依赖
|
||||
install_dependencies
|
||||
;;
|
||||
1)
|
||||
# 创建配置 / 重置配置
|
||||
check_dependencies
|
||||
bash ./bin/create_config.sh
|
||||
;;
|
||||
2)
|
||||
# 启动容器
|
||||
echo "启动容器.."
|
||||
check_dependencies
|
||||
bash ./bin/run.sh
|
||||
;;
|
||||
3)
|
||||
# 查看分享链接
|
||||
echo "查看分享链接.."
|
||||
check_dependencies
|
||||
check_config
|
||||
bash ./bin/print_share_link.sh
|
||||
;;
|
||||
4)
|
||||
# 停止容器
|
||||
echo "正在停止容器.."
|
||||
docker-compose -f ./docker-compose.yml down
|
||||
;;
|
||||
5)
|
||||
# 更新镜像
|
||||
bash ./bin/update_docker_images.sh
|
||||
;;
|
||||
6)
|
||||
# 修改端口
|
||||
check_dependencies
|
||||
check_config
|
||||
bash ./bin/update_port.sh
|
||||
restart_docker
|
||||
;;
|
||||
7)
|
||||
# 修改Reality目标域名
|
||||
check_dependencies
|
||||
check_config
|
||||
change_reality_dest
|
||||
restart_docker
|
||||
;;
|
||||
8)
|
||||
# 退出
|
||||
echo "退出程序."
|
||||
;;
|
||||
*)
|
||||
echo "无效的选择, 请重新选择."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main
|
||||
Loading…
Reference in New Issue
Block a user