golang ssh免密码

发布时间:2024-07-05 00:09:17

SSH(Secure Shell)是一种网络协议,用于在不安全网络上安全地传输数据。使用SSH可以实现远程登录和执行远程命令,并且还支持文件传输等功能。对于Golang开发者来说,使用SSH免密码是一种非常方便的方式,可以减少手动输入密码的繁琐。

生成SSH密钥

要使用SSH免密码登录,首先需要生成RSA密钥对。Golang的crypto/rsa包提供了便捷的方法来生成SSH密钥。通过调用GenerateKey函数,可以生成一个指定位数的RSA私钥。

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "encoding/pem"
    "os"
)

func generateSSHKey(bitSize int) error {
    privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)
    if err != nil {
        return err
    }

    privateKeyFile, err := os.Create("id_rsa")
    if err != nil {
        return err
    }
    defer privateKeyFile.Close()

    privateKeyPEM := &pem.Block{
        Type:  "RSA PRIVATE KEY",
        Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
    }

    pem.Encode(privateKeyFile, privateKeyPEM)

    return nil
}

配置SSH服务器

生成了SSH密钥后,接下来需要将公钥添加到SSH服务器上,以便允许免密码登录。通常情况下,SSH服务器会在家目录下的.ssh文件夹中保存已授权的用户公钥列表,文件名为authorized_keys。

在Golang中,可以使用os/user包来获取当前用户的家目录路径,然后将公钥追加到authorized_keys文件中。

import (
    "io/ioutil"
    "log"
    "os"
    "os/user"
    "path/filepath"
)

func configureSSHServer(publicKeyPath string) error {
    currentUser, err := user.Current()
    if err != nil {
        return err
    }

    sshDir := filepath.Join(currentUser.HomeDir, ".ssh")
    authorizedKeysPath := filepath.Join(sshDir, "authorized_keys")

    publicKey, err := ioutil.ReadFile(publicKeyPath)
    if err != nil {
        return err
    }

    publicKeyFile, err := os.OpenFile(authorizedKeysPath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
    if err != nil {
        return err
    }
    defer publicKeyFile.Close()

    if _, err := publicKeyFile.WriteString('\n'); err != nil {
        return err
    }

    if _, err := publicKeyFile.Write(publicKey); err != nil {
        return err
    }

    return nil
}

SSH免密码登录

配置好SSH服务器后,即可实现SSH免密码登录。Golang的golang.org/x/crypto/ssh包提供了用于SSH连接和身份验证的接口和函数。

通过调用Dial函数,可以建立一个SSH连接。在建立连接之前,我们需要创建一个客户端配置对象,并配置用户名、IP地址、认证方法等信息。

import (
    "golang.org/x/crypto/ssh"
    "log"
    "time"
)

func sshLogin(ip, username, privateKeyPath string) error {
    privateKey, err := ioutil.ReadFile(privateKeyPath)
    if err != nil {
        return err
    }

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

    config := &ssh.ClientConfig{
        User:            username,
        Auth:            []ssh.AuthMethod{ssh.PublicKeys(key)},
        Timeout:         5 * time.Second,
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }

    client, err := ssh.Dial("tcp", ip+":22", config)
    if err != nil {
        return err
    }
    defer client.Close()

    session, err := client.NewSession()
    if err != nil {
        return err
    }
    defer session.Close()

    // 执行远程命令或其他操作

    return nil
}

通过以上步骤,我们可以在Golang中实现SSH免密码登录。这使得远程命令执行和文件传输等操作变得更加便捷,并且可以避免在重复登录时输入密码的麻烦。

相关推荐