如何进行简单的 SSH x11 转发

Posted

技术标签:

【中文标题】如何进行简单的 SSH x11 转发【英文标题】:How to do simple SSH x11 forwarding 【发布时间】:2019-07-09 13:00:37 【问题描述】:

我正在尝试在Go中实现ssh x11转发,参考Paramiko的源码,但是效果不好。

x11-req 请求似乎成功,但 OpenChannel 失败。 没有更好的办法吗?

https://www.rfc-editor.org/rfc/rfc4254#section-6.3.2

完整的代码在这里。

https://gist.github.com/blacknon/6e2e6e2c0ebcd64c381925f0e3e86e42

package main

(omit)

func main() 
    // Create sshClientConfig
    sshConfig := &ssh.ClientConfig
        User: user,
        Auth: []ssh.AuthMethod
            ssh.Password(pass),
        ,
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    

    // SSH connect.
    client, err := ssh.Dial("tcp", host+":"+port, sshConfig)

    // Create Session
    session, err := client.NewSession()
    defer session.Close()

    // NOTE:
    // x11-req Payload
    payload := x11request
        SingleConnection: false,
        AuthProtocol:     string("MIT-MAGIC-COOKIE-1"),
        AuthCookie:       string("d92c30482cc3d2de61888961deb74c08"),
        ScreenNumber:     uint32(0),
    

    // NOTE:
    // send x11-req Request
    ok, err := session.SendRequest("x11-req", true, ssh.Marshal(payload))
    if err == nil && !ok 
        fmt.Println(errors.New("ssh: x11-req failed"))
    
    fmt.Printf("x11-req: %v\n", ok)
    fmt.Println("-----")

    // x11 OpenChannel (Not working...)
    x11Data := x11channel
        Host: "localhost",
        Port: uint32(6000),
    

    sshChan, req, x11err := client.OpenChannel("x11", ssh.Marshal(x11Data))
    fmt.Println(sshChan) // DEBUG
    fmt.Println(req)     // DEBUG
    fmt.Println(x11err)  // DEBUG

    (omit)


我添加了 sshd 端调试日志。

sshd[1811]: debug1: server_input_channel_req: channel 0 request x11-req reply 1
sshd[1811]: debug1: session_by_channel: session 0 channel 0
sshd[1811]: debug1: session_input_channel_req: session 0 req x11-req
sshd[1811]: debug1: channel 1: new [X11 inet listener]
sshd[1811]: debug1: channel 2: new [X11 inet listener]
sshd[1811]: debug1: server_input_channel_open: ctype x11 rchan 1 win 2097152 max 32768
sshd[1811]: debug1: server_input_channel_open: failure x11

谢谢各位!多亏了它,我才能安全地实施它。有一个工作代码。

https://gist.github.com/blacknon/9eca2e2b5462f71474e1101179847d2a

【问题讨论】:

"...但 OpenChannel 失败。"这不是很丰富。那么究竟会发生什么?服务器是否记录了任何有用的错误消息? 对不起。我添加了 sshd 端调试日志。 【参考方案1】:
// x11 OpenChannel (Not working...)
x11Data := x11channel
    Host: "localhost",
    Port: uint32(6000),


sshChan, req, x11err := client.OpenChannel("x11", ssh.Marshal(x11Data))

这里的根本问题是 X11 转发通道是从 SSH 服务器启动到 SSH 客户端的。您正在尝试打开从客户端到服务器的 X11 通道。这不受您的服务器支持,也不是使用 X 转发的常用方式。

我不是围棋程序员。但是在查看 the documentation 之后,在您发送 x11-req 之后,您似乎会调用 client.HandleChannelOpen() 来接收来自服务器的 X11 频道请求。

更多背景:为了清楚起见,从术语开始。您的程序是一个 ssh 客户端,它连接到一个 ssh 服务器。对于 X,服务器 是控制显示器、键盘和鼠标的程序。 X 客户端 是类似于 xterm 和 xeyes 的程序,它们连接到服务器以显示窗口并执行类似的操作。

当你想通过 SSH 转发 X11 时,ssh 客户端会向 ssh 服务器发送一个 X11 请求。这告诉服务器客户端需要 X11 转发连接。服务器将执行一些设置并打开一个 TCP 侦听端口以接收来自 X 客户端的连接。

当一个 X 客户端连接到 ssh 服务器的 X11 监听端口时,ssh 服务器会打开一个通道返回给 ssh 客户端。 ssh 客户端将连接到本地 X 服务器,ssh 客户端和 ssh 服务器将在 X 服务器(本地到 ssh 客户端主机)和 X 客户端(本地到 ssh 服务器主机)之间中继数据。每个通道处理一个 X 客户端。

所以像你这样的程序必须向服务器发送一个请求,表明你的程序想要通过 ssh 连接转发 X11。当 X 客户端尝试使用转发的 X11 服务时,实际的 x11 通道将根据需要从 ssh 服务器打开到 ssh 客户端。

【讨论】:

非常感谢!看来我误会了!可以根据你教的来实现!

以上是关于如何进行简单的 SSH x11 转发的主要内容,如果未能解决你的问题,请参考以下文章

PuTTY+Xming实现X11的ssh转发

X11 转发 ssh Visual Studio 远程连接

使用最后一次 CentOS CLEAN 安装设置 X11 转发的完整教程是啥?

WARNING! The remote SSH server rejected X11 forwarding

如何将 X11 转发到运行在远程 linux 主机上的虚拟机?

通过 SSH.NET c# 库转发 x11