Skip to content

Commit

Permalink
ops/virtualization,advanced/desktop: Abstract socket and X
Browse files Browse the repository at this point in the history
  • Loading branch information
taoky committed Nov 11, 2024
1 parent ef15cc5 commit 4ee82c8
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
18 changes: 18 additions & 0 deletions docs/advanced/desktop.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ X 窗口系统起源于 1984 年。在那个时代,桌面环境没有酷炫的

默认情况下,如果你正在使用 Linux 桌面,那么默认连接到的 socket 则为 `/tmp/.X11-unix/X0`(对应环境变量 `DISPLAY=:0`)。

!!! warning "X 的抽象套接字支持"

Linux 支持「抽象套接字」(abstract socket),即允许 Unix socket 绑定到一个不在文件系统中的地址(正常的 Unix socket 需要将地址设置为一个文件路径)。在编写代码时,将 `bind()` 路径(`sun_path`)的开头设置为 `NULL` 就表示抽象套接字。可以查看 `/proc/net/unix` 文件,其中以 `@` 开头的条目则是抽象套接字。

可以注意到,默认情况下,X 服务端会同时监听 `/tmp/.X11-unix/X0` 和 `@/tmp/.X11-unix/X0`:

```console
$ cat /proc/net/unix | grep X11-unix/X0
000000002c61e829: 00000003 00000000 00000000 0001 03 379918 @/tmp/.X11-unix/X0
(省略)
0000000055982f40: 00000002 00000000 00010000 0001 01 20744 /tmp/.X11-unix/X0
(省略)
```

事实上,上文的描述是有一些偏差的——目前 X 客户端仍然会会优先连接 `@/tmp/.X11-unix/X0`。

抽象套接字在如今带来了一些安全性的挑战,因为和文件系统上的 `/tmp/.X11-unix/X0` 可以依靠文件级别的权限控制不同,抽象套接字只能通过网络命名空间实现隔离。但是如果直接关闭 X server 的抽象套接字,攻击者可以创建虚假的名为 `@/tmp/.X11-unix/X0` 的套接字,欺骗 X 客户端连接。不过连接到 X server 还需要经过一层认证机制(XAuthority),因此如果不去 `xhost +` 的话,攻击者必须要能够获取 XAuthority 信息,才能够连接到对应的 X server。

!!! tip "启动一个新的 X Server"

存在这样一种场景:你需要启动一个独立的 X server 来测试,而不希望对应的程序使用当前的 X server。其中一个便利的工具是 `xvfb-run`:Xvfb 是一个无头(无显示)的 X server,对自动化测试场景来说很方便。安装 `xvfb` 包后,即可使用:
Expand Down
7 changes: 5 additions & 2 deletions docs/ops/virtualization/container.md
Original file line number Diff line number Diff line change
Expand Up @@ -530,8 +530,11 @@ COPY --from=builder /tmp/example /usr/local/bin/example

1. 当使用 `-X` 时,服务端会假设客户端是不可信任的,因此会限制一些操作;`-Y` 选项则会放宽这些限制。详见 [ssh_config(5)][ssh_config.5] 对 `ForwardX11Trusted` 的介绍。

X 客户端连接到服务器,首先需要知道 X 服务器的地址。这是由 `DISPLAY` 环境变量指定的,一般是 `:0`,代表连接到 `/tmp/.X11-unix/X0` 这个 UNIX socket。
此外,由于 X 的协议设计是「网络透明」的,因此 X 服务器理论上也可以以 TCP 的方式暴露出来(但是不建议这么做),客户端通过类似于 `DISPLAY=host:port` 的方式连接。
X 客户端连接到服务器,首先需要知道 X 服务器的地址。这是由 `DISPLAY` 环境变量指定的,一般是 `:0`,代表连接到 `/tmp/.X11-unix/X0` 这个 UNIX socket。此外,由于 X 的协议设计是「网络透明」的,因此 X 服务器理论上也可以以 TCP 的方式暴露出来(但是不建议这么做),客户端通过类似于 `DISPLAY=host:port` 的方式连接。

!!! warning "X 与抽象套接字(abstract socket)"

目前,X server 会默认开启 abstract socket 支持,即使不共享 `/tmp/.X11-unix`,X 客户端也可以以此连接到 X 服务器。Abstract socket 只能通过网络命名空间隔离。详情见[高级内容的「Linux 桌面与窗口系统」部分](../../advanced/desktop.md)。

因此,首先需要传递 `DISPLAY` 环境变量,并且将 `/tmp/.X11-unix` 挂载到容器中:

Expand Down

0 comments on commit 4ee82c8

Please sign in to comment.