使用Golang建立SSH连接并为会话打开新终端的方法

使用Golang建立SSH连接并为会话打开新终端的方法 我正在尝试通过我的应用程序建立到服务器的SSH连接。我希望SSH连接会话能在新终端中打开,以便我可以输入命令并进行相应的交互。类似于PuTTY那样?我能做到这一点吗?

2 回复

有一些可用的资源。

Package ssh

Package ssh 实现了 SSH 客户端和服务器。

更多关于使用Golang建立SSH连接并为会话打开新终端的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是的,你可以使用Golang建立SSH连接并在新终端中打开会话。以下是使用golang.org/x/crypto/ssh包实现SSH连接并创建交互式终端会话的示例:

package main

import (
    "fmt"
    "golang.org/x/crypto/ssh"
    "golang.org/x/term"
    "io"
    "log"
    "os"
    "time"
)

func main() {
    // SSH连接配置
    config := &ssh.ClientConfig{
        User: "username", // 替换为你的用户名
        Auth: []ssh.AuthMethod{
            ssh.Password("password"), // 替换为你的密码
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(), // 生产环境中应使用更安全的方式
        Timeout:         30 * time.Second,
    }

    // 建立SSH连接
    client, err := ssh.Dial("tcp", "hostname:22", config) // 替换为你的主机名和端口
    if err != nil {
        log.Fatal("Failed to dial: ", err)
    }
    defer client.Close()

    // 创建新会话
    session, err := client.NewSession()
    if err != nil {
        log.Fatal("Failed to create session: ", err)
    }
    defer session.Close()

    // 获取当前终端的文件描述符
    fd := int(os.Stdin.Fd())
    oldState, err := term.MakeRaw(fd)
    if err != nil {
        log.Fatal(err)
    }
    defer term.Restore(fd, oldState)

    // 设置终端模式
    modes := ssh.TerminalModes{
        ssh.ECHO:          1,     // 启用回显
        ssh.TTY_OP_ISPEED: 14400, // 输入速度
        ssh.TTY_OP_OSPEED: 14400, // 输出速度
    }

    // 获取终端尺寸
    termWidth, termHeight, err := term.GetSize(fd)
    if err != nil {
        termWidth = 80
        termHeight = 40
    }

    // 请求伪终端
    err = session.RequestPty("xterm-256color", termHeight, termWidth, modes)
    if err != nil {
        log.Fatal("Request for pseudo terminal failed: ", err)
    }

    // 设置标准输入、输出和错误
    stdin, err := session.StdinPipe()
    if err != nil {
        log.Fatal(err)
    }
    stdout, err := session.StdoutPipe()
    if err != nil {
        log.Fatal(err)
    }
    stderr, err := session.StderrPipe()
    if err != nil {
        log.Fatal(err)
    }

    // 启动远程shell
    err = session.Shell()
    if err != nil {
        log.Fatal("Failed to start shell: ", err)
    }

    // 复制标准输入到远程会话
    go func() {
        io.Copy(stdin, os.Stdin)
    }()

    // 复制远程输出到标准输出
    go func() {
        io.Copy(os.Stdout, stdout)
    }()

    // 复制远程错误到标准错误
    go func() {
        io.Copy(os.Stderr, stderr)
    }()

    // 等待会话结束
    err = session.Wait()
    if err != nil {
        if exitErr, ok := err.(*ssh.ExitError); ok {
            fmt.Printf("Session exited with status %d\n", exitErr.ExitStatus())
        } else {
            log.Fatal("Session failed: ", err)
        }
    }
}

对于密钥认证方式,可以使用以下配置:

func publicKeyFile(file string) ssh.AuthMethod {
    buffer, err := os.ReadFile(file)
    if err != nil {
        return nil
    }

    key, err := ssh.ParsePrivateKey(buffer)
    if err != nil {
        return nil
    }
    return ssh.PublicKeys(key)
}

// 在配置中使用
config := &ssh.ClientConfig{
    User: "username",
    Auth: []ssh.AuthMethod{
        publicKeyFile("/path/to/private/key"),
    },
    HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}

要运行此代码,需要先安装依赖:

go get golang.org/x/crypto/ssh
go get golang.org/x/term

这段代码会创建一个完整的交互式SSH终端会话,支持命令输入和输出显示,类似于PuTTY的交互体验。

回到顶部