如果您设置X11UseLocalhost = no,您甚至允许外部流量到达 X11 套接字。即定向到机器外部IP的流量可以到达SSHD X11转发。还有两种可能适用的安全机制(防火墙、X11 身份验证)。不过,如果您正在处理像这种情况下的用户甚至应用程序特定问题,我更愿意单独留下 系统全局设置。
这是在 sshd 配置中更改 X11UseLocalhost 的替代方法:
+ docker container net ns +
| |
172.17.0.1 | 172.17.0.2 |
+- docker0 --------- veth123@if5 --|-- eth0@if6 |
| (bridge) (veth pair) | (veth pair) |
| | |
| 127.0.0.1 +-------------------------+
routing +- lo
| (loopback)
|
| 192.168.1.2
+- ens33
(physical host interface)
使用默认的X11UseLocalhost yes,sshd 在根网络命名空间上侦听127.0.0.1。我们需要从 docker 网络命名空间内部获取 X11 流量到根网络 ns 中的环回接口。 veth 对连接到docker0 网桥,因此两端可以在没有任何路由的情况下与 172.17.0.1 通信。根网ns中的三个接口(@987654327@、lo和ens33)可以通过路由进行通信。
我们要实现以下目标:
+ docker container net ns +
| |
172.17.0.1 | 172.17.0.2 |
+- docker0 --------< veth123@if5 --|-< eth0@if6 -----< xeyes |
| (bridge) (veth pair) | (veth pair) |
v | |
| 127.0.0.1 +-------------------------+
routing +- lo >------- sshd -+
(loopback) |
v
192.168.1.2 |
ens33 ------<-----+
(physical host interface)
我们可以让 X11 应用程序直接与172.17.0.1 对话以“逃离”docker net ns。这是通过适当设置DISPLAY 来实现的:export DISPLAY=172.17.0.1:10:
+ docker container net ns+
| |
172.17.0.1 | 172.17.0.2 |
docker0 --------- veth123@if5 --|-- eth0@if6 -----< xeyes |
(bridge) (veth pair) | (veth pair) |
| |
127.0.0.1 +-------------------------+
lo
(loopback)
192.168.1.2
ens33
(physical host interface)
现在,我们在根网 ns 中添加一个 iptables 规则,从 172.17.0.1 路由到 127.0.0.1:
iptables \
--table nat \
--insert PREROUTING \
--proto tcp \
--destination 172.17.0.1 \
--dport 6010 \
--jump DNAT \
--to-destination 127.0.0.1:6010
sysctl net.ipv4.conf.docker0.route_localnet=1
也许您可以通过仅路由来自该容器(veth 端)的流量来改进这一点。另外,老实说,我不太确定为什么需要route_localnet。 127/8 似乎是一个奇怪的数据包源/目标,因此默认情况下禁用路由。您可能还可以将流量从 docker net ns 内的环回接口重新路由到 veth 对,然后从那里重新路由到根网络 ns 中的环回接口。
使用上面给出的命令,我们最终得到:
+ docker container net ns +
| |
172.17.0.1 | 172.17.0.2 |
+- docker0 --------< veth123@if5 --|-< eth0@if6 -----< xeyes |
| (bridge) (veth pair) | (veth pair) |
v | |
| 127.0.0.1 +-------------------------+
routing +- lo
(loopback)
192.168.1.2
ens33
(physical host interface)
但是,现在我们正尝试以172.17.0.1:10 的身份访问 X11 服务器。这不会在 x 授权文件 (~/.Xauthority) 中找到条目,通常类似于 <hostname>:10。使用 Ruben 的建议在 docker 容器中添加一个可见的新条目:
xauth add 172.17.0.1:10 . <cookie>
其中<cookie> 是 SSH X11 转发设置的 cookie,例如通过xauth list。
您可能还必须在防火墙中允许进入172.17.0.1:6010 的流量。
您还可以从 docker 容器网络命名空间内的主机启动应用程序:
sudo nsenter --target=<pid of process in container> --net su - $USER <app>
没有su,您将以root 身份运行。当然,你也可以使用另一个容器,共享网络命名空间:
sudo docker run --network=container:<other container name/id> ...
上面显示的 X11 转发机制适用于整个网络命名空间(实际上,适用于连接到 docker0 网桥的所有内容)。因此,它适用于容器网络命名空间内的任何应用程序。