diff --git a/install.sh b/install.sh index 9c500c7..a83bdcf 100755 --- a/install.sh +++ b/install.sh @@ -20,12 +20,15 @@ _is_regular_sudo && chown -R "$SUDO_USER" "$CLASH_BASE_DIR" _install_service _apply_rc -clashsecret "$(_get_random_val)" >/dev/null + +_merge_config +_detect_proxy_port clashui +clashsecret "$(_get_random_val)" >/dev/null clashsecret _okcat '🎉' 'enjoy 🎉' clashctl -_valid_config "$RESOURCES_CONFIG_BASE" && CLASH_CONFIG_URL="file://$CLASH_CONFIG_BASE" +_valid_config "$CLASH_CONFIG_BASE" && CLASH_CONFIG_URL="file://$CLASH_CONFIG_BASE" _quit "clashsub add $CLASH_CONFIG_URL && clashsub use 1" diff --git a/resources/mixin.yaml b/resources/mixin.yaml index b2e5e29..54d1b42 100644 --- a/resources/mixin.yaml +++ b/resources/mixin.yaml @@ -46,6 +46,7 @@ tun: strict-route: true route-exclude-address: - 1.1.1.1/32 # 用于 clashui 获取真实内网 IP + - 127.0.0.1/32 exclude-interface: - docker0 # 避免无法访问容器内服务 - podman0 # 详见:https://github.com/nelvko/clash-for-linux-install/issues/100#issuecomment-2995667368 diff --git a/scripts/cmd/clashctl.sh b/scripts/cmd/clashctl.sh index 9f1652a..de2171b 100644 --- a/scripts/cmd/clashctl.sh +++ b/scripts/cmd/clashctl.sh @@ -42,40 +42,34 @@ _detect_proxy_port() { local mixed_port=$("$BIN_YQ" '.mixed-port // ""' "$CLASH_CONFIG_RUNTIME") local http_port=$("$BIN_YQ" '.port // ""' "$CLASH_CONFIG_RUNTIME") local socks_port=$("$BIN_YQ" '.socks-port // ""' "$CLASH_CONFIG_RUNTIME") - local newPort count=0 [ -z "$mixed_port" ] && [ -z "$http_port" ] && [ -z "$socks_port" ] && mixed_port=7890 - [ -n "$mixed_port" ] && _is_port_used "$mixed_port" && { - ((count += 1)) - newPort=$(_get_random_port) - _failcat '🎯' "端口冲突:[mixed-port] ${mixed_port} 🎲 随机分配 $newPort" - mixed_port=$newPort - "$BIN_YQ" -i ".mixed-port = $newPort" "$CLASH_CONFIG_MIXIN" - } - [ -n "$http_port" ] && _is_port_used "$http_port" && { - ((count += 1)) - newPort=$(_get_random_port) - _failcat '🎯' "端口冲突:[port] ${http_port} 🎲 随机分配 $newPort" - http_port=$newPort - "$BIN_YQ" -i ".port = $newPort" "$CLASH_CONFIG_MIXIN" - } - [ -n "$socks_port" ] && _is_port_used "$socks_port" && { - ((count += 1)) - newPort=$(_get_random_port) - _failcat '🎯' "端口冲突:[port] ${socks_port} 🎲 随机分配 $newPort [socks-port]" - socks_port=$newPort - "$BIN_YQ" -i ".socks-port = $newPort" "$CLASH_CONFIG_MIXIN" - } + + local newPort count=0 + local port_list=( + "mixed_port|mixed-port" + "http_port|port" + "socks_port|socks-port" + ) + clashstatus >&/dev/null && local isActive='true' + for entry in "${port_list[@]}"; do + local var_name="${entry%|*}" + local yaml_key="${entry#*|}" + [ -n "${!var_name}" ] && _is_port_used "${!var_name}" && [ "$isActive" != "true" ] && { + newPort=$(_get_random_port) + ((count++)) + _failcat '🎯' "端口冲突:[$yaml_key] ${!var_name} 🎲 随机分配 $newPort" + "$BIN_YQ" -i ".${yaml_key} = $newPort" "$CLASH_CONFIG_MIXIN" + } + done ((count)) && _merge_config } function clashon() { + _detect_proxy_port + clashstatus >&/dev/null || placeholder_start clashstatus >&/dev/null || { - _detect_proxy_port - placeholder_start - clashstatus >/dev/null || { - _failcat '启动失败: 执行 clashlog 查看日志' - return 1 - } + _failcat '启动失败: 执行 clashlog 查看日志' + return 1 } clashproxy >/dev/null && _set_system_proxy _okcat '已开启代理环境' @@ -91,9 +85,13 @@ watch_proxy() { } function clashoff() { - clashstatus >/dev/null && { - placeholder_stop >/dev/null || { - _failcat '关闭失败: 可执行 clashlog 查看日志' + clashstatus >&/dev/null && { + placeholder_stop >/dev/null + clashstatus >&/dev/null && _tunstatus >&/dev/null && { + _tunoff || _error_quit "请先关闭 Tun 模式" + } + clashstatus >&/dev/null && { + _failcat '代理环境关闭失败' return 1 } } @@ -154,7 +152,7 @@ $(env | grep -i 'proxy=')" function clashstatus() { placeholder_status "$@" - placeholder_is_active + placeholder_is_active >&/dev/null } function clashlog() { @@ -259,7 +257,9 @@ _merge_config_restart() { placeholder_start >/dev/null sleep 0.1 } - +_get_secret() { + "$BIN_YQ" '.secret // ""' "$CLASH_CONFIG_RUNTIME" +} function clashsecret() { case "$1" in -h | --help) @@ -278,7 +278,7 @@ EOF case $# in 0) - _okcat "当前密钥:$("$BIN_YQ" '.secret // ""' "$CLASH_CONFIG_RUNTIME")" + _okcat "当前密钥:$(_get_secret)" ;; 1) "$BIN_YQ" -i ".secret = \"$1\"" "$CLASH_CONFIG_MIXIN" || { @@ -307,23 +307,29 @@ _tunstatus() { } _tunoff() { _tunstatus >/dev/null || return 0 - "$BIN_YQ" -i '.tun.enable = false' "$CLASH_CONFIG_MIXIN" - _merge_config sudo placeholder_stop - clashon >/dev/null - _okcat "Tun 模式已关闭" + clashstatus >&/dev/null || { + "$BIN_YQ" -i '.tun.enable = false' "$CLASH_CONFIG_MIXIN" + _merge_config + clashon >/dev/null + _okcat "Tun 模式已关闭" + return 0 + } + _tunstatus >&/dev/null && _failcat "Tun 模式关闭失败" } _sudo_restart() { sudo placeholder_stop - sleep 0.3 placeholder_sudo_start - sleep 0.3 + sleep 0.5 } _tunon() { _tunstatus 2>/dev/null && return 0 + sudo placeholder_stop "$BIN_YQ" -i '.tun.enable = true' "$CLASH_CONFIG_MIXIN" _merge_config - _sudo_restart + placeholder_sudo_start + sleep 0.5 + clashstatus >&/dev/null || _error_quit "Tun 模式开启失败" local fail_msg="Start TUN listening error|unsupported kernel version" local ok_msg="Tun adapter listening at|TUN listening iface" clashlog | grep -E -m1 -qs "$fail_msg" && { @@ -441,7 +447,6 @@ EOF _detect_ext_addr clashstatus >&/dev/null || clashon >/dev/null - local secret=$("$BIN_YQ" '.secret // ""' "$CLASH_CONFIG_RUNTIME") _okcat '⏳' "请求内核升级..." [ "$log_flag" = true ] && { log_cmd=(placeholder_follow_log) @@ -453,7 +458,7 @@ EOF --silent \ --noproxy "*" \ --location \ - -H "Authorization: Bearer $secret" \ + -H "Authorization: Bearer $(_get_secret)" \ "http://${EXT_IP}:${EXT_PORT}/upgrade?channel=$channel" ) [ "$log_flag" = true ] && pkill -9 -f "${log_cmd[*]}" diff --git a/scripts/cmd/common.sh b/scripts/cmd/common.sh index c72a92d..3af16c7 100755 --- a/scripts/cmd/common.sh +++ b/scripts/cmd/common.sh @@ -61,8 +61,8 @@ function _detect_ext_addr() { EXT_IP=$ext_ip EXT_PORT=${ext_addr##*:} [ "$ext_ip" = '0.0.0.0' ] && EXT_IP=$(_get_local_ip) - _is_port_used "$EXT_PORT" && clashstatus >&/dev/null && clashoff >&/dev/null _is_port_used "$EXT_PORT" && { + curl -s --noproxy "*" -H "Authorization: Bearer $(_get_secret)" "127.0.0.1:${EXT_PORT}" | grep -qs "${KERNEL_NAME}" && return 0 local newPort=$(_get_random_port) _failcat '🎯' "端口冲突:[external-controller] ${EXT_PORT} 🎲 随机分配 $newPort" EXT_PORT=$newPort diff --git a/scripts/preflight.sh b/scripts/preflight.sh index d6a34b2..5a9ebf2 100644 --- a/scripts/preflight.sh +++ b/scripts/preflight.sh @@ -1,8 +1,6 @@ #!/usr/bin/env bash RESOURCES_BASE_DIR=".${CLASH_RESOURCES_DIR#"$CLASH_BASE_DIR"}" -RESOURCES_CONFIG_BASE=".${CLASH_CONFIG_BASE#"$CLASH_BASE_DIR"}" -RESOURCES_CONFIG_MIXIN=".${CLASH_CONFIG_MIXIN#"$CLASH_BASE_DIR"}" ZIP_BASE_DIR=".${CLASH_RESOURCES_DIR#"$CLASH_BASE_DIR"}/zip" @@ -228,6 +226,7 @@ _openrc() { service_stop=(rc-service "$KERNEL_NAME" stop) service_restart=(rc-service "$KERNEL_NAME" restart) service_status=(rc-service "$KERNEL_NAME" status) + service_is_active=(rc-service "$KERNEL_NAME" status) } _runit() { service_src="${SCRIPT_INIT_DIR}/runit.sh" @@ -267,6 +266,7 @@ _sysvinit() { service_stop=(service "$KERNEL_NAME" stop) service_restart=(service "$KERNEL_NAME" restart) service_status=(service "$KERNEL_NAME" status) + service_is_active=(service "$KERNEL_NAME" status) } # shellcheck disable=SC2206 _systemd() { @@ -282,14 +282,16 @@ _systemd() { service_stop=($_SUDO systemctl stop "$KERNEL_NAME") service_restart=($_SUDO systemctl restart "$KERNEL_NAME") service_status=($_SUDO systemctl status "$KERNEL_NAME") + service_is_active=($_SUDO systemctl is-active "$KERNEL_NAME") } _nohup() { service_enable=(false) service_disable=(false) service_start=('(' nohup "$BIN_KERNEL" -d "$CLASH_RESOURCES_DIR" -f "$CLASH_CONFIG_RUNTIME" '>\&' "$FILE_LOG" '\&' ')') - service_sudo_start=('(' sudo nohup "$BIN_KERNEL" -d "$CLASH_RESOURCES_DIR" -f "$CLASH_CONFIG_RUNTIME" '>\&' "$FILE_LOG" '\&' ')') + service_sudo_start=(sudo nohup "$BIN_KERNEL" -d "$CLASH_RESOURCES_DIR" -f "$CLASH_CONFIG_RUNTIME" '>\&' "$FILE_LOG" '\&') service_status=(pgrep -fa "$BIN_KERNEL") + service_is_active=(pgrep -fa "$BIN_KERNEL") service_stop=(pkill -9 -f "$BIN_KERNEL") } @@ -313,7 +315,7 @@ _install_service() { -e "s#placeholder_kernel_desc#$kernel_desc#g" \ "$service_target" } - + [ "$INIT_TYPE" != "nohup" ] && service_sudo_start=("${service_start[@]}") sed -i \ -e "s#placeholder_start#${service_start[*]}#g" \ -e "s#placeholder_sudo_start#${service_sudo_start[*]}#g" \ diff --git a/uninstall.sh b/uninstall.sh index aede408..4c36e3e 100755 --- a/uninstall.sh +++ b/uninstall.sh @@ -3,7 +3,7 @@ . "$CLASH_BASE_DIR/scripts/cmd/clashctl.sh" 2>/dev/null . scripts/preflight.sh -pgrep -f "$BIN_KERNEL" -u 0 >/dev/null && ! _is_root && _error_quit '请使用 sudo 执行卸载' +pgrep -f "$BIN_KERNEL" -u 0 >/dev/null && ! _is_root && _error_quit "请先关闭 Tun 模式" clashoff 2>/dev/null _uninstall_service _revoke_rc