简介
在Linux服务器上远程工具基本都是SSH,自动化实现的时候的,可以利用sshd直接进行部署,就不需要安装另外的agent。使用Python的时候,有ansible框架可以很快的实现。
使用Go也可以很快的实现一些SSH的功能。
拷贝文件就是一个比较常用的功能。
![c9ccf7edcf02fcdf7ddc9793aa26333b.png](https://i-blog.csdnimg.cn/blog_migrate/38fbff3ecbc7013be19ca3351d511ed1.jpeg)
实现
这里使用官方的ssh结合sftp这个包来实现scp的功能。
package sshimport ( "errors" "fmt" "io/ioutil" "net" "os" "time" "github.com/pkg/sftp" "golang.org/x/crypto/ssh")// SftpClient sftp客户端type SftpClient struct { Session *sftp.Client}// NewSessionWithPassword 使用密码登录func NewSessionWithPassword(host string, port int, user, password string) (sftpClient *SftpClient, err error) { sftpClient, err = NewSession(host, port, user, ssh.Password(password)) return}// NewSessionWithKey 通过key登录sftpfunc NewSessionWithKey(host string, port int, user, keyPath, keyPassword string) (sftpClient *SftpClient, err error) { fmt.Println(keyPath) keyData, err := ioutil.ReadFile(keyPath) if err != nil { return } fmt.Println(string(keyData)) var singer ssh.Signer if keyPassword == "" { singer, err = ssh.ParsePrivateKey(keyData) } else { singer, err = ssh.ParsePrivateKeyWithPassphrase(keyData, []byte(keyPassword)) } if err != nil { return } sftpClient, err = NewSession(host, port, user, ssh.PublicKeys(singer)) return}// NewSession 开启一个会话func NewSession(host string, port int, user string, authMehtods ...ssh.AuthMethod) (sftpClient *SftpClient, err error) { clientConfig := &ssh.ClientConfig{ User: user, Auth: authMehtods, Timeout: 4 * time.Second, HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil }, } sshClient, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", host, port), clientConfig) if err != nil { return nil, err } sftpClient = &SftpClient{} sftpClient.Session, err = sftp.NewClient(sshClient) if err != nil { return nil, err } return}// ScopyRmoteFile 拷贝远程文件func (sftpClient *SftpClient) ScopyRmoteFile(remoteFilePath, localFilePath string) (err error) { srcFile, err := sftpClient.Session.Open(remoteFilePath) if err != nil { return } defer srcFile.Close() dstFile, err := os.Create(localFilePath) if err != nil { return } defer dstFile.Close() if _, err = srcFile.WriteTo(dstFile); err != nil { return } return}// SendFile 发送文件到远程func (sftpClient *SftpClient) SendFile(localFilePath, remoteFilePath string) (err error) { srcFile, err := os.Open(localFilePath) if err != nil { return } defer srcFile.Close() dstFile, err := sftpClient.Session.Create(localFilePath) if err != nil { return } defer dstFile.Close() buf := make([]byte, 1024) for { n, _ := srcFile.Read(buf) if n == 0 { break } dstFile.Write(buf) } return}// Close close sessionfunc (sftpClient *SftpClient) Close() (err error) { err = sftpClient.Session.Close() return}
![c8c737b1db47f65aee4919b884cdc89c.png](https://i-blog.csdnimg.cn/blog_migrate/8fe2f70e4b19fa78f8c7356592452ed2.jpeg)
使用
package mainimport ( "mygolang/ssh")func main(){ sftpClient , err := NewSessionWithPassword("192.168.100.100",22,"root","opcai@2019") if err !=nil{ panic(err) } defer sftpClient.Close() err = sftpClient.ScopyRemoteFile("/data/remotefile","/data/localfile") if err !=nil{ panic(err) }}
总结
在做运维开发的时候,使用Golang开发还是比较快速的。
![69a209991bdb90e470aa2e7082ff550d.png](https://i-blog.csdnimg.cn/blog_migrate/c9174aeeef9a4de5e5a35117043bb9a4.jpeg)