ssh X11 Forwarding机制浅析
ssh通常被用来进行字符运维,但其实ssh也可以进行图像传输,所谓图像传输,实际上是X11协议数据的转发。Linux上的Xserver和Xclient是可以分离的,Xserver是负责显示以及键盘鼠标的输入,Xclient负责程序的运行。当Xserver监听网络端口时,也可以直接通过socket进行通信。一般Xserver默认不允许直接网络传输,这时候就可以借助ssh通道进行显示。
运行简易流程
ssh发起请求
ssh -X user@serverIP
sshd初始化
为了更好的叙述,将sshd运行的机子称为服务端。该端同时运行Xclient。
sshd接受请求建立连接,并将本次ssh会话的DISPLAY指定为hostname:10.0
,这里需要注意的是DISPLAY环境变量格式为hostname:displaynumber.screennumber
,若hostname为空,则表示Xserver运行在本机,当以tcp连接时,displaynumber的值为实际连接的端口减去6000,即本次的监听端口为6010,而6010的监听者就是sshd程序。
图形程序的运行
在ssh会话中执行图形程序,ssh客户端本质上只负责输入和显示,程序的执行在sshd上,这在pstree查看sshd进程可以看到sshd(822369)---bash(822539)---xclock(1014618)
。比如在这里我运行了xclock,父进程为bash。该程序与6010进行TCP通信,将X11协议数据发送到6010,sshd再将该数据放入ssh通道与ssh客户端进行通信。
详见openssh项目channels.c文件中static void channel_post_x11_listener(struct ssh *ssh, Channel *c)
函数。
ssh与Xserver通信
ssh运行在客户端,该端同时运行Xserver.
ssh与Xserver建立连接,将ssh通道中的X11协议数据发送到Xserver。
详见openssh项目channels.c文件中int x11_connect_display(struct ssh *ssh)
函数。
流程图
本质上就是进行对X11协议进行了代理转发