gpt4 book ai didi

SSH 连接超时

转载 作者:IT老高 更新时间:2023-10-28 13:06:59 25 4
gpt4 key购买 nike

我正在尝试使用 golang.org/x/crypto/ssh 建立 SSH 连接,我有点惊讶我似乎无法找出如何使 NewSession 函数(我实际上没有看到任何超时的方法)。当我尝试连接到有问题的服务器时,它会挂起很长时间。我写了一些东西来使用 selecttime.After 但感觉就像一个黑客。我还没有尝试过将底层的 net.Conn 保留在我的结构中,并继续进行 Conn.SetDeadline() 调用。还没有尝试过,因为我不知道 crypto/ssh 库是否会覆盖这个或类似的东西。

任何人有一个很好的方法来使用这个库来超时死服务器?或者有人知道更好的图书馆吗?

最佳答案

使用 ssh 包透明地处理此问题的一种方法是通过自定义的 net.Conn 创建一个空闲超时的连接,该连接为您设置截止日期。但是,这会导致后台Reads on a connection超时,所以我们需要使用ssh keepalives来保持连接打开。根据您的用例,只需使用 ssh keepalives 作为连接失效的警报就足够了。

// Conn wraps a net.Conn, and sets a deadline for every read
// and write operation.
type Conn struct {
net.Conn
ReadTimeout time.Duration
WriteTimeout time.Duration
}

func (c *Conn) Read(b []byte) (int, error) {
err := c.Conn.SetReadDeadline(time.Now().Add(c.ReadTimeout))
if err != nil {
return 0, err
}
return c.Conn.Read(b)
}

func (c *Conn) Write(b []byte) (int, error) {
err := c.Conn.SetWriteDeadline(time.Now().Add(c.WriteTimeout))
if err != nil {
return 0, err
}
return c.Conn.Write(b)
}

然后您可以使用 net.DialTimeoutnet.Dialer 来获取连接,将其包装在您的 Conn 中并设置超时,然后将其传递给 ssh.NewClientConn.

func SSHDialTimeout(network, addr string, config *ssh.ClientConfig, timeout time.Duration) (*ssh.Client, error) {
conn, err := net.DialTimeout(network, addr, timeout)
if err != nil {
return nil, err
}

timeoutConn := &Conn{conn, timeout, timeout}
c, chans, reqs, err := ssh.NewClientConn(timeoutConn, addr, config)
if err != nil {
return nil, err
}
client := ssh.NewClient(c, chans, reqs)

// this sends keepalive packets every 2 seconds
// there's no useful response from these, so we can just abort if there's an error
go func() {
t := time.NewTicker(2 * time.Second)
defer t.Stop()
for range t.C {
_, _, err := client.Conn.SendRequest("keepalive@golang.org", true, nil)
if err != nil {
return
}
}
}()
return client, nil
}

关于SSH 连接超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31554196/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com