@@ -1563,6 +1563,66 @@ print_config_kernel_feedback() {
15631563 ui_blank
15641564}
15651565
1566+ tun_container_runtime_hint_lines () {
1567+ local env_type os_variant cap_check printed=" false"
1568+
1569+ env_type=" $( container_env_type 2> /dev/null || echo unknown) "
1570+ os_variant=" $( install_env_os_variant 2> /dev/null || true) "
1571+ cap_check=" $( has_cap_net_admin; echo $? ) "
1572+
1573+ if [ " $env_type " = " docker" ]; then
1574+ if ! tun_device_exists 2> /dev/null || [ " $cap_check " != " 0" ]; then
1575+ echo " 👉 当前问题来自容器启动参数;仅在容器内执行 sudo 或切换到 root,无法补齐缺失的 device / capability"
1576+ printed=" true"
1577+ fi
1578+ fi
1579+
1580+ if ! tun_device_exists 2> /dev/null; then
1581+ if [ " $env_type " = " docker" ]; then
1582+ echo " 👉 请重新创建 Docker 容器并挂载 Tun 设备:--device /dev/net/tun"
1583+ else
1584+ echo " 👉 请在容器启动时映射 Tun 设备;Docker 示例:--device /dev/net/tun"
1585+ fi
1586+ printed=" true"
1587+ fi
1588+
1589+ case " $cap_check " in
1590+ 0)
1591+ ;;
1592+ 2)
1593+ if [ " $env_type " = " docker" ]; then
1594+ echo " 👉 当前容器内缺少 capsh,无法确认 CAP_NET_ADMIN;请重点检查启动参数是否包含:--cap-add NET_ADMIN"
1595+ else
1596+ echo " 👉 无法确认 CAP_NET_ADMIN(缺少 capsh);请检查容器启动参数是否授予了该 capability"
1597+ fi
1598+ printed=" true"
1599+ ;;
1600+ * )
1601+ if [ " $env_type " = " docker" ]; then
1602+ echo " 👉 请重新创建 Docker 容器并增加能力:--cap-add NET_ADMIN"
1603+ else
1604+ echo " 👉 请在容器启动时授予网络管理能力;Docker 示例:--cap-add NET_ADMIN"
1605+ fi
1606+ printed=" true"
1607+ ;;
1608+ esac
1609+
1610+ if ! has_ip_command 2> /dev/null; then
1611+ case " $os_variant " in
1612+ openwrt)
1613+ echo " 👉 当前环境缺少 ip 命令;OpenWrt 可安装:opkg update && opkg install ip-full"
1614+ ;;
1615+ * )
1616+ echo " 👉 当前环境缺少 ip 命令;Debian/Ubuntu 可安装:apt update && apt install -y iproute2"
1617+ echo " 👉 其他发行版请安装提供 ip 命令的 iproute / iproute2 软件包"
1618+ ;;
1619+ esac
1620+ printed=" true"
1621+ fi
1622+
1623+ [ " $printed " = " true" ]
1624+ }
1625+
15661626print_tun_container_gate_feedback () {
15671627 local mode=" $1 "
15681628 local reason=" ${2:- } "
@@ -1587,7 +1647,8 @@ print_tun_container_gate_feedback() {
15871647 ui_kv " 💻" " 环境模式" " 容器环境"
15881648 ui_kv " ❗" " 容器裁决" " 高风险,已阻断开启"
15891649 [ -n " ${reason:- } " ] && ui_kv " ❗" " 阻断原因" " $reason "
1590- ui_next " clashctl tun doctor"
1650+ tun_container_runtime_hint_lines | sed ' s/^/ /' || true
1651+ ui_next " 查看完整诊断:clashctl tun doctor"
15911652 ui_blank
15921653 ;;
15931654 * )
@@ -5454,31 +5515,51 @@ tun_doctor_action_lines() {
54545515
54555516 case " $reason " in
54565517 missing-cap-net-admin)
5457- case " $backend " in
5458- systemd)
5459- echo " 👉 当前运行后端为 systemd;若关键证据显示 unit 未声明能力,可尝试为服务显式补 CAP_NET_ADMIN / CAP_NET_RAW:"
5460- echo " sudo systemctl edit $unit "
5461- ;;
5462- systemd-user)
5463- echo " 👉 当前运行后端为 systemd-user;请结合容器与 unit 证据判断,必要时改用系统服务或显式补 CAP_NET_ADMIN / CAP_NET_RAW"
5464- ;;
5465- script)
5466- echo " 👉 当前运行后端为 script;请确认启动 mihomo 的实际进程具备 CAP_NET_ADMIN / CAP_NET_RAW:"
5467- echo " sudo clashctl tun on"
5468- ;;
5469- * )
5470- echo " 👉 请结合运行后端、容器环境和进程能力证据,确认 mihomo 实际拥有 CAP_NET_ADMIN / CAP_NET_RAW"
5471- ;;
5472- esac
5518+ if [ " $( container_env_type 2> /dev/null || echo unknown) " != " host" ]; then
5519+ tun_container_runtime_hint_lines || true
5520+ else
5521+ case " $backend " in
5522+ systemd)
5523+ echo " 👉 当前运行后端为 systemd;若关键证据显示 unit 未声明能力,可尝试为服务显式补 CAP_NET_ADMIN / CAP_NET_RAW:"
5524+ echo " sudo systemctl edit $unit "
5525+ ;;
5526+ systemd-user)
5527+ echo " 👉 当前运行后端为 systemd-user;请结合容器与 unit 证据判断,必要时改用系统服务或显式补 CAP_NET_ADMIN / CAP_NET_RAW"
5528+ ;;
5529+ script)
5530+ echo " 👉 当前运行后端为 script;请确认启动 mihomo 的实际进程具备 CAP_NET_ADMIN / CAP_NET_RAW"
5531+ echo " 👉 若当前就是主机脚本模式,可尝试提升权限后重新执行:sudo clashctl tun on"
5532+ ;;
5533+ * )
5534+ echo " 👉 请结合运行后端、容器环境和进程能力证据,确认 mihomo 实际拥有 CAP_NET_ADMIN / CAP_NET_RAW"
5535+ ;;
5536+ esac
5537+ fi
54735538 ;;
54745539 missing-tun-device)
5475- echo " 👉 请先挂载或启用 /dev/net/tun"
5540+ if [ " $( container_env_type 2> /dev/null || echo unknown) " != " host" ]; then
5541+ tun_container_runtime_hint_lines || true
5542+ else
5543+ echo " 👉 请先挂载或启用 /dev/net/tun"
5544+ fi
54765545 ;;
54775546 tun-device-not-readable)
54785547 echo " 👉 请修复 /dev/net/tun 权限,确保当前运行用户可读写"
54795548 ;;
54805549 missing-ip-command)
5481- echo " 👉 请先安装 iproute2,确保 ip 命令可用"
5550+ if [ " $( container_env_type 2> /dev/null || echo unknown) " != " host" ]; then
5551+ tun_container_runtime_hint_lines || true
5552+ else
5553+ case " $( install_env_os_variant 2> /dev/null || true) " in
5554+ openwrt)
5555+ echo " 👉 当前环境缺少 ip 命令;OpenWrt 可安装:opkg update && opkg install ip-full"
5556+ ;;
5557+ * )
5558+ echo " 👉 Debian/Ubuntu 可安装:apt update && apt install -y iproute2"
5559+ echo " 👉 其他发行版请安装提供 ip 命令的 iproute / iproute2 软件包"
5560+ ;;
5561+ esac
5562+ fi
54825563 ;;
54835564 runtime-not-running)
54845565 echo " 👉 请先启动代理:clashon"
@@ -5592,11 +5673,9 @@ tun_recommendation_lines() {
55925673 if [ " $can_enable " != " true" ]; then
55935674 case " $container_mode " in
55945675 container-risky)
5595- echo " 1. 当前容器环境已被裁决为高风险:${risk_reason:- 容器条件不足} "
5596- echo " 2. 检查宿主机是否映射 /dev/net/tun"
5597- echo " 3. 检查是否授予 CAP_NET_ADMIN / --cap-add=NET_ADMIN"
5598- echo " 4. 检查容器内是否具备 ip 命令"
5599- echo " 5. 条件满足后再执行:clashctl tun on"
5676+ echo " 👉 当前容器环境已被裁决为高风险:${risk_reason:- 容器条件不足} "
5677+ tun_container_runtime_hint_lines || true
5678+ echo " 👉 条件满足后再执行:clashctl tun on"
56005679 ;;
56015680 * )
56025681 echo " 1. 当前环境不满足 Tun 基础条件"
@@ -5622,9 +5701,9 @@ tun_recommendation_lines() {
56225701 return 0
56235702 ;;
56245703 container-risky)
5625- echo " 1. 当前容器环境属于高风险,不建议直接开启 Tun"
5626- echo " 2. 先修复: ${risk_reason :- 容器条件不足} "
5627- echo " 3. 修复后再执行:clashctl tun on"
5704+ echo " 👉 当前容器环境属于高风险,不建议直接开启 Tun: ${risk_reason :- 容器条件不足} "
5705+ tun_container_runtime_hint_lines || true
5706+ echo " 👉 修复后再执行:clashctl tun on"
56285707 return 0
56295708 ;;
56305709 esac
0 commit comments