我正在尝试在Go中实现ssh x11转发,这参考了Paramiko的源代码,但是效果不佳。
x11-req请求似乎成功,但对于OpenChannel失败。 有没有更好的方法?
https://tools.ietf.org/html/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
答案 0 :(得分:0)
// 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客户端会将X11请求发送到ssh服务器。这告诉服务器客户端希望X11转发该连接。服务器将执行一些设置,并打开一个TCP侦听端口以接收来自X客户端的连接。
当X客户端连接到ssh服务器的X11侦听端口时,ssh服务器将打开一个返回ssh客户端的通道。 ssh客户端将连接到本地X服务器,并且ssh客户端和ssh服务器将在X服务器(对ssh客户端主机本地)和X客户端(对ssh服务器主机本地)之间中继数据。每个通道只处理一个X客户端。
因此,您这样的程序必须向服务器发送请求,以表明您的程序希望通过ssh连接转发X11。当X客户端尝试使用转发的X11服务时,实际的x11通道将根据需要从ssh服务器打开到ssh客户端。