From a8982d6d3db2faf6a3b451d4cb8190454a4bddbb Mon Sep 17 00:00:00 2001 From: wnlen <62139570+wnlen@users.noreply.github.com> Date: Tue, 13 Jan 2026 23:46:40 +0800 Subject: [PATCH] Add systemd installer and non-root support --- README.md | 40 ++++++++++++-- scripts/clash_profile_conversion.sh | 6 ++- scripts/install_systemd.sh | 52 ++++++++++++++++++ scripts/resolve_subconverter.sh | 82 +++++++++++++++++++++++++++++ shutdown.sh | 14 ++++- start.sh | 37 +++++++++---- systemd/clash-for-linux.service | 4 +- update.sh | 4 +- 8 files changed, 222 insertions(+), 17 deletions(-) create mode 100755 scripts/install_systemd.sh create mode 100755 scripts/resolve_subconverter.sh diff --git a/README.md b/README.md index 0ee67ce..df87fd2 100644 --- a/README.md +++ b/README.md @@ -159,11 +159,10 @@ $ proxy_off ## systemd 服务 -将仓库中的 `systemd/clash-for-linux.service` 复制到 `/etc/systemd/system/`,并根据实际路径修改 `WorkingDirectory` 与脚本路径: +推荐使用自动安装脚本生成 systemd 单元(自动识别安装路径、创建低权限用户并修正目录权限): ```bash -$ sudo cp systemd/clash-for-linux.service /etc/systemd/system/ -$ sudo vim /etc/systemd/system/clash-for-linux.service +$ sudo bash scripts/install_systemd.sh ``` 启用并启动服务: @@ -179,6 +178,41 @@ $ sudo systemctl enable --now clash-for-linux.service $ sudo systemctl stop clash-for-linux.service ``` +> 如需自定义运行用户,可在执行脚本前设置 `CLASH_SERVICE_USER`(可选 `CLASH_SERVICE_GROUP`)。 +> 默认使用 `clash` 用户运行服务,systemd 环境文件输出到 `temp/clash-for-linux.sh`。 + +如果需要手动安装,可参考 `systemd/clash-for-linux.service` 模板并替换安装路径。 + + +
+ +## subconverter 多架构支持 + +`subconverter` 用于将订阅内容转换为标准 clash 配置。默认会尝试以下位置: + +- `tools/subconverter/subconverter` +- `tools/subconverter/subconverter-` +- `tools/subconverter/bin/subconverter-` + +其中 `` 取值为: + +- `linux-amd64` +- `linux-arm64` +- `linux-armv7` + +你也可以设置: + +- `SUBCONVERTER_PATH`:指定自定义 `subconverter` 可执行文件路径。 +- `SUBCONVERTER_AUTO_DOWNLOAD=true`:启用自动下载(需 `curl`/`wget`)。 +- `SUBCONVERTER_DOWNLOAD_URL_TEMPLATE`:下载模板,使用 `{arch}` 占位符,如: + +```bash +export SUBCONVERTER_AUTO_DOWNLOAD=true +export SUBCONVERTER_DOWNLOAD_URL_TEMPLATE='https://example.com/subconverter_{arch}.tar.gz' +``` + +当 `subconverter` 不可用时会自动跳过转换,并提示警告。 +
diff --git a/scripts/clash_profile_conversion.sh b/scripts/clash_profile_conversion.sh index 6cd1716..ce8dbb4 100644 --- a/scripts/clash_profile_conversion.sh +++ b/scripts/clash_profile_conversion.sh @@ -21,7 +21,11 @@ else echo "$decoded_content" > ${Server_Dir}/temp/clash_config.yaml else echo "解码后的内容不符合clash标准,尝试将其转换为标准格式" - ${Server_Dir}/tools/subconverter/subconverter -g &>> ${Server_Dir}/logs/subconverter.log + if [ -z "$SUBCONVERTER_BIN" ]; then + echo "subconverter 未配置,无法执行转换" + exit 1 + fi + "${SUBCONVERTER_BIN}" -g &>> ${Server_Dir}/logs/subconverter.log converted_file=${Server_Dir}/temp/clash_config.yaml # 判断转换后的内容是否符合clash配置文件标准 if awk '/^proxies:/{p=1} /^proxy-groups:/{g=1} /^rules:/{r=1} p&&g&&r{exit} END{if(p&&g&&r) exit 0; else exit 1}' $converted_file; then diff --git a/scripts/install_systemd.sh b/scripts/install_systemd.sh new file mode 100755 index 0000000..7e21b4a --- /dev/null +++ b/scripts/install_systemd.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +set -euo pipefail + +Server_Dir=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +Service_Name="clash-for-linux" +Service_User="${CLASH_SERVICE_USER:-clash}" +Service_Group="${CLASH_SERVICE_GROUP:-$Service_User}" +Unit_Path="/etc/systemd/system/${Service_Name}.service" + +if [ "$(id -u)" -ne 0 ]; then + echo -e "\033[31m[ERROR] 需要 root 权限来安装 systemd 单元\033[0m" + exit 1 +fi + +if ! getent group "$Service_Group" >/dev/null 2>&1; then + groupadd --system "$Service_Group" +fi + +if ! id "$Service_User" >/dev/null 2>&1; then + useradd --system --no-create-home --shell /usr/sbin/nologin --gid "$Service_Group" "$Service_User" +fi + +install -d -m 0755 "$Server_Dir/conf" "$Server_Dir/logs" "$Server_Dir/temp" +chown -R "$Service_User:$Service_Group" "$Server_Dir/conf" "$Server_Dir/logs" "$Server_Dir/temp" + +cat >"$Unit_Path"</dev/null 2>&1; then + curl -L -sS -o "${Download_Archive}" "${Download_Url}" + elif command -v wget >/dev/null 2>&1; then + wget -q -O "${Download_Archive}" "${Download_Url}" + else + echo -e "\033[33m[WARN] 未找到 curl 或 wget,无法自动下载 subconverter\033[0m" + return 0 + fi + + if [ -f "${Download_Archive}" ]; then + tar -xzf "${Download_Archive}" -C "${Extract_Dir}" 2>/dev/null + Downloaded_Bin=$(find "${Extract_Dir}" -maxdepth 3 -type f -name "subconverter" -print -quit) + if [ -n "${Downloaded_Bin}" ]; then + mv "${Downloaded_Bin}" "${Subconverter_Dir}/subconverter-${Resolved_Arch}" + chmod +x "${Subconverter_Dir}/subconverter-${Resolved_Arch}" + try_subconverter_bin "${Subconverter_Dir}/subconverter-${Resolved_Arch}" && return 0 + fi + fi +fi diff --git a/shutdown.sh b/shutdown.sh index 535cf18..8230d5e 100644 --- a/shutdown.sh +++ b/shutdown.sh @@ -36,6 +36,18 @@ else fi # 清除环境变量 -> /etc/profile.d/clash-for-linux.sh +Env_File="${CLASH_ENV_FILE:-}" +if [ "$Env_File" != "off" ] && [ "$Env_File" != "disabled" ]; then + if [ -z "$Env_File" ]; then + if [ -w /etc/profile.d ]; then + Env_File="/etc/profile.d/clash-for-linux.sh" + else + Env_File="$Temp_Dir/clash-for-linux.sh" + fi + fi + if [ -f "$Env_File" ]; then + > "$Env_File" + fi +fi echo -e "\n服务关闭成功,请执行以下命令关闭系统代理:proxy_off\n" diff --git a/start.sh b/start.sh index 4d84485..6ac309d 100644 --- a/start.sh +++ b/start.sh @@ -12,9 +12,11 @@ export Server_Dir=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd) source $Server_Dir/.env # 给二进制启动程序、脚本等添加可执行权限 -chmod +x $Server_Dir/bin/* -chmod +x $Server_Dir/scripts/* -chmod +x $Server_Dir/tools/subconverter/subconverter +chmod +x $Server_Dir/bin/* 2>/dev/null +chmod +x $Server_Dir/scripts/* 2>/dev/null +if [ -f "$Server_Dir/tools/subconverter/subconverter" ]; then + chmod +x $Server_Dir/tools/subconverter/subconverter 2>/dev/null +fi @@ -175,8 +177,10 @@ if_success $Text3 $Text4 $ReturnStatus ## 判断订阅内容是否符合clash配置文件标准,尝试转换(需 subconverter 可执行文件支持) -if [ -x "$Server_Dir/tools/subconverter/subconverter" ]; then +source $Server_Dir/scripts/resolve_subconverter.sh +if [ "$Subconverter_Ready" = "true" ]; then echo -e '\n判断订阅内容是否符合clash配置文件标准:' + export SUBCONVERTER_BIN="$Subconverter_Bin" bash $Server_Dir/scripts/clash_profile_conversion.sh sleep 3 else @@ -262,11 +266,23 @@ else fi echo '' -# 添加环境变量(root权限) - 使用配置的端口 -if [ -f /etc/profile.d/clash.sh ]; then - echo -e "\033[33m[WARN] 检测到旧版环境变量文件 /etc/profile.d/clash.sh,建议确认是否需要清理\033[0m" -fi -cat>/etc/profile.d/clash-for-linux.sh<"$Env_File"<