mcpField
W
windows-host-browser

windows-host-browser

github.com/iliyasoneAgent 工作流068 次安装6 天前更新
代码仓库

关于 windows-host-browser

windows-host-browser 是操作 Iliyas 的 Windows PC 上持久运行的 Chrome 的技能,供需要访问该浏览器会话的 Agent 使用。它通过 CDP 和隧道连接,并规定标签页、代理设置及账户操作的谨慎边界。

主要功能

  1. 01通过 connect.sh 建立 CDP 连接
  2. 02检查并复用现有标签页
  3. 03使用 CDP 执行脚本和监视网络
  4. 04按 Chrome 配置文件管理代理
  5. 05规定可见操作与账户变更的审批要求

适用场景

  1. 01访问仅在已登录浏览器中可用的页面
  2. 02排查无头浏览器无法处理的挑战
  3. 03检查页面脚本执行与网络请求
  4. 04为指定配置文件设置并恢复代理

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/iliyasone/skills --skill windows-host-browser

安装后在 Claude Code 中输入/windows-host-browser确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

cdp.py
connect.sh
mk-shortcut.ps1

详细介绍

Windows 主机浏览器

目标是 Iliyas 的 Windows PC 上长期运行的 Chrome,通过 --remote-debugging-port=<PORT> --user-data-dir="C:\chrome-debug" 启动。它不是 无头沙盒,而是 Iliyas 也在使用的真实浏览器,运行着他的登录会话(Vercel、Google Cloud 等),并显示在他的实体屏幕上。

以下两点决定了后续所有做法:

  • 能力 — 无需询问凭据,就能访问他登录后才能访问的内容;还可以像他看到的那样调试页面:查看已打开的标签页、在其中运行 JS、监控网络流量、通过指定代理路由。
  • 克制 — 他看得到你打开的每个窗口,也会看到你更改的每项设置。打开可见内容时要告诉他;除非他希望保留,否则关闭你打开的标签页;用完后撤销对整个浏览器生效的更改(例如代理设置)。如果通过已认证的 CLI 或无头浏览器也能获取数据,优先使用这些方式。

无需询问即可使用的情况

Iliyas 宁愿你使用此浏览器,也不愿你停下来等他。在成本更低的方式失败时,可自行使用:

  • 无头浏览器被 Cloudflare 验证或验证码拦截;
  • 页面需要他的某个登录账号,且没有 CLI 或令牌可用;
  • 某些操作只会在他的浏览器或会话中发生,无头浏览器无法复现。

未经询问时,将页面作为后台标签页打开,以免影响他的当前标签页:在浏览器 WebSocket 上调用带有 background: true 的 Target.createTarget(GET /json/version → webSocketDebuggerUrl;连接时不要发送 Origin 标头,如 cdp.py 所做),而不是 PUT /json/new。只有需要他操作时(例如处理验证码),才通过 Target.activateTarget 将页面切到前台。如果 Chrome 没有打开任何窗口,仍会出现一个新窗口;要告知他。标签页会在默认配置文件中打开:如果所需登录账号位于其他配置文件中,请询问他。你可以在自己打开的标签页中,以正常速度读取和浏览任务所需的少量页面(你接管他一个空白标签页也算你自己的;参见“重用现有窗口”,你可以在其中浏览并关闭该标签页)。在聊天中说明你打开了哪个页面,以及原因。Cloudflare 验证通常会在此浏览器中自动通过;可以勾选 Turnstile 复选框;遇到其他验证码时,请他在打开的标签页中完成验证。

凡是会更改他任何账号的状态或产生费用的操作,都要事先询问:提交表单、发帖、购买、更改账号设置、点击确认、接受、授权或登出链接、OAuth 同意,以及通过页面 JS 发送任何非 GET 请求。复制浏览器中的 Cookie 或令牌,以及将页面显示的凭据(API 密钥、令牌、密码、环境变量值)粘贴到任何地方(包括聊天)之前,也要先询问。其他私人内容可以发到与他的聊天中,但不要放进 issue、PR 或与其他人的聊天。通过他的浏览器循环执行、轮询或批量获取数据,必须先取得他的同意:这些操作会使用他的家庭 IP 和账号。更改任何配置文件的代理设置之前也要先询问。即使他要求你使用浏览器,这些规则仍然适用,除非他的请求明确指定了该操作。

如果你是在未经询问的情况下操作,而 connect.sh 失败,请停止并告知他。下面的修复操作(结束 Chrome、重写 chromedebug 任务、运行 net stop winnat)会关闭他的窗口和其他 Agent 的标签页;必须先取得他的同意。

其他 Agent 可能同时在使用浏览器:请在自己的标签页中操作,绝不要关闭或浏览不属于你的标签页(见下方空白标签页规则)。

第 0 步 — 连接:运行 connect.sh,使用固定端点

在 dev-remote 上,端点是固定的:http://127.0.0.1:18800,无论 Chrome 在 Windows 端使用哪个端口。运行一条命令即可完成所有设置:

~/.agents/skills/windows-host-browser/connect.sh
# on success prints:  CDP_HTTP=http://127.0.0.1:18800
export CDP_HTTP="http://127.0.0.1:18800"

该脚本具有幂等性,所有服务都已运行时,执行开销很小。如果服务未运行,脚本会从 chromedebug 计划任务中重新发现当前的 Windows 端口(这是事实来源——端口会变化,参见“端口问题”;绝不要将其写死),如果 Chrome 进程已停止,则通过计划任务重新启动 Chrome(无窗口——参见“启动”),并将两条 SSH 跳转都重新连接起来(dev-remote → wsl → windows),使用本地端口 18800。

dev-remote 上的 systemd 计时器每 2 分钟重新运行一次脚本,因此端点通常已在运行:使用 systemctl status cdp-tunnel.timer 查看状态,使用 journalctl -u cdp-tunnel.service 查看日志。

如果 connect.sh 输出 FAIL,其消息会指出发生故障的层级;以下各节介绍手动排查流程。截至 2026-09-01,Windows 端口为 9555(9222、9223、9250、9333 和 9444 均先后被 WinNAT 阻止)。

手动流程(connect.sh 自动执行的步骤)

调试端口仅在 Windows 主机自身的环回地址上。家用机器(WSL 机器 iliyasone)和 dev-remote 都在 Iliyas 的 Tailscale tailnet 上,这是两者之间稳定的连接路径。要访问该端口,需要经过两跳隧道——WSL 机器无法直接访问 Windows 环回地址,因此也必须连接到主机。先查找端口:

PORT=$(ssh wsl 'ssh windows "schtasks /query /tn chromedebug /xml"' \
        | grep -aoE 'remote-debugging-port=[0-9]+' | grep -oE '[0-9]+')
  • 在 WSL 机器 iliyasone 上:将主机端口转发到 WSL 的环回地址:

    pgrep -f "ssh .*-L $PORT:127.0.0.1:$PORT windows" >/dev/null \
      || ssh -f -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 \
             -L "$PORT:127.0.0.1:$PORT" windows
    

    (也可以使用 ssh windows "curl 127.0.0.1:$PORT/json/version",无需建立隧道,适用于临时检查。)

  • 在 dev-remote 上:通过 tailnet(100.93.231.101)使用 ssh wsl 连接到 WSL shell。在上面 WSL→主机的转发基础上,再建立第二条转发:

    pgrep -f "ssh -N .*-L $PORT:127.0.0.1:$PORT wsl" >/dev/null \
      || setsid ssh -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 \
               -L "$PORT:127.0.0.1:$PORT" wsl >/dev/null 2>&1 < /dev/null &
    

然后运行检查:

curl -s --max-time 4 "http://127.0.0.1:$PORT/json/version" || echo NO_CDP

如果返回 Chrome 版本 → 前往第 1 步。若返回 NO_CDP → 按排查成本从低到高检查原因:隧道未运行(重新执行上述转发);即使 Chrome 正在运行,端口也可能已被 WinNAT 占用(参见“端口问题”);家用 PC / WSL 机器处于离线状态(运行 tailscale status——如果 iliyasone 离线,说明机器已关闭,无法从这里修复);或者调试用 Chrome 未运行(参见“启动”)。不要捏造路径。

第 1 步 — 连接

有一点需要注意:这一规则适用于所有 WebSocket 连接,而不仅仅是辅助工具:Chrome 启动时未设置 --remote-allow-origins,因此打开 CDP WebSocket 时不要发送 Origin 标头,否则连接会被拒绝。

此后即可通过 $CDP_HTTP 直接使用 CDP:

  • GET /json/list — 获取标签页及其 WebSocket URL;使用任意 CDP 客户端连接,即可执行 JS、截取屏幕截图或监视网络事件(Network.enable + Network.requestWillBeSent / responseReceived)。
  • PUT /json/new?url=… — 打开一个页面(该页面会作为可见标签页显示在 Iliyas 的屏幕上——执行前请说明)。
  • GET /json/version → webSocketDebuggerUrl — 获取浏览器 WebSocket,用于调用 Target.* 等方法,例如 createTarget。
复用现有窗口——不要不断新建窗口

每个窗口和标签页都显示在 Iliyas 的屏幕上,他要求 Agent 不要再不断新建窗口。打开任何内容之前,先执行 GET /json/list 并按以下顺序复用现有内容:

  1. 存在你自己打开的空白标签页,或 Iliyas 留下的空白标签页 (about:blank 或 chrome://newtab/):将其导航到目标页面(连接到它的 websocket,执行 Page.navigate),而不是新建 target。新打开的空白标签页 可能属于另一个即将导航的 Agent;如果无法确定,就视为不属于你,然后遵循规则 2。
  2. 打开的标签页是你自己的,或明显处于空闲状态(不是 Iliyas 正在 积极使用的内容):在同一个窗口中将你的页面作为标签页打开—— PUT /json/new 会执行此操作,它会以现有窗口为目标。
  3. 仅在你有意需要时才新建窗口——例如,现有窗口里满是 Iliyas 正在处理的无关任务,或者你需要隔离(不同的窗口尺寸、需要他单独观察的流程)。 说明原因。

清理时也一样:对你打开的标签页执行 /json/close/<id>;绝不要关闭 你未打开的标签页。

代理控制——cdp.py(按配置文件区分)

除非 Iliyas 已要求更改代理,否则在任何配置文件上执行 set 或 direct 前都要先征求他的同意。将你自己获准设置的代理恢复为 direct 不需要再次征求同意;如果发现代理已设置,则由他决定如何处理。

Chrome 安装了 Proxy Switcher 扩展程序 (iejkjpdckomcjdhmkemlfdapjodcpgih),代理设置由它管理。代理按 Chrome 配置文件区分,而不是按窗口区分:浏览器可以同时运行多个配置文件(使用不同的窗口、Cookie 和扩展程序副本),每个配置文件都可以使用不同的代理。cdp.py(与此文件位于同一目录)负责驱动该扩展程序。它默认使用固定端点 http://127.0.0.1:18800(先运行 connect.sh);只有在其他位置运行时,$CDP_HTTP 才会覆盖此设置。

python3 cdp.py profiles             # list running profiles by their open tabs
python3 cdp.py get -p 2             # proxy setting of profile 2 from that list
python3 cdp.py set 82.38.65.142 41196 http proxyuser 'PASSWORD' -p proton
python3 cdp.py egress -p proton     # prove the exit IP/country through it
python3 cdp.py direct -p proton     # revert that profile to direct

--profile / -p 接受 profiles 中的索引,或该配置文件中打开的标签页 URL/标题的子串。只有一个配置文件在运行时可以省略;有多个配置文件时则必须指定——该工具不会猜测,因为在错误的配置文件上设置代理会改变 Iliyas 浏览网页时使用的代理。

该工具隐藏了两个容易踩坑的地方:此扩展程序使用 MV3,因此其按配置文件区分的服务工作线程会休眠并从 target 列表中消失——而且,无法通过 Target.createTarget 唤醒某个特定配置文件中的休眠工作线程(CDP 会拒绝真实配置文件的 browserContextIds)。cdp.py 会通过该配置文件自己的页面执行 window.open 打开一个临时标签页,将其导航到扩展程序弹出窗口,然后关闭它,以此唤醒工作线程。

set 会为该配置文件调用 chrome.proxy.settings.set(与扩展程序弹出窗口执行的操作完全相同);如果提供了用户名,还会将 auth-username / auth-password 写入扩展程序的存储,并重新启用其 onAuthRequired 处理程序,以免经过身份验证的代理弹出对话框。

在 Iliyas 自己用于浏览网页的配置文件上操作完成后,始终执行 direct——遗留在该配置文件中的代理会改变他自己的浏览体验。专用代理配置文件可以保留其代理。

将扩展程序添加到新配置文件需要手动操作:在该配置文件的窗口中打开 https://chromewebstore.google.com/detail/iejkjpdckomcjdhmkemlfdapjodcpgih 并让 Iliyas 点击 “Add to Chrome”——安装确认是无法通过 CDP 访问的原生 UI。

代理来源

reverse-api 项目使用一张 proxy 表(Postgres,Heroku 应用 pinc000):包含 scheme, server, port, username, password, country_code 列。 这是使用用户名和密码进行身份验证的 HTTP 代理,通过 country_code(ISO-3166 alpha-2)选择。请查询该表,而不要将凭据硬编码:

# on dev-remote, heroku CLI is authed to app pinc000
heroku pg:psql -a pinc000 -c \
  "select scheme,server,port,username,password,country_code from proxy where country_code='nl';"

代理不会轮换——每个账号使用的代理是固定的——因此浏览器使用时,选择目标国家的任意一行即可。

启动调试版 Chrome

如果步骤 0 显示 NO_CDP,但 ssh wsl 可以正常使用,请通过计划任务启动 Chrome——切勿通过普通 SSH 启动,因为这样会让 Chrome 进入不可见的会话 0,并在尚未绑定端口时退出:

# from the WSL box:
ssh windows 'schtasks /run /tn chromedebug'
# from dev-remote (hop through WSL):
ssh wsl 'ssh windows "schtasks /run /tn chromedebug"'
# then poll: curl -s "$CDP_HTTP/json/version"

该任务使用 --no-startup-window 启动 Chrome,因此启动过程不可见:Chrome 会在后台运行,CDP 已启动,但不会显示窗口,直到有东西打开一个页面(此时 PUT /json/new 会在他的屏幕上打开一个窗口——记得告诉他)。这样可以避免每次登录后 2 分钟计时器触发时,Chrome 都跳到 Iliyas 面前;重写任务操作时务必保留此标志。“Agent Chrome”快捷方式会在启动任务后自行打开窗口。该任务以 LogonType=InteractiveToken 运行(“常规”选项卡:“仅当用户登录时运行”),因此会在他的可见会话中启动,且不会存储密码。

如果重新启动成功,但几分钟后 Chrome 又退出了,不要反复重启——请参阅“退出问题”。

Iliyas 可以自行打开——桌面快捷方式

Windows 桌面上的 “Agent Chrome” 可手动打开此浏览器,例如登录某项服务,以便 Agent 随后使用该会话。它会运行 C:\chrome-debug\open-debug-chrome.ps1:如果调试版 Chrome 已在运行,就在其中打开一个新窗口;否则启动 chromedebug 任务,等待调试端口响应,然后打开窗口(如果任务实例仍在运行,普通的 schtasks /run 会被静默忽略,因为该任务使用 MultipleInstances IgnoreNew——因此脚本会先检查)。所以,他需要登录某处时,请让他使用该快捷方式,而不要替他打开标签页。

如果快捷方式或启动脚本缺失,请在主机上通过 -EncodedCommand 传输方式运行 mk-shortcut.ps1(与此文件位于同一目录)以重新创建二者。该脚本会在 C:\chrome-debug 中创建 .lnk 文件,然后将其移到桌面——由于桌面文件夹的名称是西里尔字母(Рабочий стол),WScript.Shell 无法直接将文件保存到该文件夹。

端口问题——WinNAT 可能会占用调试端口

**症状:**调试版 Chrome 正在运行且浏览正常,但 $CDP_HTTP/json/version 连接失败,也没有 DevTools 服务端。 使用 --enable-logging --v=1 启动后,C:\chrome-debug\chrome_debug.log 会显示 bind() ... Only one usage of each socket address ... (0x2740),随后显示 Cannot start http server for devtools。

**原因:**Hyper-V/WSL2 WinNAT/HNS 会预留一些 TCP 端口范围;WSL 或主机重启后,某个范围可能包含调试端口。即使 netstat 显示该端口无人占用,且该端口也不在 netsh int ipv4 show excludedportrange 的结果中,它仍会变得无法绑定。“昨天还能用,今天就坏了”=预留范围移到了该端口上。自定义 user-data-dir、策略和会话 0 都是干扰因素——请根据上述日志行确认。

恢复方法(无需管理员权限,也无需重启服务):

  1. 找一个空闲端口——尝试绑定候选端口,并选取第一个绑定成功的端口:

    foreach ($p in 9223,9250,9333,9555,18222) {
      try { $l=[System.Net.Sockets.TcpListener]::new([Net.IPAddress]::Loopback,$p)
            $l.Start(); "OK $p"; $l.Stop() } catch { "FAIL $p" } }
    
  2. 将任务改为使用该端口。使用 PowerShell Set-ScheduledTask,不要 使用 schtasks /change——即使任务没有存储密码,后者也会错误地提示输入 Windows 密码:

    $a = New-ScheduledTaskAction -Execute 'C:\Program Files\Google\Chrome\Application\chrome.exe' `
         -Argument '--remote-debugging-port=<PORT> --user-data-dir=C:\chrome-debug --no-startup-window'
    Set-ScheduledTask -TaskName 'chromedebug' -Action $a
    

    通过 ssh wsl 'ssh windows "..."' 传递引号很不可靠;请使用 -EncodedCommand <base64-UTF16LE> 运行 PowerShell,以避免此问题。

  3. 结束旧实例,重新启动并验证:

    Get-CimInstance Win32_Process -Filter "name='chrome.exe'" |
      ? { $_.CommandLine -like '*chrome-debug*' } | % { Stop-Process $_.ProcessId -Force }
    schtasks /run /tn chromedebug
    (Invoke-WebRequest -UseBasicParsing http://127.0.0.1:<PORT>/json/version).Content
    
  4. 使用新的 $PORT 重新运行步骤 0 中的隧道命令。

**持久解决方法(可选,需要管理员权限):**预留该端口,避免 WinNAT 占用——net stop winnat; netsh int ipv4 add excludedportrange protocol=tcp startport=<PORT> numberofports=1 store=persistent; net start winnat。停止 winnat 会短暂中断 WSL2/Hyper-V NAT,因此经过它的 SSH 链路可能会短暂断开——只有在可以接受短暂中断时才执行。

Death 陷阱 — 电池状态切换时任务计划程序会终止 Chrome

**症状:**与端口陷阱相反,调试版 Chrome 进程会在每次启动几分钟后退出(命令行中没有 chrome-debug 的 chrome.exe),而调试端口空闲且可绑定。运行 schtasks /run /tn chromedebug 会恢复 CDP,但大约 2 分钟后又会退出。

**原因:**这台电脑是笔记本电脑,而使用默认设置创建的任务会设置 StopIfGoingOnBatteries=true / DisallowStartIfOnBatteries=true。即使插着充电器,Windows 的交流电/电池状态也可能每隔几分钟切换一次(电池养护导致的充电限制、接头松动),每次切换时,任务计划程序都会终止任务中的 Chrome。证据是任务计划程序操作日志事件 327:Task Scheduler stopped instance ... of task "\chromedebug" because the computer is switching to battery power. chromedebug 任务已经应用了固定设置,但如果通过 New-ScheduledTask/Register-ScheduledTask 重新创建任务,默认设置会悄悄重新引入这些问题,因此每次此症状再次出现时,都要重新检查设置。

诊断:

  1. schtasks /query /tn chromedebug /xml — 在 <Settings> 中, StopIfGoingOnBatteries / DisallowStartIfOnBatteries 必须为 false, ExecutionTimeLimit 必须为 PT0S(无限制)。如果不是,问题就在这里——直接进行修复。

  2. 任务计划程序操作日志默认处于禁用状态;启用它并捕捉下次退出时的事件:

    wevtutil sl Microsoft-Windows-TaskScheduler/Operational /e:true
    # after a death:
    Get-WinEvent -LogName 'Microsoft-Windows-TaskScheduler/Operational' -MaxEvents 100 |
      ? { $_.Message -match 'chromedebug' } | select TimeCreated, Id, Message
    

    事件 327 中出现“switching to battery power”表示这是此陷阱。如果完全没有 32x 停止事件,则说明 Chrome 自身崩溃了——在任务操作中添加 --enable-logging --v=1,重现问题,读取 C:\chrome-debug\chrome_debug.log,然后撤销这些标志。

  3. 检查电池状态:运行 Get-CimInstance Win32_Battery(有结果表示这是笔记本电脑),并运行 [System.Windows.Forms.SystemInformation]::PowerStatus(先运行 Add-Type -AssemblyName System.Windows.Forms)查看当前交流电状态。

持久修复 — 替换任务的设置,同时保留操作和 InteractiveToken 主体(Set-ScheduledTask 不会触碰你未传入的部分)。将以下内容放入 .ps1,并通过 -EncodedCommand 传输,而不是在两次 SSH 跳转之间内联加引号:

$s = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries `
     -ExecutionTimeLimit ([TimeSpan]::Zero) -MultipleInstances IgnoreNew
Set-ScheduledTask -TaskName 'chromedebug' -Settings $s
# from dev-remote: encode UTF-16LE+base64, run via the double hop
B64=$(iconv -f UTF-8 -t UTF-16LE /tmp/fix.ps1 | base64 -w0)
ssh wsl "ssh windows 'powershell -NoProfile -EncodedCommand $B64'"

(-ExecutionTimeLimit 设为零很重要:否则 New-ScheduledTaskSettingsSet 默认会设为 72 h,导致 Chrome 在三天后退出。)然后重新启动,并进行真正的测试——确认 4–5 分钟后进程数仍不为零,确保已超过状态切换间隔,而不只是确认 CDP 曾成功响应一次。

访问连接方式(及修复方法)

两台机器都是 Iliyas 的 Tailscale tailnet 上的节点:

  • iliyasone = 100.93.231.101 — 家用 PC 上的 WSL 机器。Tailscale 运行在 WSL 内部,而不是 Windows 上;Windows 主机通过 WSL 使用 ssh windows 访问(→ 127.0.0.1:2222,密钥 ~/.ssh/id_win)。Windows 环回地址不会共享到 WSL,因此要从 WSL 访问调试端口,需要使用步骤 0 中的 ssh -L ... windows 隧道。
  • dev-remote = 100.105.176.17。它的 ~/.ssh/config 中有 Host wsl → 100.93.231.101,并且它的 root 密钥已加入 WSL 机器的 authorized_keys, 因此可以通过 tailnet 使用 ssh wsl。

tailnet 地址不会因家庭 IP 变化而改变,因此 Iliyas 的网络切换时无需重新配置。 当 connect.sh 失败(或手动检查显示 NO_CDP)时:

  • 远端离线(PC 处于睡眠状态/WSL 未启动):tailscale status 会显示 iliyasone 离线。无法从 dev-remote 修复。
  • Chrome 未运行,但 ssh wsl 可以连接:参见“启动”。
  • 端口被 WinNAT 占用:参见“端口问题”。
  • Chrome 重启后又立即退出:参见“退出问题”。
  • 隧道未启动:重新运行 connect.sh(它会重建两段连接)。
  • tailnet 路径上的 MTU 黑洞(2026-08-15 发现):ping 正常,但 ssh wsl 卡在 expecting SSH2_MSG_KEX_ECDH_REPLY,或者小型 CDP 调用 (/json/version)正常,而大型调用(/json/list)没有返回结果—— dev-remote 与 iliyasone 之间的大数据包被丢弃了。分两步修复: 对每次连接 wsl 的 ssh 强制使用较小的经典 KEX (-o [email protected],curve25519-sha256—— 默认的抗量子 sntrup761 KEX 会发送超大数据包),并降低 dev-remote 上接口的 MTU: ip link set dev tailscale0 mtu 1200(默认值 1280 超过了实际路径 MTU)。MTU 设置在 dev-remote 重启后不会保留,但 connect.sh 会在每次非快速路径运行时重新 应用;如果大数据传输仍然卡住,请检查 ip link show tailscale0。MTU 修复前打开的 隧道仍使用错误的 MSS——更改 MTU 后请重启这些隧道。

目前 tailnet 上只有一个家用节点(iliyasone)。如果 Iliyas 之后改用另一台机器, 它会作为独立节点加入,并拥有自己的名称/IP——将 Host wsl(或新增 Host wsl-<name>)指向该节点。不要自行创建非 tailnet 路由。

评论

支持 Markdown