feat: ssh生成本地RSA,支持本地直连授权配置
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/cmd"
|
||||
gossh "golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
@@ -96,20 +97,11 @@ func (c *ConnSSH) Close() {
|
||||
func (c *ConnSSH) NewClientByLocalPrivate() (*ConnSSH, error) {
|
||||
c.Port = 22
|
||||
c.AuthMode = "1"
|
||||
usr, err := user.Current()
|
||||
privateKey, err := c.CurrentUserRsaKey(false)
|
||||
if err != nil {
|
||||
logger.Errorf("NewClientByLocal get current user => %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 读取用户默认的私钥文件
|
||||
keyPath := fmt.Sprintf("%s/.ssh/id_rsa", usr.HomeDir)
|
||||
key, err := os.ReadFile(keyPath)
|
||||
if err != nil {
|
||||
logger.Errorf("NewClientByLocal [%s] read private key => %s", usr.Username, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
c.PrivateKey = string(key)
|
||||
c.PrivateKey = privateKey
|
||||
return c.NewClient()
|
||||
}
|
||||
|
||||
@@ -134,7 +126,55 @@ func (c *ConnSSH) RunCMD(cmd string) (string, error) {
|
||||
return c.LastResult, err
|
||||
}
|
||||
|
||||
// NewClient 创建SSH客户端会话对象
|
||||
// SendToAuthorizedKeys 发送当前用户私钥到远程服务器进行授权密钥
|
||||
func (c *ConnSSH) SendToAuthorizedKeys() error {
|
||||
publicKey, err := c.CurrentUserRsaKey(true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
authorizedKeysEntry := fmt.Sprintln(strings.TrimSpace(publicKey))
|
||||
cmdStr := "echo '" + authorizedKeysEntry + "' >> ~/.ssh/authorized_keys"
|
||||
_, err = c.RunCMD(cmdStr)
|
||||
if err != nil {
|
||||
logger.Errorf("SendAuthorizedKeys echo err %s", err.Error())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CurrentUserRsaKey 当前用户OMC使用的RSA私钥
|
||||
// 默认读取私钥
|
||||
// ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
|
||||
// ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub
|
||||
func (c *ConnSSH) CurrentUserRsaKey(publicKey bool) (string, error) {
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
logger.Errorf("CurrentUserRsaKey get => %s", err.Error())
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 是否存在私钥并创建
|
||||
keyPath := fmt.Sprintf("%s/.ssh/id_rsa", usr.HomeDir)
|
||||
if _, err := os.Stat(keyPath); err != nil {
|
||||
_, err2 := cmd.ExecWithCheck("ssh-keygen", "-t", "rsa", "-P", "", "-f", keyPath)
|
||||
if err2 != nil {
|
||||
logger.Errorf("CurrentUserPrivateKey ssh-keygen [%s] rsa => %s", usr.Username, err2.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// 读取用户默认的文件
|
||||
if publicKey {
|
||||
keyPath = keyPath + ".pub"
|
||||
}
|
||||
key, err := os.ReadFile(keyPath)
|
||||
if err != nil {
|
||||
logger.Errorf("CurrentUserRsaKey [%s] read => %s", usr.Username, err.Error())
|
||||
return "", fmt.Errorf("read file %s fail", keyPath)
|
||||
}
|
||||
return string(key), nil
|
||||
}
|
||||
|
||||
// NewClientSession 创建SSH客户端会话对象
|
||||
func (c *ConnSSH) NewClientSession(cols, rows int) (*SSHClientSession, error) {
|
||||
sshSession, err := c.Client.NewSession()
|
||||
if err != nil {
|
||||
|
||||
@@ -354,3 +354,53 @@ func (s *NeHostController) CheckBySSH(c *gin.Context) {
|
||||
|
||||
c.JSON(200, result.OkData(data))
|
||||
}
|
||||
|
||||
// 网元主机SSH方式授权免密发送
|
||||
//
|
||||
// POST /authorizedBySSH
|
||||
func (s *NeHostController) AuthorizedBySSH(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body model.NeHost
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 本地免密创建链接直连
|
||||
sshLink := false
|
||||
lcoalConnSSH := ssh.ConnSSH{
|
||||
User: body.User,
|
||||
Addr: body.Addr,
|
||||
Port: body.Port,
|
||||
}
|
||||
lcoalClient, err := lcoalConnSSH.NewClientByLocalPrivate()
|
||||
if err == nil {
|
||||
sshLink = true
|
||||
}
|
||||
defer lcoalClient.Close()
|
||||
if sshLink {
|
||||
// 连接主机成功,无需重复免密授权认证
|
||||
c.JSON(200, result.OkMsg(i18n.TKey(language, "neHost.okBySSHLink")))
|
||||
return
|
||||
}
|
||||
|
||||
// 创建链接SSH客户端
|
||||
var connSSH ssh.ConnSSH
|
||||
body.CopyTo(&connSSH)
|
||||
client, err := connSSH.NewClient()
|
||||
if err != nil {
|
||||
// 连接主机失败,请检查连接参数后重试
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.errByHostInfo")))
|
||||
return
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
// 发送密钥
|
||||
err = client.SendToAuthorizedKeys()
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user