Skip to content

Commit d30411f

Browse files
authored
improve(tun): clarify docker capability requirements
improve(tun): clarify docker capability requirements
2 parents 9f30995 + 24eeddc commit d30411f

1 file changed

Lines changed: 106 additions & 27 deletions

File tree

scripts/core/clashctl.sh

Lines changed: 106 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
15661626
print_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

Comments
 (0)