feat: 主机密码加密存储 (#1516)

This commit is contained in:
ssongliu 2023-07-03 16:48:14 +08:00 committed by GitHub
parent 695d4b4a16
commit 30bb64d058
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 643 additions and 811 deletions

View File

@ -7,7 +7,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/copier"
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
"github.com/gin-gonic/gin"
)
@ -36,7 +36,12 @@ func (b *BaseApi) CreateHost(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.Password = string(password)
passwordItem, err := encrypt.StringEncrypt(string(password))
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.Password = passwordItem
}
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
@ -44,7 +49,12 @@ func (b *BaseApi) CreateHost(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.PrivateKey = string(privateKey)
keyItem, err := encrypt.StringEncrypt(string(privateKey))
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.Password = keyItem
}
host, err := hostService.Create(req)
@ -148,33 +158,6 @@ func (b *BaseApi) SearchHost(c *gin.Context) {
})
}
// @Tags Host
// @Summary Load host info
// @Description 加载主机信息
// @Accept json
// @Param id path integer true "request"
// @Success 200 {object} dto.HostInfo
// @Security ApiKeyAuth
// @Router /hosts/:id [get]
func (b *BaseApi) GetHostInfo(c *gin.Context) {
id, err := helper.GetParamID(c)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
host, err := hostService.GetHostInfo(id)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
var hostDto dto.HostInfo
if err := copier.Copy(&hostDto, host); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, hostDto)
}
// @Tags Host
// @Summary Delete host
// @Description 删除主机
@ -227,7 +210,12 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.Password = string(password)
passwordItem, err := encrypt.StringEncrypt(string(password))
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.Password = passwordItem
}
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
@ -235,7 +223,12 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.PrivateKey = string(privateKey)
keyItem, err := encrypt.StringEncrypt(string(privateKey))
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.PrivateKey = keyItem
}
upMap := make(map[string]interface{})

View File

@ -7,6 +7,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
"github.com/1Panel-dev/1Panel/backend/utils/ssh"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
@ -89,7 +90,20 @@ func (u *HostService) TestLocalConn(id uint) bool {
if err := copier.Copy(&connInfo, &host); err != nil {
return false
}
connInfo.PrivateKey = []byte(host.PrivateKey)
if len(host.Password) != 0 {
host.Password, err = encrypt.StringDecrypt(host.Password)
if err != nil {
return false
}
connInfo.Password = host.Password
}
if len(host.PrivateKey) != 0 {
host.PrivateKey, err = encrypt.StringDecrypt(host.PrivateKey)
if err != nil {
return false
}
connInfo.PrivateKey = []byte(host.PrivateKey)
}
if len(host.PassPhrase) != 0 {
connInfo.PassPhrase = []byte(host.PassPhrase)
}
@ -107,6 +121,18 @@ func (u *HostService) GetHostInfo(id uint) (*model.Host, error) {
if err != nil {
return nil, constant.ErrRecordNotFound
}
if len(host.Password) != 0 {
host.Password, err = encrypt.StringDecrypt(host.Password)
if err != nil {
return nil, err
}
}
if len(host.PrivateKey) != 0 {
host.PrivateKey, err = encrypt.StringDecrypt(host.PrivateKey)
if err != nil {
return nil, err
}
}
return &host, err
}

View File

@ -34,6 +34,7 @@ func Init() {
migrations.AddBackupAccountDir,
migrations.AddMfaInterval,
migrations.UpdateAppDetail,
migrations.EncryptHostPassword,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)

View File

@ -426,3 +426,35 @@ var UpdateAppDetail = &gormigrate.Migration{
return nil
},
}
var EncryptHostPassword = &gormigrate.Migration{
ID: "20230703-encrypt-host-password",
Migrate: func(tx *gorm.DB) error {
var hosts []model.Host
if err := tx.Find(&hosts).Error; err != nil {
return err
}
for _, host := range hosts {
if len(host.Password) != 0 {
pass, err := encrypt.StringEncrypt(host.Password)
if err != nil {
return err
}
if err := tx.Model(&model.Host{}).Where("id = ?", host.ID).Update("password", pass).Error; err != nil {
return err
}
}
if len(host.PrivateKey) != 0 {
key, err := encrypt.StringEncrypt(host.PrivateKey)
if err != nil {
return err
}
if err := tx.Model(&model.Host{}).Update("private_key", key).Error; err != nil {
return err
}
}
}
return nil
},
}

View File

@ -24,7 +24,6 @@ func (s *HostRouter) InitHostRouter(Router *gin.RouterGroup) {
hostRouter.POST("/tree", baseApi.HostTree)
hostRouter.POST("/test/byinfo", baseApi.TestByInfo)
hostRouter.POST("/test/byid/:id", baseApi.TestByID)
hostRouter.GET(":id", baseApi.GetHostInfo)
hostRouter.GET("/firewall/base", baseApi.LoadFirewallBaseInfo)
hostRouter.POST("/firewall/search", baseApi.SearchFirewallRule)

View File

@ -34,6 +34,7 @@ func Start() {
log.Init()
app.Init()
db.Init()
hook.Init()
migration.Init()
validator.Init()
gob.Register(psession.SessionUser{})
@ -42,7 +43,6 @@ func Start() {
gin.SetMode("debug")
cron.Run()
business.Init()
hook.Init()
rootRouter := router.Routers()
address := fmt.Sprintf(":%s", global.CONF.System.Port)

View File

@ -8,6 +8,7 @@ import (
"crypto/rand"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"io"
@ -15,6 +16,9 @@ import (
)
func StringEncrypt(text string) (string, error) {
if len(text) == 0 {
return "", errors.New("it is not possible to encrypt an empty string.")
}
key := global.CONF.System.EncryptKey
pass := []byte(text)
xpass, err := aesEncryptWithSalt([]byte(key), pass)
@ -26,6 +30,9 @@ func StringEncrypt(text string) (string, error) {
}
func StringDecrypt(text string) (string, error) {
if len(text) == 0 {
return "", errors.New("it is not possible to decrypt an empty string.")
}
key := global.CONF.System.EncryptKey
bytesPass, err := base64.StdEncoding.DecodeString(text)
if err != nil {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -11,9 +11,6 @@ export const searchHosts = (params: Host.SearchWithPage) => {
export const getHostTree = (params: Host.ReqSearch) => {
return http.post<Array<Host.HostTree>>(`/hosts/tree`, params);
};
export const getHostInfo = (id: number) => {
return http.get<Host.Host>(`/hosts/` + id);
};
export const addHost = (params: Host.HostOperate) => {
let reqest = deepCopy(params) as Host.HostOperate;
if (reqest.password) {