安全策略
基于 main@306d253 的文档在 GitHub 上查看编辑此页
WebMux 以启动服务的系统用户身份执行任意命令,等同于把一个 shell 暴露到网络上。它不是进程沙箱,也不提供多用户隔离。安全依赖于网络隔离:
- 默认监听所有接口
0.0.0.0:7681;仅本机使用请设为127.0.0.1:7681。远程访问建议绑定 Tailscale / WireGuard 等可信 VPN 地址,并用防火墙限制可访问的接口。 - 设置随机的共享
token。未显式指定--config且默认配置不存在时,首次启动会生成 0600 配置文件和持久化的 256 位 Token;未启用隧道时不会在启动输出中打印该 Token,可用webmux status --json --reveal-token查看。启用隧道时仍会输出带 Token 的链接和二维码,详见下文;日志中的持久化 Token 不会因重启失效。若现有配置的 token 为空且监听地址不是 loopback(包括默认的0.0.0.0),则每次启动临时生成 256 位随机 Token,终端打印带#token=的本地链接;以 systemd / launchd 运行时该链接会写入 journal 或日志文件,且重启后更换。只有仅监听 loopback 且未启用隧道时,空 token 才表示不认证。 - 不要把 WebMux 直接暴露到公网。 确需公网访问时,只使用受控 Cloudflare Tunnel 入口,并接受下面的风险模型。
Cloudflare Tunnel
Section titled “Cloudflare Tunnel”--tunnel、TOML 或网页“设置 → 公网访问”可通过 Cloudflare Tunnel 把同一个 shell 以 HTTPS 暴露到公网。此时 Token 是唯一入口屏障:
- Quick Tunnel 没有 Cloudflare Access 或额外身份验证。任何拿到链接、二维码或 Token 的人都能以服务用户身份执行命令。
- 隧道要求至少 43 字符的 WebMux 登录 Token。启动需要认证且未配置时生成 256 位随机 Token;运行时不生成或更换登录 Token。网页配置恢复遇到弱 Token 时保留本地服务且公网保持关闭,修正配置后重启。建议用
openssl rand -base64 32生成。 - 隧道模式会在终端打印带
#token=的本地与公网链接和二维码。以 systemd / launchd 运行时,这些内容会写入 journal 或日志文件,请限制日志访问权限。首次启动写入配置文件的 Token 会跨重启保留;只有未持久化的临时 Token 会在重启时更换。 - 公网主机名只接受 Cloudflare 转发的 Host 与该主机的
https://Origin,其他 Host 与http://Origin 会被拒绝;cloudflared 退出后立即撤销授权。 - Token 不进入请求 URL(HTTP 使用 Bearer 头,WebSocket 使用
webmux.token.*子协议),前端也不写入 Cookie(Cookie 不按端口隔离,同一主机其他端口的页面可以读取);服务端仅为兼容手动设置的客户端仍接受webmux_tokenCookie 作为 HTTP 认证,并照常执行 Host 与 Origin 检查;但 Bearer、子协议头与终端输入输出仍会经过 Cloudflare 边缘。 - 不再需要公网访问时,在网页、托盘或本机 API 中关闭隧道;持久化设置会在下次启动恢复,仅移除
--tunnel不等于关闭。网页 API 保留 Token、Host 和 Origin 校验;本机控制面仅允许同一用户且会话之外的进程修改设置。网页开启前确认公开 shell 风险。 - Cloudflare 凭据只写不读,保存于状态目录内 0600 文件,目录为 0700;不要共享该目录。损坏或不可读存储不回退配置文件开启公网。关闭时即使持久化失败也立即撤销公网授权并停止隧道,返回未持久化错误;修复后重新保存,避免重启恢复旧开关。
- Named Tunnel 的控制台步骤、两个 token 的区别与排错见 Cloudflare Named Tunnel 配置指南。
Tailscale Serve / Funnel
Section titled “Tailscale Serve / Funnel”[tailscale] mode = "serve" 通过 tailscaled 为当前节点创建 HTTPS 入口,默认只在 tailnet 内可达;mode = "funnel" 会显式公开到互联网,风险与 Named Tunnel 相当:
- Funnel 必须由用户显式配置,WebMux 不会因为检测到 Tailscale 就自动公开。任何拿到 Funnel 链接与 Token 的人都能执行命令。
- Serve/Funnel 都要求至少 43 字符的 WebMux 登录 Token;留空时生成本次进程 Token,带 Token 的启动链接可能写入日志。
- WebMux 只操作
tailscale.json记录的精确端口与 target,不覆盖其他入口,也不调用serve reset/funnel reset;退出、失败或切换时先撤销来源授权,正常路径下旧 ts.net Host/Origin 立即返回 403。若此前按手工方案把 ts.net 主机名写入了allowed_origins,该白名单独立于来源注册表,撤销后仍会接受旧 Origin;迁移到托管的 Serve/Funnel 时请删除这些手工条目。 GET /api/tailscale不返回 Token、其他入口的 target 或原始 CLI 输出。网页可修改模式、端口与 provider 并立即生效:写端点保留 Token、Host 与 Origin 校验,开启 Funnel 需要显式确认公网风险,登录 Token 少于 43 字符时拒绝开启;WebMux 会话内的进程不能经本机 API 修改。CLI 路径只能在 TOML 中设置;网页设置文件损坏或被锁时托管入口保持关闭。- WSL 中的 Windows provider 必须显式选择且要求 mirrored 网络;WebMux 不会自动修改
.wslconfig、Windows 防火墙、tailnet ACL 或自动提权。 - 配置、端口与故障排查见 Tailscale Serve / Funnel 入口。
内置的防护措施:
- 所有 API 与 WebSocket 都需要认证(启用 token 时),token 以常量时间比较。
- 带 Origin 的请求必须同源或位于
allowed_origins中,防止其他网站通过浏览器发起连接。 - 终端输入输出不会写入日志;配置接口不返回 token。
- 响应头包含
X-Content-Type-Options: nosniff与Referrer-Policy: no-referrer。
其他注意事项:
- WebMux 不内置 TLS;需要 HTTPS 时请使用
tailscale serve或反向代理。 - token 保存在浏览器 localStorage 中,只在可信设备上登录。
- 登记的 Git 仓库必须可信:Git 会执行仓库配置中的 hooks 与 filters。
- 关闭会话会清理其进程树,但完全脱离终端会话的自守护进程可能不受控制。
只有最新发布版本会接收安全修复。
请不要通过公开 Issue 报告安全漏洞。请使用 GitHub 的 私密漏洞报告 功能,并提供:
- 受影响的版本与平台;
- 复现步骤或概念验证;
- 可能的影响范围。
我们会尽快确认并处理。