go - 如何进行简单的 SSH x11 转发
问题描述
我正在尝试在 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
解决方案
// 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 转发的常用方法。
我不是围棋程序员。但是在查看文档之后,在您发送 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 客户端。
推荐阅读
- amazon-web-services - 将约 200.000 个 s3 文件复制到新前缀
- javascript - fetch() 未捕获自定义错误消息
- python - 如何制作时间间隔不均匀的折线图?在 FacetGrid 函数中
- javascript - 如何制作图像滑块的想法
- types - 为什么 Unsigned 特征不会自动给出 Rust 中的 One 特征?
- java - Spring Boot 2.5/Spring Data Rest 3.5 在创建/修补资源时导致 NPE
- visual-studio-code - 带引号的 Stange bux
- android - 使用 FirebaseStored 下载 SVG 数据图像
- css - 你如何在单行中制作css网格流而不换行
- javascript - 传单地理搜索 - 将结果标记绑定到现有标记