Skip to content

feat: add ALLOW-LAN; command: clashctl lan status/on/off#252

Merged
wnlen merged 1 commit into
wnlen:masterfrom
yangtaowillv:feature/add-LAN
May 7, 2026
Merged

feat: add ALLOW-LAN; command: clashctl lan status/on/off#252
wnlen merged 1 commit into
wnlen:masterfrom
yangtaowillv:feature/add-LAN

Conversation

@yangtaowillv
Copy link
Copy Markdown
Contributor

PR: Improve LAN Proxy Support / 改进局域网代理支持

Background / 背景

This project already had a basic allow-lan: true default in the bundled Clash/Mihomo template, but LAN access could still fail or be unclear in real usage.

项目原本已经在内置 Clash/Mihomo 模板中提供了基础的 allow-lan: true 默认值,但在实际使用中,局域网访问仍可能失败,且用户不容易判断当前是否真的生效。

The original behavior had three main problems:

原行为主要有三个问题:

  1. The runtime config respected subscription-provided allow-lan.

    运行时配置会保留订阅中提供的 allow-lan

    Some subscription YAML files include allow-lan: false. During runtime config normalization, the project only filled allow-lan when it was missing:

    部分订阅 YAML 会包含 allow-lan: false。此前运行时配置规范化时,只会在字段缺失时补默认值:

    allow-lan: existing value or true

    That meant a subscription could silently disable LAN access even though the project default expected it to be enabled.

    因此,即使项目默认希望开启局域网访问,订阅也可能静默地把它关闭。

  2. The checked-in default template exposed mixed proxy LAN access, but the controller template still used localhost.

    仓库中的默认模板开启了 mixed proxy 的局域网访问,但控制器模板仍绑定在本机回环地址。

    config/template.yaml had allow-lan: true, but external-controller was bound to 127.0.0.1:9090. This made local Web UI access work, while LAN Web UI access depended on runtime regeneration or other paths.

    config/template.yaml 中有 allow-lan: true,但 external-controller 绑定为 127.0.0.1:9090。这会导致本机 Web UI 可用,但局域网 Web UI 是否可访问取决于运行时重新生成配置等其他路径。

  3. There was no explicit LAN management command.

    缺少显式的局域网代理管理命令。

    Users had to inspect generated YAML or infer behavior from status output. There was no simple command to confirm, enable, or disable LAN proxy access.

用户需要手动检查生成后的 YAML,或者从 status 输出中推断行为;没有一个简单命令用于确认、开启或关闭局域网代理。

Changes / 改动

1. Make LAN access a project-level runtime setting / 将局域网访问变为项目级运行时设置

Added project-level helpers in scripts/core/config.sh:

scripts/core/config.sh 中新增项目级辅助函数:

  • config_allow_lan
  • set_config_allow_lan

Runtime config normalization now writes allow-lan from the project template setting instead of preserving the subscription value. This prevents upstream subscriptions from unexpectedly turning LAN access off.

运行时配置规范化现在会使用项目模板中的设置写入 allow-lan,不再保留订阅里的同名值。这样可以避免上游订阅意外关闭局域网访问。

Before / 修改前:

allow-lan: subscription value if present, otherwise true

After / 修改后:

allow-lan: project template setting

Default / 默认值:

allow-lan: true

2. Bind the controller to all interfaces by default / 默认将控制器绑定到所有网卡

Updated config/template.yaml:

更新 config/template.yaml

external-controller: 0.0.0.0:9090

This matches the runtime-generated template and allows LAN clients to reach the Web UI when the port is permitted by the host firewall.

这与运行时生成模板保持一致;当宿主机防火墙放行端口时,局域网设备可以访问 Web UI。

3. Add runtime status support for allow-lan / 增加运行时 allow-lan 状态读取能力

Added runtime_config_allow_lan in scripts/core/common.sh so command output can read the effective runtime value from runtime/config.yaml.

scripts/core/common.sh 中新增 runtime_config_allow_lan,使命令输出可以从 runtime/config.yaml 中读取实际生效的运行时值。

4. Add clashctl lan / 新增 clashctl lan

Added a dedicated LAN management command:

新增专门的局域网代理管理命令:

clashctl lan status
clashctl lan on
clashctl lan off

Behavior / 行为:

  • status: shows whether LAN proxy is enabled and prints the LAN proxy URL when available.
  • status 显示局域网代理是否开启,并在可用时输出局域网代理地址。
  • on: writes allow-lan: true, regenerates runtime config, and applies the change.
  • on 写入 allow-lan: true,重新生成运行时配置,并应用变更。
  • off: writes allow-lan: false, regenerates runtime config, and applies the change.
  • off 写入 allow-lan: false,重新生成运行时配置,并应用变更。

5. Improve clashctl status / 改进 clashctl status

clashctl status and clashctl status --verbose now show LAN proxy information alongside the local proxy:

clashctl statusclashctl status --verbose 现在会在本地代理旁展示局域网代理信息:

本地代理:http://127.0.0.1:7890
局域网代理:http://<lan-ip>:7890

If LAN access is disabled, status reports:

如果局域网访问已关闭,状态输出为:

局域网代理:已关闭

6. Add shell completion / 增加 Shell 补全

Updated completion support for:

补充以下命令的补全支持:

clashctl lan on
clashctl lan off
clashctl lan status

User Impact / 用户影响

After this change, users have a clear and predictable way to expose the proxy to LAN devices or Docker containers.

此改动后,用户可以用更清晰、可预期的方式将代理暴露给局域网设备或 Docker 容器。

Typical Docker usage / 典型 Docker 用法:

clashctl lan on
clashctl lan status

Inside a Docker container using the default bridge network, the host is usually reachable at:

在使用默认 bridge 网络的 Docker 容器中,宿主机通常可通过以下地址访问:

172.17.0.1

So the proxy variables can be set as:

因此容器内可以设置以下代理变量:

export http_proxy=http://172.17.0.1:7890
export https_proxy=http://172.17.0.1:7890
export all_proxy=socks5://172.17.0.1:7890

Note: host firewalls such as UFW may still need to allow Docker bridge traffic to the proxy port:

如果宿主机启用了 UFW 等防火墙,仍可能需要放行 Docker bridge 到代理端口的访问:

sudo ufw allow in on docker0 to any port 7890 proto tcp

Verification / 验证

Commands used for verification:

验证时使用的命令:

bash -n scripts/core/config.sh
bash -n scripts/core/common.sh
bash -n scripts/core/clashctl.sh
bash -n scripts/core/completion.sh
bash scripts/core/clashctl.sh lan status
bash scripts/core/clashctl.sh status

Expected runtime config / 预期运行时配置:

allow-lan: true
mixed-port: 7890
external-controller: 0.0.0.0:9090

Expected listening ports / 预期监听端口:

*:7890
*:9090

Expected host-side proxy check / 预期宿主机侧代理检查:

curl -I --max-time 8 -x http://127.0.0.1:7890 https://www.google.com
curl -I --max-time 8 -x http://172.17.0.1:7890 https://www.google.com

Notes / 备注

  • This change does not bypass host firewall rules. If the process listens on *:7890 but Docker or LAN clients time out, the most likely cause is firewall policy.
  • 此改动不会绕过宿主机防火墙规则。如果进程已经监听 *:7890,但 Docker 或局域网客户端访问超时,最常见原因是防火墙策略。
  • This project uses mixed-port: 7890, so both HTTP and SOCKS proxy traffic can use port 7890 unless a separate socks-port is configured.
  • 本项目使用 mixed-port: 7890,因此除非额外配置了独立的 socks-port,HTTP 与 SOCKS 代理都可以走 7890
  • Subscriptions can still define their own proxy groups, rules, DNS settings, etc., but they no longer silently override the project-level LAN enablement policy.
  • 订阅仍然可以定义自己的代理组、规则、DNS 等配置,但不能再静默覆盖项目级的局域网开关策略。

@wnlen wnlen merged commit 95c1380 into wnlen:master May 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants