From 4adb219b11324c1304d607fb3efbb40ed4f43322 Mon Sep 17 00:00:00 2001 From: Olia Lisa Date: Thu, 21 May 2026 16:57:44 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E4=BB=A3=E7=A0=81,=20?= =?UTF-8?q?=E5=B0=86=E5=8F=98=E9=87=8F=E6=94=B9=E4=B8=BA=E5=A4=A7=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/create_config.sh | 60 ++++++++++++------------- bin/create_self_tls.sh | 18 ++++---- bin/domain.sh | 20 ++++----- bin/password.sh | 8 ++-- bin/port.sh | 70 +++++++++++++++--------------- bin/print_share_link.sh | 50 ++++++++++----------- bin/remote/update_docker_images.sh | 12 ++--- bin/run.sh | 10 ++--- bin/update_docker_images.sh | 12 ++--- 9 files changed, 130 insertions(+), 130 deletions(-) diff --git a/bin/create_config.sh b/bin/create_config.sh index a5ef50d..b9bfe88 100644 --- a/bin/create_config.sh +++ b/bin/create_config.sh @@ -2,11 +2,11 @@ create_acme_tls_config() { - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 - local config_dir="$script_dir/../config" - local config_file="$config_dir/config.json" + local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 + local CONFIG_DIR="$SCRIPT_DIR/../config" + local CONFIG_FILE="$CONFIG_DIR/config.json" - cp "$config_dir/template/tuic/tuic_acme_tls_config.json" "$config_file" + cp "$CONFIG_DIR/template/tuic/tuic_acme_tls_config.json" "$CONFIG_FILE" # 设置端口 update_port @@ -18,39 +18,39 @@ create_acme_tls_config() { update_uuid # 获取邮箱 - local user_email - read -p "请输入你的邮箱(可留空): " user_email - if [[ -z "$user_email" ]]; then - user_email="example@example.com" + local USER_EMAIL + read -p "请输入你的邮箱(可留空): " USER_EMAIL + if [[ -z "$USER_EMAIL" ]]; then + USER_EMAIL="example@example.com" fi # 获取域名 - local user_domain - read -p "请输入你的域名 (例如: example.com): " user_domain - while [[ -z "$user_domain" ]]; do + local USER_DOMAIN + read -p "请输入你的域名 (例如: example.com): " USER_DOMAIN + while [[ -z "$USER_DOMAIN" ]]; do echo "[错误] 域名不能为空" - read -p "请输入你的域名: " user_domain + read -p "请输入你的域名: " USER_DOMAIN done # 获取 Cloudflare API Token - local cloudflare_token - read -p "请输入你的 Cloudflare API Token: " cloudflare_token - while [[ -z "$cloudflare_token" ]]; do + local CLOUDFLARE_TOKEN + read -p "请输入你的 Cloudflare API Token: " CLOUDFLARE_TOKEN + while [[ -z "$CLOUDFLARE_TOKEN" ]]; do echo "[错误] Cloudflare API Token 不能为空" - read -p "请输入你的 Cloudflare API Token: " cloudflare_token + read -p "请输入你的 Cloudflare API Token: " CLOUDFLARE_TOKEN done - sed -i "s/你的邮箱/$user_email/g" "$config_file" - sed -i "s/你的域名/$user_domain/g" "$config_file" - sed -i "s/你的Cloudflare_API_Token/$cloudflare_token/g" "$config_file" + sed -i "s/你的邮箱/$USER_EMAIL/g" "$CONFIG_FILE" + sed -i "s/你的域名/$USER_DOMAIN/g" "$CONFIG_FILE" + sed -i "s/你的Cloudflare_API_Token/$CLOUDFLARE_TOKEN/g" "$CONFIG_FILE" green "成功创建配置" } create_self_tls_config() { - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 + local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 - cp "$script_dir/../config/template/tuic/tuic_self_tls_config.json" "$script_dir/../config/config.json" + cp "$SCRIPT_DIR/../config/template/tuic/tuic_self_tls_config.json" "$SCRIPT_DIR/../config/config.json" # 设置端口 update_port @@ -68,14 +68,14 @@ create_self_tls_config() { } create_config(){ - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 - local config_file="$script_dir/../config/config.json" + local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 + local CONFIG_FILE="$SCRIPT_DIR/../config/config.json" # 如果配置文件已存在,提示用户是否重新生成 - if [ -e "$config_file" ]; then - local regenerate - read -p "检测到配置已存在,是否重新生成配置?(y/n): " regenerate - if [ "$regenerate" != "y" ] && [ "$regenerate" != "Y" ]; then + if [ -e "$CONFIG_FILE" ]; then + local REGENERATE + read -p "检测到配置已存在,是否重新生成配置?(y/n): " REGENERATE + if [ "$REGENERATE" != "y" ] && [ "$REGENERATE" != "Y" ]; then echo "取消重新生成配置." return fi @@ -84,9 +84,9 @@ create_config(){ echo "请选择配置类型:" echo "1. 自签名证书配置" echo "2. tls证书配置" - local choice - read -p "输入您的选择: " choice - case $choice in + local CHOICE + read -p "输入您的选择: " CHOICE + case $CHOICE in 1) echo "重置为自签名证书配置..." create_self_tls_config diff --git a/bin/create_self_tls.sh b/bin/create_self_tls.sh index 7426931..d79a564 100644 --- a/bin/create_self_tls.sh +++ b/bin/create_self_tls.sh @@ -2,22 +2,22 @@ # 生成自签名证书 create_self_tls() { - local domain="${1:-bing.com}" - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 - local key_dir="$script_dir/../tls/self-tls" - local config_file="$script_dir/../config/config.json" + local DOMAIN="${1:-bing.com}" + local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 + local KEY_DIR="$SCRIPT_DIR/../tls/self-tls" + local CONFIG_FILE="$SCRIPT_DIR/../config/config.json" # 创建存放证书的目录 - mkdir -p "$key_dir" + mkdir -p "$KEY_DIR" # 生成自签名证书 openssl req -x509 -nodes -newkey ec:<(openssl ecparam -name prime256v1) \ - -keyout "$key_dir/server.key" \ - -out "$key_dir/server.crt" \ - -subj "/CN=$domain" \ + -keyout "$KEY_DIR/server.key" \ + -out "$KEY_DIR/server.crt" \ + -subj "/CN=$DOMAIN" \ -days 36500 # 更新config.json文件中的域名信息 - modify_json_file "$config_file" "inbounds[0].tls.server_name" "$domain" + modify_json_file "$CONFIG_FILE" "inbounds[0].tls.server_name" "$DOMAIN" } diff --git a/bin/domain.sh b/bin/domain.sh index 306cf7c..eaeb6ff 100644 --- a/bin/domain.sh +++ b/bin/domain.sh @@ -2,32 +2,32 @@ # 修改域名 update_domain(){ - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 - local config_file="$script_dir/../config/config.json" + local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 + local CONFIG_FILE="$SCRIPT_DIR/../config/config.json" # 检查jq是否安装 check_jq # 获取旧的domain - local old_domain=$(jq -r ".inbounds[0].tls.server_name" "$config_file") + local OLD_DOMAIN=$(jq -r ".inbounds[0].tls.server_name" "$CONFIG_FILE") # 输入新的domain - local domain - read -p "请输入域名[当前域名: $old_domain]: " domain + local DOMAIN + read -p "请输入域名[当前域名: $OLD_DOMAIN]: " DOMAIN # 如果输入为空,退出脚本 - if [[ -z "$domain" ]]; then + if [[ -z "$DOMAIN" ]]; then echo "输入域名为空,退出脚本" exit 1 fi # 修改server_name - modify_json_file "$config_file" ".inbounds[0].tls.server_name" "$domain" + modify_json_file "$CONFIG_FILE" ".inbounds[0].tls.server_name" "$DOMAIN" # 是否存在acme域名, 存在则修改 - local acme_exists=$(jq -r 'has("inbounds") and (.inbounds[0] | has("tls")) and (.inbounds[0].tls | has("acme"))' "$config_file") - if [[ "$acme_exists" == "true" ]]; then - modify_json_file "$config_file" ".inbounds[0].tls.acme.domain[0]" "$domain" + local ACME_EXISTS=$(jq -r 'has("inbounds") and (.inbounds[0] | has("tls")) and (.inbounds[0].tls | has("acme"))' "$CONFIG_FILE") + if [[ "$ACME_EXISTS" == "true" ]]; then + modify_json_file "$CONFIG_FILE" ".inbounds[0].tls.acme.domain[0]" "$DOMAIN" fi echo "修改域名成功" diff --git a/bin/password.sh b/bin/password.sh index edb87be..7329b04 100644 --- a/bin/password.sh +++ b/bin/password.sh @@ -2,15 +2,15 @@ # 更新密码的函数 update_password() { - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 - local config_file="$script_dir/../config/config.json" + local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 + local CONFIG_FILE="$SCRIPT_DIR/../config/config.json" # 生成一个长度为16的随机密码 - local new_password=$(gen_password 16) + local NEW_PASSWORD=$(gen_password 16) # 修改密码 - sed -i 's/你的密码/'"$new_password"'/g' $config_file + sed -i 's/你的密码/'"$NEW_PASSWORD"'/g' $CONFIG_FILE echo "设置密码成功" } diff --git a/bin/port.sh b/bin/port.sh index a7bf9b0..9404481 100644 --- a/bin/port.sh +++ b/bin/port.sh @@ -8,27 +8,27 @@ # $2: 结束端口(默认 65535) # $3: 最大随机尝试次数(默认 100) find_free_port() { - local start="${1:-10001}" - local max="${2:-65535}" - local attempts="${3:-100}" + local START="${1:-10001}" + local MAX="${2:-65535}" + local ATTEMPTS="${3:-100}" # ------------------------------------------------------------ # 收集当前正在监听的端口(TCP + UDP) # 优先使用 ss,其次 netstat # ------------------------------------------------------------ - local used_ports raw + local USED_PORTS RAW if command -v ss >/dev/null 2>&1; then # ss 输出示例: # LISTEN 0 128 0.0.0.0:22 - raw=$(ss -lntu 2>/dev/null || true) - used_ports=$(printf "%s\n" "$raw" \ + RAW=$(ss -lntu 2>/dev/null || true) + USED_PORTS=$(printf "%s\n" "$RAW" \ | awk '{print $5}' \ | sed -E 's/.*[:]//g') elif command -v netstat >/dev/null 2>&1; then # netstat 输出示例: # tcp 0 0 0.0.0.0:22 - raw=$(netstat -lntu 2>/dev/null || true) - used_ports=$(printf "%s\n" "$raw" \ + RAW=$(netstat -lntu 2>/dev/null || true) + USED_PORTS=$(printf "%s\n" "$RAW" \ | awk '{print $4}' \ | sed -E 's/.*[:]//g') else @@ -40,12 +40,12 @@ find_free_port() { # 将已占用端口存入关联数组,便于 O(1) 判断 # 需要 bash 4+ # ------------------------------------------------------------ - declare -A used_map - local p - for p in $used_ports; do + declare -A USED_MAP + local P + for P in $USED_PORTS; do # 过滤非数字字段(如 *、:::) - if [[ $p =~ ^[0-9]+$ ]]; then - used_map["$p"]=1 + if [[ $P =~ ^[0-9]+$ ]]; then + USED_MAP["$P"]=1 fi done @@ -53,14 +53,14 @@ find_free_port() { # 随机尝试若干次 # 每次随机生成一个端口,只要未被监听就立即返回 # ------------------------------------------------------------ - local port i - for ((i=0; i&2 + echo "Error: no free port found after $ATTEMPTS random attempts." >&2 return 1 } @@ -172,34 +172,34 @@ port_manage() { # update_port 8080 # ========================================== update_port(){ - local port=$1 + local PORT=$1 # 如果没有提供端口参数,则自动查找一个随机空闲端口 - if [[ -z "$port" ]]; then - port=$(find_free_port 5000 15000) + if [[ -z "$PORT" ]]; then + PORT=$(find_free_port 5000 15000) fi - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 - local config_dir="$script_dir/../config" - modify_json_file "$config_dir/config.json" ".inbounds[0].listen_port" "$port" - port_manage allow "$port" + local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 + local CONFIG_DIR="$SCRIPT_DIR/../config" + modify_json_file "$CONFIG_DIR/config.json" ".inbounds[0].listen_port" "$PORT" + port_manage allow "$PORT" echo "设置端口成功" } # 通过交互方式更新端口 ask_update_port(){ - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - local config_file="$script_dir/../config/config.json" + local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + local CONFIG_FILE="$SCRIPT_DIR/../config/config.json" - local current_port=$(get_listen_port) - local new_port=$(ask_update "请输入新的端口号" "$current_port") - update_port "$new_port" + local CURRENT_PORT=$(get_listen_port) + local NEW_PORT=$(ask_update "请输入新的端口号" "$CURRENT_PORT") + update_port "$NEW_PORT" } # 获取当前配置的监听端口 get_listen_port(){ - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - local config_file="$script_dir/../config/config.json" + local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + local CONFIG_FILE="$SCRIPT_DIR/../config/config.json" - local port=$(jq -r ".inbounds[0].listen_port" "$config_file") - echo $port + local PORT=$(jq -r ".inbounds[0].listen_port" "$CONFIG_FILE") + echo $PORT } diff --git a/bin/print_share_link.sh b/bin/print_share_link.sh index 3c494f3..46b29ec 100644 --- a/bin/print_share_link.sh +++ b/bin/print_share_link.sh @@ -2,53 +2,53 @@ print_share_link() { - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 - local config_dir=$(readlink -f "$script_dir/../config") + local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 + local CONFIG_DIR=$(readlink -f "$SCRIPT_DIR/../config") # 检查jq是否安装 check_jq - config_file="$config_dir/config.json" + CONFIG_FILE="$CONFIG_DIR/config.json" # 检查配置是否正确 - local uuid=$(jq -r '.inbounds[0].users[0].uuid' "$config_file") - if [ "$uuid" = "你的UUID" ] || [ -z "$uuid" ] || [[ "$uuid" == null ]]; then + local UUID=$(jq -r '.inbounds[0].users[0].uuid' "$CONFIG_FILE") + if [ "$UUID" = "你的UUID" ] || [ -z "$UUID" ] || [[ "$UUID" == null ]]; then red "error: 配置有误, 请重新生成配置" exit 1 fi # 读取配置文件内容 - local config=$(cat "$config_file") + local CONFIG=$(cat "$CONFIG_FILE") # 提取所需信息 - uuid=$(echo "$config" | jq -r '.inbounds[0].users[0].uuid') - local sni=$(echo "$config" | jq -r '.inbounds[0].tls.server_name') - local ipv4=$(curl -4 -sSL --connect-timeout 3 --retry 2 ip.sb || echo "null") - local port=$(echo "$config" | jq -r '.inbounds[0].listen_port') - local password=$(echo "$config" | jq -r '.inbounds[0].users[0].password') - local congestion_control=$(echo "$config" | jq -r '.inbounds[0].congestion_control') - local allowInsecure=1 # 是否跳过证书验证,1表示跳过,0表示不跳过 - local insecure=1 # 是否允许不安全连接,1表示允许,0表示不允许 + UUID=$(echo "$CONFIG" | jq -r '.inbounds[0].users[0].uuid') + local SNI=$(echo "$CONFIG" | jq -r '.inbounds[0].tls.server_name') + local IPV4=$(curl -4 -sSL --connect-timeout 3 --retry 2 ip.sb || echo "null") + local PORT=$(echo "$CONFIG" | jq -r '.inbounds[0].listen_port') + local PASSWORD=$(echo "$CONFIG" | jq -r '.inbounds[0].users[0].password') + local CONGESTION_CONTROL=$(echo "$CONFIG" | jq -r '.inbounds[0].congestion_control') + local ALLOW_INSECURE=1 # 是否跳过证书验证,1表示跳过,0表示不跳过 + local INSECURE=1 # 是否允许不安全连接,1表示允许,0表示不允许 # 检查是否使用ACME申请证书 - if jq -e '.inbounds[0].tls.acme' "$config_dir/config.json" > /dev/null 2>&1; then - allowInsecure=0 # 不跳过证书验证 - insecure=0 + if jq -e '.inbounds[0].tls.acme' "$CONFIG_DIR/config.json" > /dev/null 2>&1; then + ALLOW_INSECURE=0 # 不跳过证书验证 + INSECURE=0 fi # 构建分享链接 - local share_link="tuic://$uuid:$password@$ipv4:$port?sni=$sni&alpn=h3&insecure=$insecure&allowInsecure=$allowInsecure&congestion_control=$congestion_control#Tuic节点" + local SHARE_LINK="tuic://$UUID:$PASSWORD@$IPV4:$PORT?sni=$SNI&alpn=h3&insecure=$INSECURE&allowInsecure=$ALLOW_INSECURE&congestion_control=$CONGESTION_CONTROL#Tuic节点" # 输出分享链接 echo -e "\033[32m" - echo "IPV4: $ipv4" - echo "port: $port" - echo "uuid: $uuid" - echo "password: $password" - echo "sni: $sni" - echo "congestion_control(拥塞控制算法): $congestion_control" + echo "IPV4: $IPV4" + echo "port: $PORT" + echo "uuid: $UUID" + echo "password: $PASSWORD" + echo "sni: $SNI" + echo "congestion_control(拥塞控制算法): $CONGESTION_CONTROL" echo "" - echo "分享链接: $share_link" + echo "分享链接: $SHARE_LINK" echo -e "\033[0m" } diff --git a/bin/remote/update_docker_images.sh b/bin/remote/update_docker_images.sh index 2276429..89ef02e 100644 --- a/bin/remote/update_docker_images.sh +++ b/bin/remote/update_docker_images.sh @@ -2,26 +2,26 @@ update_docker_images(){ - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../" # 脚本文件绝对路径 - local compose_file="$script_dir/../docker-compose.yml" # docker-compose.yml文件路径 + local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../" # 脚本文件绝对路径 + local COMPOSE_FILE="$SCRIPT_DIR/../docker-compose.yml" # docker-compose.yml文件路径 # 检查是否存在 docker-compose.yml 文件 - if [ ! -f $compose_file ]; then + if [ ! -f $COMPOSE_FILE ]; then echo "Error: docker-compose.yml 文件不存在." exit 1 fi echo "正在关闭容器.." - docker compose -f $compose_file down + docker compose -f $COMPOSE_FILE down echo "正在更新镜像.." - docker compose -f $compose_file pull + docker compose -f $COMPOSE_FILE pull echo "正在删除未使用的镜像..." docker image prune -f echo "正在启动容器.." - docker compose -f $compose_file up -d + docker compose -f $COMPOSE_FILE up -d } diff --git a/bin/run.sh b/bin/run.sh index 415695b..6d1a23b 100644 --- a/bin/run.sh +++ b/bin/run.sh @@ -1,15 +1,15 @@ #!/bin/bash run() { - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 - local compose_file="$script_dir/../docker-compose.yml" + local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 + local COMPOSE_FILE="$SCRIPT_DIR/../docker-compose.yml" # 如果容器已经启动, 则先停止容器 - if docker compose -f "$compose_file" ps | grep -q "Up"; then - docker compose -f "$compose_file" down + if docker compose -f "$COMPOSE_FILE" ps | grep -q "Up"; then + docker compose -f "$COMPOSE_FILE" down fi # 启动docker容器 - docker compose -f "$compose_file" up -d + docker compose -f "$COMPOSE_FILE" up -d } diff --git a/bin/update_docker_images.sh b/bin/update_docker_images.sh index 2ace306..4db8de1 100644 --- a/bin/update_docker_images.sh +++ b/bin/update_docker_images.sh @@ -2,25 +2,25 @@ update_docker_images(){ - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 - local compose_file="$script_dir/../docker-compose.yml" # docker-compose.yml文件路径 + local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径 + local COMPOSE_FILE="$SCRIPT_DIR/../docker-compose.yml" # docker-compose.yml文件路径 # 检查是否存在 docker-compose.yml 文件 - if [ ! -f $compose_file ]; then + if [ ! -f $COMPOSE_FILE ]; then echo "Error: docker-compose.yml 文件不存在." exit 1 fi echo "正在关闭容器.." - docker compose -f $compose_file down + docker compose -f $COMPOSE_FILE down echo "正在更新镜像.." - docker compose -f $compose_file pull + docker compose -f $COMPOSE_FILE pull echo "正在删除未使用的镜像..." docker image prune -f echo "正在启动容器.." - docker compose -f $compose_file up -d + docker compose -f $COMPOSE_FILE up -d }