diff --git a/resource/mixin.yaml b/resource/config-mixin.yaml similarity index 78% rename from resource/mixin.yaml rename to resource/config-mixin.yaml index cfc2d70..ea5e14f 100644 --- a/resource/mixin.yaml +++ b/resource/config-mixin.yaml @@ -1,3 +1,4 @@ +# tun-config-start tun: enable: true stack: system # or gvisor @@ -8,4 +9,5 @@ tun: # - tcp://any:53 auto-route: true # manage $(ip route) and $(ip rules) auto-redir: true # manage nftable REDIRECT - auto-detect-interface: true # 与 $(interface-name) 冲突 + auto-detect-interface: true +# tun-config-end diff --git a/script/clashctl.sh b/script/clashctl.sh index 891c1e0..3172dcf 100644 --- a/script/clashctl.sh +++ b/script/clashctl.sh @@ -1,10 +1,12 @@ #!/bin/bash +# shellcheck disable=SC2015 # shellcheck disable=SC2155 # clash快捷指令 function clashon() { - sudo systemctl start clash && echo '😼 已开启代理环境' || - echo '😾 启动失败: 执行 "systemctl status clash" 查看日志' || return 1 - local proxy_addr=http://127.0.0.1:7890 + sudo systemctl start clash && echo '😼 已开启代理环境' \ + || echo '😾 启动失败: 执行 "systemctl status clash" 查看日志' || return 1 + _get_port + local proxy_addr=http://127.0.0.1:${MIXED_PORT} export http_proxy=$proxy_addr export https_proxy=$proxy_addr export HTTP_PROXY=$proxy_addr @@ -12,32 +14,37 @@ function clashon() { } function clashoff() { - sudo systemctl stop clash && echo '😼 已关闭代理环境' || - echo '😾 关闭失败: 执行 "systemctl status clash" 查看日志' || return 1 + sudo systemctl stop clash && echo '😼 已关闭代理环境' \ + || echo '😾 关闭失败: 执行 "systemctl status clash" 查看日志' || return 1 unset http_proxy unset https_proxy unset HTTP_PROXY unset HTTPS_PROXY } +clashrestart() { + { clashoff && clashon; } >&/dev/null +} + function clashui() { # 防止tun模式强制走代理 clashoff >&/dev/null # 查询公网ip # ifconfig.me # cip.cc + _get_port local public_ip=$(curl -s --noproxy "*" ifconfig.me) - local public_address="http://${public_ip}:9090/ui" + local public_address="http://${public_ip}:${EXT_PORT}/ui" # 内网ip # ip route get 1.1.1.1 | grep -oP 'src \K\S+' local local_ip=$(hostname -I | awk '{print $1}') - local local_address="http://${local_ip}:9090/ui" + local local_address="http://${local_ip}:${EXT_PORT}/ui" printf "\n" printf "╔═══════════════════════════════════════════════╗\n" printf "║ 😼 Web 面板地址 ║\n" printf "║═══════════════════════════════════════════════║\n" printf "║ ║\n" - printf "║ 🔓 请注意放行 9090 端口 ║\n" + printf "║ 🔓 请注意放行 %s 端口 ║\n" "$EXT_PORT" printf "║ 🏠 内网:%-30s ║\n" "$local_address" printf "║ 🌍 公网:%-30s ║\n" "$public_address" printf "║ ☁️ 公共:https://clash.razord.top ║\n" @@ -57,7 +64,7 @@ function clashsecret() { [ -z "$secret" ] && secret=\'\' sudo sed -iE s/"secret\s.*"/"secret $secret"/ /etc/systemd/system/clash.service sudo systemctl daemon-reload - { clashoff && clashon; } >/dev/null 2>&1 + clashrestart _okcat "密钥更新成功,已重启生效" ;; *) @@ -70,16 +77,15 @@ _valid_yq() { yq -V >&/dev/null && return 0 read -r -p '依赖 yq 命令,是否安装?[y/N]: ' flag [ "$flag" = "y" ] && { - sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq && - sudo chmod +x /usr/bin/yq + sudo wget "${GH_PROXY}"/https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq && sudo chmod +x /usr/bin/yq _okcat 'yq 安装成功' } || _failcat '取消安装' - } -_concat_config() { - _valid_yq - yq -n "load(\"$CLASH_CONFIG_MIXIN\") * load(\"$CLASH_CONFIG_RAW\")" >"$CLASH_CONFIG_RUNTIME" +_concat_config_restart() { + _valid_config "$CLASH_CONFIG_MIXIN" || _error_quit "Mixin 配置验证失败,请检查" + _valid_yq || return 1 + yq -n "load(\"$CLASH_CONFIG_RAW\") * load(\"$CLASH_CONFIG_MIXIN\")" > "$CLASH_CONFIG_RUNTIME" && clashrestart } _tunstatus() { @@ -88,18 +94,15 @@ _tunstatus() { } _tunoff() { - _tunstatus >/dev/null || return 0 + _tunstatus > /dev/null || return 0 yq -i '.tun.enable = false' "$CLASH_CONFIG_MIXIN" - _concat_config - { clashoff && clashon; } >&/dev/null - _okcat "Tun 模式已关闭" + _concat_config_restart && _okcat "Tun 模式已关闭" } _tunon() { - _tunstatus 2>/dev/null && return 0 + _tunstatus 2> /dev/null && return 0 yq -i '.tun.enable = true' "$CLASH_CONFIG_MIXIN" - _concat_config - { clashoff && clashon; } >&/dev/null + _concat_config_restart systemctl status clash | grep -qs 'unsupported kernel version' && { _tunoff >&/dev/null _error_quit '当前系统内核版本不支持' @@ -108,7 +111,7 @@ _tunon() { } function clashtun() { - _valid_yq + _valid_yq || return 1 case "$1" in on) _tunon @@ -126,35 +129,33 @@ function clashupdate() { local url=$(cat "$CLASH_CONFIG_URL") local is_auto=false case "$1" in - --auto) + auto) is_auto=true + url=$2 ;; log) tail "${CLASH_UPDATE_LOG}" return $? ;; *) - url=$2 + url=$1 ;; esac [ "${url:0:4}" != 'http' ] && _error_quit '请正确填写订阅链接' [ "$is_auto" = true ] && { - grep -qs 'clashupdate' "$CLASH_CRON_TAB" || - echo "0 0 */2 * * . $BASHRC;clashupdate $url" >>"$CLASH_CRON_TAB" && - echo 666 + grep -qs 'clashupdate' "$CLASH_CRON_TAB" || echo "0 0 */2 * * . $BASHRC;clashupdate $url" >> "$CLASH_CRON_TAB" _okcat "定时任务设置成功" && return 0 } _download_config "$url" "$CLASH_CONFIG_RAW" # shellcheck disable=SC2015 _valid_config "$CLASH_CONFIG_RAW" && { - _concat_config - { clashoff && clashon; } >/dev/null 2>&1 - _okcat '配置更新成功,已重启生效' - echo "$url" >"$CLASH_CONFIG_URL" - echo "$(date +"%Y-%m-%d %H:%M:%S") 配置更新成功 ✅ $url" >>"${CLASH_UPDATE_LOG}" + _mark_raw + _concat_config_restart && _okcat '配置更新成功,已重启生效' + echo "$url" > "$CLASH_CONFIG_URL" + echo "$(date +"%Y-%m-%d %H:%M:%S") 配置更新成功 ✅ $url" >> "${CLASH_UPDATE_LOG}" } || { - echo "$(date +"%Y-%m-%d %H:%M:%S") 配置更新失败 ❌ $url" >>"${CLASH_UPDATE_LOG}" + echo "$(date +"%Y-%m-%d %H:%M:%S") 配置更新失败 ❌ $url" >> "${CLASH_UPDATE_LOG}" _error_quit '配置无效:请检查配置内容' } } @@ -162,12 +163,15 @@ function clashupdate() { function clashmixin() { case "$1" in -e) - sudo vi "$CLASH_CONFIG_MIXIN" + sudo vi "$CLASH_CONFIG_MIXIN" && { + _concat_config_restart && _okcat "配置更新成功,已重启生效" + } + ;; + -r) + less "$CLASH_CONFIG_RUNTIME" ;; *) less "$CLASH_CONFIG_MIXIN" - _valid_config - clashon clashoff ;; esac } @@ -179,7 +183,8 @@ Usage: clashoff 关闭代理: clashui 面板地址: clashtun [on|off] Tun模式: - clashupdate [auto|log] 更新订阅: clashsecret [secret] 查看/设置密钥: + clashmixin [-e|-r] Mixin配置: + clashupdate [auto|log] 更新订阅: EOF } diff --git a/script/common.sh b/script/common.sh index 25e0f36..5a08ca6 100644 --- a/script/common.sh +++ b/script/common.sh @@ -1,5 +1,8 @@ #!/bin/bash # shellcheck disable=SC2034 +# shellcheck disable=SC2155 +GH_PROXY='https://ghgo.xyz' + TEMP_CONFIG='./resource/config.yaml' TEMP_CLASH_RAR='./resource/clash-linux-amd64-v3-2023.08.17.gz' TEMP_UI_RAR='./resource/yacd.tar.xz' @@ -7,10 +10,20 @@ TEMP_UI_RAR='./resource/yacd.tar.xz' CLASH_BASE_DIR='/opt/clash' CLASH_CONFIG_URL="${CLASH_BASE_DIR}/url" CLASH_CONFIG_RAW="${CLASH_BASE_DIR}/config.yaml" -CLASH_CONFIG_MIXIN="${CLASH_BASE_DIR}/mixin.yaml" +CLASH_CONFIG_MIXIN="${CLASH_BASE_DIR}/config-mixin.yaml" CLASH_CONFIG_RUNTIME="${CLASH_BASE_DIR}/config-runtime.yaml" CLASH_UPDATE_LOG="${CLASH_BASE_DIR}/clashupdate.log" +function _get_value() { + sed -En "s/$1:\s(.*)/\1/p" $CLASH_CONFIG_RUNTIME +} +function _get_port() { + local ext_ctl=$(_get_value 'external-controller') + EXT_PORT=${ext_ctl##*:} + EXT_PORT=${EXT_PORT//\'/} + MIXED_PORT=$(_get_value 'mixed-port') +} + function _get_os() { local os_info os_info=$(cat /etc/os-release) @@ -25,6 +38,10 @@ function _get_os() { } _get_os +function _mark_raw() { + sed -i -e '1i\# raw-config-start' -e '$a\# raw-config-end\n' "${CLASH_CONFIG_RAW}" +} + function _okcat() { echo "😼 $1" && return 0 } @@ -50,22 +67,22 @@ function _valid_env() { # 配置文件和clash在同一目录 function _valid_config() { - [ -e "$1" ] && [ "$(wc -l <"$1")" -gt 1 ] && - "$(dirname "$1")/clash" -d "$(dirname "$1")" -f "$(basename "$1")" -t + [ -e "$1" ] && [ "$(wc -l < "$1")" -gt 1 ] \ + && "$(dirname "$1")/clash" -d "$(dirname "$1")" -f "$1" -t } function _download_config() { local url=$1 local output=$2 local agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0' - wget --timeout=3 \ + wget --timeout=5 \ --tries=1 \ --no-check-certificate \ --user-agent="$agent" \ -O "$output" \ - "$url" || - curl --connect-timeout 3 \ - --retry 1 \ + "$url" \ + || curl --connect-timeout 5 \ + --retry 2 \ --user-agent "$agent" \ -k -o "$output" \ "$url"