如何让我的 GCloud Function 打开一个新的 SSH 连接来使用 SFTP 服务器?

How can I make my GCloud Function open a new SSH connection to consume a SFTP server?

我的设置需要一个 Google 函数来做一些事情并将结果上传到 SFTP 服务器。我目前正在使用基本的 sftpcrypto/ssh 包来实现这一点。在本地,经过一些调试,我能够检索到服务器的公钥。

当部署到 GCloud 时,当然没有任何效果。

这就是处理我函数上的连接的原因

func Connect(host string, port string, user string, password string) (*ssh.Client, error) {
    hostKey := getHostKey(host)

    var auths []ssh.AuthMethod

    // Use password authentication if provided
    if password != "" {
        auths = append(auths, ssh.Password(password))
    }

    config := &ssh.ClientConfig{
        User:            user,
        HostKeyCallback: ssh.FixedHostKey(hostKey),
        Auth:            auths,
    }

    cipherOrder := config.Ciphers
    config.Ciphers = append(cipherOrder, "aes128-cbc", "3des-cbc")

    sshConn, err := ssh.Dial("tcp", host+":"+port, config)
    if err != nil {
        return nil, err
    }

    return sshConn, nil
}

func getHostKey(host string) ssh.PublicKey {
    file, err := os.Open("/root/.ssh/known_hosts")
    if err != nil {
        fmt.Fprintf(os.Stderr, "Unable to read known_hosts file: %v\n", err)
        os.Exit(1)
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)
    var hostKey ssh.PublicKey
    for scanner.Scan() {
        fields := strings.Split(scanner.Text(), " ")
        if len(fields) != 3 {
            continue
        }
        if strings.Contains(fields[0], host) {
            var err error
            hostKey, _, _, _, err = ssh.ParseAuthorizedKey(scanner.Bytes())
            if err != nil {
                fmt.Fprintf(os.Stderr, "Error parsing %q: %v\n", fields[2], err)
                os.Exit(1)
            }
            break
        }
    }

    if hostKey == nil {
        fmt.Fprintf(os.Stderr, "No hostkey found for %s", host)
        os.Exit(1)
    }

    return hostKey
}

known_hosts 文件不存在。我没有服务器的公钥,但使用 Filezilla 我可以很好地连接到它。

我必须指定那些密码,因为准系统 ssh hostname 会 return Unable to negotiate... 错误

还有其他方法吗?我正在考虑上传我自己的 known_hosts 文件,但这听起来不是一个很好的解决方案。

我可能设计过度了。

像这样设置 ssh.ClientConfig 解决了问题:

config := &ssh.ClientConfig{
        User:            user,
        Auth:            auths,
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}

无论如何我也找到了一个更好的包来轻松处理 SSH 连接,simplessh

conn, _ := simplessh.ConnectWithPassword(host, user, pass)

client, _ := sftp.NewClient(conn.SSHClient)