与 FamilyWild 共享 X11 服务器跨主机
2026-08-02 你有没有尝试过在容器、chroot 或通过 ssh 运行 X11 应用程序,并使用绑定挂载的 .Xauthority,但却遇到“需要授权,但未指定授权协议”的提示?文件就在那儿,挂载为只读,客户端也期待着它,但 X 却拒绝了连接。原因其实很微妙,解决方法只需要一行 sed。为什么 cookie 被拒绝?一个 .Xauthority 文件是一个 cookie 列表,每个条目由一个家庭和一个主机名进行标识。当客户端连接时,它不仅仅是找第一个找到的 cookie——它会查找与客户端认为运行的机器匹配的主机名的条目。正是这一点在客户端运行的位置与 cookie 创建的位置不同时被破坏。在容器内,主机名不同;通过未转发的套接字,客户端解析出的名字也完全不同。cookie 存在且有效,但其主机名不匹配,因此客户端从未提供它,X 会退回到“没有授权协议”。你可以自己查看家庭/主机名的键值:$ xauth list myhost/unix:0 MIT-MAGIC-COOKIE-1 a1b2c3d4e5f6... 那个前缀 myhost/unix:0 就是问题所在——它将 cookie 锁定到 myhost。面对这样的困境,FamilyWild 的出现提供了帮助。X 有一个通配符家庭 FamilyWild ,其数值为 0xffff。这个家庭中的 cookie 可以匹配任何主机名。因此,我们不再试图让客户端的主机名与 cookie 匹配,而是将 cookie 重写为能匹配每个主机。xauth nlist 以数字格式打印条目,其中第一个字段是 4 个十六进制数字的家庭。用 ffff 进行覆盖,并将结果合并到一个新的文件中:: > /tmp/portable.Xauthority && xauth nlist :0 | \ sed 's/^..../ffff/' | xauth -f /tmp/portable.Xauthority nmerge - # 替换 :0 为你的 $DISPLAY 值。这个变化只是一字段。这一小修改是值得注意的。一个 .Xauthority 条目是一个打包的二进制记录:先是一个 2 字节的家庭,然后是长度前缀的地址、显示号码、授权名称以及 cookie 本身。打印原始文件,家庭就在前两个字节中——0100,也就是 FamilyLocal:00000000: 0100 0006 6d79 686f 7374 0001 3000 124d ....myhost..0..M 00000010: 4954 2d4d 4147 4943 2d43 4f4f 4b49 452d IT-MAGIC-COOKIE- 00000020: 3100 10a1 b2c3 d4e5 f607 1829 3a4b 5c6d 1..........):K\m 00000030: 7e8f 90 ~.. 现在打印我们刚刚构建的 FamilyWild 版本。所有字节逐字相同——相同的 myhost 地址,相同的 cookie——除了前两个字节,现在被翻转为 ffff:00000000: ffff 0006 6d79 686f 7374 0001 3000 124d ....myhost..0..M 00000010: 4954 2d4d 4147 4943 2d43 4f4f 4b49 452d IT-MAGIC-COOKIE- 00000020: 3100 10a1 b2c3 d4e5 f607 1829 3a4b 5c6d 1..........):K\m 00000030: 7e8f 90 ~.. 这一字段就是整个窍门:地址字节仍然拼写为 myhost,但 X 不再在乎,因为家庭 0xffff 无条件匹配。绑定挂载(或 scp)/tmp/portable.Xauthority 到客户端运行的位置,将 XAUTHORITY 指向它,无论主机名不匹配,连接都会被接受。那 xhost + 呢?你常常会看到建议使用 xhost + 作为“让它工作”的解决方案,它确实有效——通过完全关闭基于主机的访问控制。然后每个主机的每个客户端都可以连接到你的显示器,而不需要任何 cookie。在单用户机器上,这听起来无害,但 X 在客户端之间没有隔离:任何能够访问服务器的人都可以读取你的按键、抓取任何窗口的内容并注入合成输入。xhost + 将这种能力交给每个本地用户,并且如果你的服务器监听 TCP,则会还把它交给网络。即使是较窄的 xhost +local:仍然信任盒子上的每个 UID。FamilyWild cookie 保持了门的锁定——客户端仍然需要提供秘密——同时仅移除了阻碍的主机名约束。使用它而不是 xhost + 并将 cookie 文件保留在 0600。一个注意事项 FamilyWild cookie 故意没有前一个 cookie 具体:任何能够访问你的 X 套接字并读取此文件的人都可以与显示器对话。只将它交给实际需要的环境,切勿在共享机器上留下副本。这一技巧是一个更大设置中的一小部分——我用它将 X 转发到非特权的 LXC 容器中,详细写在《用 LXC 增强 x11 应用程序安全性》中。
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡