在Go语言中实现一个ssh代理,错误信息包长度错误,这些是ssh在调试模式下的错误:
debug1: SSH2_MSG_KEXINIT sent
Bad packet length 1231976033.
ssh_dispatch_run_fatal: Connection to ::1 port 8080: message authentication code incorrect
代码:
func handleSSH(conn net.Conn, r *bufio.Reader, protocol string) {
target, err := url.Parse("ssh://localhost:3333")
if err != nil {
fmt.Println("Error parsing target", err)
conn.Close()
return
}
targetConn, err := net.Dial("tcp", target.Host)
if err != nil {
fmt.Println("error dialing SSH target:", err)
conn.Close()
return
}
defer targetConn.Close()
var wg sync.WaitGroup
wg.Add(2)
go func() {
_, err := io.Copy(targetConn, conn)
if err != nil {
fmt.Println("error copying data to target:", err)
}
wg.Done()
}()
go func() {
_, err := io.Copy(conn, targetConn)
if err != nil {
fmt.Println("error copying data from target:", err)
}
wg.Done()
}()
wg.Wait()
conn.Close()
}
// EDIT
func connection(conn net.Conn) {
r := bufio.NewReader(conn)
protocol, err := r.ReadString('\n')
if err != nil {
fmt.Println("Error reading first line", err)
conn.Close()
return
}
if protocol[0:3] == "SSH" {
handleSSH(conn, r, protocol)
}
}
func main() {
ln, err := net.Listen("tcp", ":8080")
if err != nil {
panic(err)
}
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
panic(err)
}
go connection(conn)
}
}
编辑:添加了有关如何启动连接的相关信息的代码,并重现错误。
我最好的猜测是ssh协商过程被中断了,事情失去了同步。
1条答案
按热度按时间hjqgdpho1#
该代码从客户端阅读第一行,并检查协议的类型,以便调用适当的处理程序:
但是代码无法将已经读取的字节转发到连接的服务器,这些字节位于
protocol
中,并被指定给handleSSH
,但是一旦连接建立,它无法将这些字节发送到连接的服务器,相反,它只是在客户端和服务器之间复制新数据。这意味着服务器没有从客户端获得第一行,因此它可能会抱怨类似
Invalid SSH identification string.
的协议错误,该错误被转发到客户端,并被误认为是来自SSH连接的有效数据。