mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
feat: 主机密码加密存储 (#1516)
This commit is contained in:
parent
695d4b4a16
commit
30bb64d058
@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"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"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,7 +36,12 @@ func (b *BaseApi) CreateHost(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
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 {
|
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
|
||||||
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
|
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)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
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)
|
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
|
// @Tags Host
|
||||||
// @Summary Delete host
|
// @Summary Delete host
|
||||||
// @Description 删除主机
|
// @Description 删除主机
|
||||||
@ -227,7 +210,12 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
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 {
|
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
|
||||||
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
|
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)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
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{})
|
upMap := make(map[string]interface{})
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"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/1Panel-dev/1Panel/backend/utils/ssh"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -89,7 +90,20 @@ func (u *HostService) TestLocalConn(id uint) bool {
|
|||||||
if err := copier.Copy(&connInfo, &host); err != nil {
|
if err := copier.Copy(&connInfo, &host); err != nil {
|
||||||
return false
|
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 {
|
if len(host.PassPhrase) != 0 {
|
||||||
connInfo.PassPhrase = []byte(host.PassPhrase)
|
connInfo.PassPhrase = []byte(host.PassPhrase)
|
||||||
}
|
}
|
||||||
@ -107,6 +121,18 @@ func (u *HostService) GetHostInfo(id uint) (*model.Host, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, constant.ErrRecordNotFound
|
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
|
return &host, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ func Init() {
|
|||||||
migrations.AddBackupAccountDir,
|
migrations.AddBackupAccountDir,
|
||||||
migrations.AddMfaInterval,
|
migrations.AddMfaInterval,
|
||||||
migrations.UpdateAppDetail,
|
migrations.UpdateAppDetail,
|
||||||
|
migrations.EncryptHostPassword,
|
||||||
})
|
})
|
||||||
if err := m.Migrate(); err != nil {
|
if err := m.Migrate(); err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
|
@ -426,3 +426,35 @@ var UpdateAppDetail = &gormigrate.Migration{
|
|||||||
return nil
|
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
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -24,7 +24,6 @@ func (s *HostRouter) InitHostRouter(Router *gin.RouterGroup) {
|
|||||||
hostRouter.POST("/tree", baseApi.HostTree)
|
hostRouter.POST("/tree", baseApi.HostTree)
|
||||||
hostRouter.POST("/test/byinfo", baseApi.TestByInfo)
|
hostRouter.POST("/test/byinfo", baseApi.TestByInfo)
|
||||||
hostRouter.POST("/test/byid/:id", baseApi.TestByID)
|
hostRouter.POST("/test/byid/:id", baseApi.TestByID)
|
||||||
hostRouter.GET(":id", baseApi.GetHostInfo)
|
|
||||||
|
|
||||||
hostRouter.GET("/firewall/base", baseApi.LoadFirewallBaseInfo)
|
hostRouter.GET("/firewall/base", baseApi.LoadFirewallBaseInfo)
|
||||||
hostRouter.POST("/firewall/search", baseApi.SearchFirewallRule)
|
hostRouter.POST("/firewall/search", baseApi.SearchFirewallRule)
|
||||||
|
@ -34,6 +34,7 @@ func Start() {
|
|||||||
log.Init()
|
log.Init()
|
||||||
app.Init()
|
app.Init()
|
||||||
db.Init()
|
db.Init()
|
||||||
|
hook.Init()
|
||||||
migration.Init()
|
migration.Init()
|
||||||
validator.Init()
|
validator.Init()
|
||||||
gob.Register(psession.SessionUser{})
|
gob.Register(psession.SessionUser{})
|
||||||
@ -42,7 +43,6 @@ func Start() {
|
|||||||
gin.SetMode("debug")
|
gin.SetMode("debug")
|
||||||
cron.Run()
|
cron.Run()
|
||||||
business.Init()
|
business.Init()
|
||||||
hook.Init()
|
|
||||||
|
|
||||||
rootRouter := router.Routers()
|
rootRouter := router.Routers()
|
||||||
address := fmt.Sprintf(":%s", global.CONF.System.Port)
|
address := fmt.Sprintf(":%s", global.CONF.System.Port)
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
@ -15,6 +16,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func StringEncrypt(text string) (string, error) {
|
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
|
key := global.CONF.System.EncryptKey
|
||||||
pass := []byte(text)
|
pass := []byte(text)
|
||||||
xpass, err := aesEncryptWithSalt([]byte(key), pass)
|
xpass, err := aesEncryptWithSalt([]byte(key), pass)
|
||||||
@ -26,6 +30,9 @@ func StringEncrypt(text string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StringDecrypt(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
|
key := global.CONF.System.EncryptKey
|
||||||
bytesPass, err := base64.StdEncoding.DecodeString(text)
|
bytesPass, err := base64.StdEncoding.DecodeString(text)
|
||||||
if err != nil {
|
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
@ -11,9 +11,6 @@ export const searchHosts = (params: Host.SearchWithPage) => {
|
|||||||
export const getHostTree = (params: Host.ReqSearch) => {
|
export const getHostTree = (params: Host.ReqSearch) => {
|
||||||
return http.post<Array<Host.HostTree>>(`/hosts/tree`, params);
|
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) => {
|
export const addHost = (params: Host.HostOperate) => {
|
||||||
let reqest = deepCopy(params) as Host.HostOperate;
|
let reqest = deepCopy(params) as Host.HostOperate;
|
||||||
if (reqest.password) {
|
if (reqest.password) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user