mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-27 12:39:01 +08:00
feat(system-security): Support Hot Reloading of System Certificates (#7152)
Refs https://github.com/1Panel-dev/1Panel/issues/7129
This commit is contained in:
parent
7fdb0a5078
commit
c3565f72c4
@ -381,6 +381,9 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) (*model.Website
|
|||||||
logger.Println(i18n.GetMsgByKey("ExecShellSuccess"))
|
logger.Println(i18n.GetMsgByKey("ExecShellSuccess"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reloadSystemSSL(websiteSSL, logger)
|
||||||
|
|
||||||
return websiteSSL, nil
|
return websiteSSL, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package service
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto"
|
"crypto"
|
||||||
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -188,6 +189,31 @@ func printSSLLog(logger *log.Logger, msgKey string, params map[string]interface{
|
|||||||
logger.Println(i18n.GetMsgWithMap(msgKey, params))
|
logger.Println(i18n.GetMsgWithMap(msgKey, params))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func reloadSystemSSL(websiteSSL *model.WebsiteSSL, logger *log.Logger) {
|
||||||
|
systemSSLEnable, sslID := GetSystemSSL()
|
||||||
|
if systemSSLEnable && sslID == websiteSSL.ID {
|
||||||
|
fileOp := files.NewFileOp()
|
||||||
|
certPath := path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt")
|
||||||
|
keyPath := path.Join(global.CONF.System.BaseDir, "1panel/secret/server.key")
|
||||||
|
printSSLLog(logger, "StartUpdateSystemSSL", nil, logger == nil)
|
||||||
|
if err := fileOp.WriteFile(certPath, strings.NewReader(websiteSSL.Pem), 0600); err != nil {
|
||||||
|
logger.Printf("Failed to update the SSL certificate File for 1Panel System domain [%s] , err:%s", websiteSSL.PrimaryDomain, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := fileOp.WriteFile(keyPath, strings.NewReader(websiteSSL.PrivateKey), 0600); err != nil {
|
||||||
|
logger.Printf("Failed to update the SSL certificate for 1Panel System domain [%s] , err:%s", websiteSSL.PrimaryDomain, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
newCert, err := tls.X509KeyPair([]byte(websiteSSL.Pem), []byte(websiteSSL.PrivateKey))
|
||||||
|
if err != nil {
|
||||||
|
logger.Printf("Failed to update the SSL certificate for 1Panel System domain [%s] , err:%s", websiteSSL.PrimaryDomain, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
printSSLLog(logger, "UpdateSystemSSLSuccess", nil, logger == nil)
|
||||||
|
constant.CertStore.Store(&newCert)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w WebsiteSSLService) ObtainSSL(apply request.WebsiteSSLApply) error {
|
func (w WebsiteSSLService) ObtainSSL(apply request.WebsiteSSLApply) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
@ -344,6 +370,8 @@ func (w WebsiteSSLService) ObtainSSL(apply request.WebsiteSSLApply) error {
|
|||||||
}
|
}
|
||||||
printSSLLog(logger, "ApplyWebSiteSSLSuccess", nil, apply.DisableLog)
|
printSSLLog(logger, "ApplyWebSiteSSLSuccess", nil, apply.DisableLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reloadSystemSSL(websiteSSL, logger)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -1002,23 +1002,22 @@ func saveCertificateFile(websiteSSL *model.WebsiteSSL, logger *log.Logger) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSystemSSL() (bool, bool, uint) {
|
func GetSystemSSL() (bool, uint) {
|
||||||
sslSetting, err := settingRepo.Get(settingRepo.WithByKey("SSL"))
|
sslSetting, err := settingRepo.Get(settingRepo.WithByKey("SSL"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
global.LOG.Errorf("load service ssl from setting failed, err: %v", err)
|
global.LOG.Errorf("load service ssl from setting failed, err: %v", err)
|
||||||
return false, false, 0
|
return false, 0
|
||||||
}
|
}
|
||||||
if sslSetting.Value == "enable" {
|
if sslSetting.Value == "enable" {
|
||||||
sslID, _ := settingRepo.Get(settingRepo.WithByKey("SSLID"))
|
sslID, _ := settingRepo.Get(settingRepo.WithByKey("SSLID"))
|
||||||
idValue, _ := strconv.Atoi(sslID.Value)
|
idValue, _ := strconv.Atoi(sslID.Value)
|
||||||
if idValue <= 0 {
|
if idValue <= 0 {
|
||||||
return false, false, 0
|
return false, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
auto, _ := settingRepo.Get(settingRepo.WithByKey("AutoRestart"))
|
return true, uint(idValue)
|
||||||
return true, auto.Value == "enable", uint(idValue)
|
|
||||||
}
|
}
|
||||||
return false, false, 0
|
return false, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateSSLConfig(websiteSSL model.WebsiteSSL) error {
|
func UpdateSSLConfig(websiteSSL model.WebsiteSSL) error {
|
||||||
@ -1037,22 +1036,7 @@ func UpdateSSLConfig(websiteSSL model.WebsiteSSL) error {
|
|||||||
return buserr.WithErr(constant.ErrSSLApply, err)
|
return buserr.WithErr(constant.ErrSSLApply, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enable, auto, sslID := GetSystemSSL()
|
reloadSystemSSL(&websiteSSL, nil)
|
||||||
if enable && sslID == websiteSSL.ID {
|
|
||||||
fileOp := files.NewFileOp()
|
|
||||||
secretDir := path.Join(global.CONF.System.BaseDir, "1panel/secret")
|
|
||||||
if err := fileOp.WriteFile(path.Join(secretDir, "server.crt"), strings.NewReader(websiteSSL.Pem), 0600); err != nil {
|
|
||||||
global.LOG.Errorf("Failed to update the SSL certificate File for 1Panel System domain [%s] , err:%s", websiteSSL.PrimaryDomain, err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := fileOp.WriteFile(path.Join(secretDir, "server.key"), strings.NewReader(websiteSSL.PrivateKey), 0600); err != nil {
|
|
||||||
global.LOG.Errorf("Failed to update the SSL certificate for 1Panel System domain [%s] , err:%s", websiteSSL.PrimaryDomain, err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if auto {
|
|
||||||
_, _ = cmd.Exec("systemctl restart 1panel.service")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package constant
|
package constant
|
||||||
|
|
||||||
|
import "sync/atomic"
|
||||||
|
|
||||||
type DBContext string
|
type DBContext string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -123,3 +125,5 @@ var DynamicRoutes = []string{
|
|||||||
`^/databases/postgresql/setting/[^/]+/[^/]+$`,
|
`^/databases/postgresql/setting/[^/]+/[^/]+$`,
|
||||||
`^/websites/[^/]+/config/[^/]+$`,
|
`^/websites/[^/]+/config/[^/]+$`,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var CertStore atomic.Value
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package job
|
package job
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||||
@ -10,9 +8,7 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/app/service"
|
"github.com/1Panel-dev/1Panel/backend/app/service"
|
||||||
"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/cmd"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ssl struct {
|
type ssl struct {
|
||||||
@ -23,7 +19,6 @@ func NewSSLJob() *ssl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ssl *ssl) Run() {
|
func (ssl *ssl) Run() {
|
||||||
systemSSLEnable, auto, sslID := service.GetSystemSSL()
|
|
||||||
sslRepo := repo.NewISSLRepo()
|
sslRepo := repo.NewISSLRepo()
|
||||||
sslService := service.NewIWebsiteSSLService()
|
sslService := service.NewIWebsiteSSLService()
|
||||||
sslList, _ := sslRepo.List()
|
sslList, _ := sslRepo.List()
|
||||||
@ -59,22 +54,6 @@ func (ssl *ssl) Run() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if systemSSLEnable && sslID == s.ID {
|
|
||||||
websiteSSL, _ := sslRepo.GetFirst(repo.NewCommonRepo().WithByID(s.ID))
|
|
||||||
fileOp := files.NewFileOp()
|
|
||||||
secretDir := path.Join(global.CONF.System.BaseDir, "1panel/secret")
|
|
||||||
if err := fileOp.WriteFile(path.Join(secretDir, "server.crt"), strings.NewReader(websiteSSL.Pem), 0600); err != nil {
|
|
||||||
global.LOG.Errorf("Failed to update the SSL certificate File for 1Panel System domain [%s] , err:%s", s.PrimaryDomain, err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := fileOp.WriteFile(path.Join(secretDir, "server.key"), strings.NewReader(websiteSSL.PrivateKey), 0600); err != nil {
|
|
||||||
global.LOG.Errorf("Failed to update the SSL certificate for 1Panel System domain [%s] , err:%s", s.PrimaryDomain, err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if auto {
|
|
||||||
_, _ = cmd.Exec("systemctl restart 1panel.service")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
global.LOG.Infof("The SSL certificate for the [%s] domain has been successfully updated", s.PrimaryDomain)
|
global.LOG.Infof("The SSL certificate for the [%s] domain has been successfully updated", s.PrimaryDomain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,8 @@ ErrDefaultCA: "The default organization cannot be deleted"
|
|||||||
ApplyWebSiteSSLLog: "Start updating {{ .name }} website certificate"
|
ApplyWebSiteSSLLog: "Start updating {{ .name }} website certificate"
|
||||||
ErrUpdateWebsiteSSL: "{{ .name }} website failed to update certificate: {{ .err }}"
|
ErrUpdateWebsiteSSL: "{{ .name }} website failed to update certificate: {{ .err }}"
|
||||||
ApplyWebSiteSSLSuccess: "Update website certificate successfully"
|
ApplyWebSiteSSLSuccess: "Update website certificate successfully"
|
||||||
|
StartUpdateSystemSSL: "Start updating system certificate"
|
||||||
|
UpdateSystemSSLSuccess: "Update system certificate successfully"
|
||||||
|
|
||||||
#mysql
|
#mysql
|
||||||
ErrUserIsExist: "The current user already exists. Please enter a new user"
|
ErrUserIsExist: "The current user already exists. Please enter a new user"
|
||||||
|
@ -126,6 +126,8 @@ ErrDefaultCA: "默認機構不能刪除"
|
|||||||
ApplyWebSiteSSLLog: "開始更新 {{ .name }} 網站憑證"
|
ApplyWebSiteSSLLog: "開始更新 {{ .name }} 網站憑證"
|
||||||
ErrUpdateWebsiteSSL: "{{ .name }} 網站更新憑證失敗: {{ .err }}"
|
ErrUpdateWebsiteSSL: "{{ .name }} 網站更新憑證失敗: {{ .err }}"
|
||||||
ApplyWebSiteSSLSuccess: "更新網站憑證成功"
|
ApplyWebSiteSSLSuccess: "更新網站憑證成功"
|
||||||
|
StartUpdateSystemSSL: "開始更新系統證書"
|
||||||
|
UpdateSystemSSLSuccess: "更新系統證書成功"
|
||||||
|
|
||||||
|
|
||||||
#mysql
|
#mysql
|
||||||
|
@ -130,6 +130,8 @@ ApplyWebSiteSSLSuccess: "更新网站证书成功"
|
|||||||
ErrExecShell: "执行脚本失败 {{ .err }}"
|
ErrExecShell: "执行脚本失败 {{ .err }}"
|
||||||
ExecShellStart: "开始执行脚本"
|
ExecShellStart: "开始执行脚本"
|
||||||
ExecShellSuccess: "脚本执行成功"
|
ExecShellSuccess: "脚本执行成功"
|
||||||
|
StartUpdateSystemSSL: "开始更新系统证书"
|
||||||
|
UpdateSystemSSLSuccess: "更新系统证书成功"
|
||||||
|
|
||||||
#mysql
|
#mysql
|
||||||
ErrUserIsExist: "当前用户已存在,请重新输入"
|
ErrUserIsExist: "当前用户已存在,请重新输入"
|
||||||
|
@ -4,13 +4,13 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/i18n"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/i18n"
|
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/init/app"
|
"github.com/1Panel-dev/1Panel/backend/init/app"
|
||||||
"github.com/1Panel-dev/1Panel/backend/init/business"
|
"github.com/1Panel-dev/1Panel/backend/init/business"
|
||||||
|
|
||||||
@ -81,12 +81,16 @@ func Start() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
constant.CertStore.Store(&cert)
|
||||||
|
|
||||||
server.TLSConfig = &tls.Config{
|
server.TLSConfig = &tls.Config{
|
||||||
Certificates: []tls.Certificate{cert},
|
GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||||
|
return constant.CertStore.Load().(*tls.Certificate), nil
|
||||||
|
},
|
||||||
}
|
}
|
||||||
global.LOG.Infof("listen at https://%s:%s [%s]", global.CONF.System.BindAddress, global.CONF.System.Port, tcpItem)
|
global.LOG.Infof("listen at https://%s:%s [%s]", global.CONF.System.BindAddress, global.CONF.System.Port, tcpItem)
|
||||||
|
|
||||||
if err := server.ServeTLS(tcpKeepAliveListener{ln.(*net.TCPListener)}, certPath, keyPath); err != nil {
|
if err := server.ServeTLS(tcpKeepAliveListener{ln.(*net.TCPListener)}, "", ""); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -29,7 +29,6 @@ export namespace Setting {
|
|||||||
bindAddress: string;
|
bindAddress: string;
|
||||||
ssl: string;
|
ssl: string;
|
||||||
sslType: string;
|
sslType: string;
|
||||||
autoRestart: string;
|
|
||||||
allowIPs: string;
|
allowIPs: string;
|
||||||
bindDomain: string;
|
bindDomain: string;
|
||||||
securityEntrance: string;
|
securityEntrance: string;
|
||||||
|
@ -1551,11 +1551,6 @@ const message = {
|
|||||||
bindDomain: 'Bind Domain',
|
bindDomain: 'Bind Domain',
|
||||||
unBindDomain: 'Unbind domain',
|
unBindDomain: 'Unbind domain',
|
||||||
panelSSL: 'Panel SSL',
|
panelSSL: 'Panel SSL',
|
||||||
sslAutoRestart: 'Restart 1Panel service after certificate auto-renewal',
|
|
||||||
sslChangeHelper1:
|
|
||||||
'Currently, automatic restart of 1Panel service is not selected. The certificate auto-renewal will not take effect immediately and will still require a manual restart of 1Panel.',
|
|
||||||
sslChangeHelper2:
|
|
||||||
'The 1Panel service will automatically restart after setting the panel SSL. Do you want to continue?',
|
|
||||||
unBindDomainHelper:
|
unBindDomainHelper:
|
||||||
'The action of unbinding a domain name may cause system insecurity. Do you want to continue?',
|
'The action of unbinding a domain name may cause system insecurity. Do you want to continue?',
|
||||||
bindDomainHelper:
|
bindDomainHelper:
|
||||||
|
@ -1494,9 +1494,6 @@ const message = {
|
|||||||
bindDomain: '域名綁定',
|
bindDomain: '域名綁定',
|
||||||
unBindDomain: '域名解綁',
|
unBindDomain: '域名解綁',
|
||||||
panelSSL: '面板 SSL',
|
panelSSL: '面板 SSL',
|
||||||
sslAutoRestart: '證書自動續期後重啟 1Panel 服務',
|
|
||||||
sslChangeHelper1: '當前未勾選自動重啟 1Panel 服務,證書自動續期後不會立即生效,仍需手動重啟 1Panel。',
|
|
||||||
sslChangeHelper2: '設置面板 SSL 後將自動重啟 1Panel 服務,是否繼續?',
|
|
||||||
unBindDomainHelper: '解除域名綁定可能造成系統不安全,是否繼續?',
|
unBindDomainHelper: '解除域名綁定可能造成系統不安全,是否繼續?',
|
||||||
bindDomainHelper: '設置域名綁定後,僅能通過設置中域名訪問 1Panel 服務',
|
bindDomainHelper: '設置域名綁定後,僅能通過設置中域名訪問 1Panel 服務',
|
||||||
bindDomainHelper1: '綁定域名為空時,則取消域名綁定',
|
bindDomainHelper1: '綁定域名為空時,則取消域名綁定',
|
||||||
|
@ -1496,9 +1496,6 @@ const message = {
|
|||||||
bindDomain: '域名绑定',
|
bindDomain: '域名绑定',
|
||||||
unBindDomain: '域名解绑',
|
unBindDomain: '域名解绑',
|
||||||
panelSSL: '面板 SSL',
|
panelSSL: '面板 SSL',
|
||||||
sslAutoRestart: '证书自动续期后重启 1Panel 服务',
|
|
||||||
sslChangeHelper1: '当前未勾选自动重启 1Panel 服务,证书自动续期后不会立即生效,仍需手动重启 1Panel。',
|
|
||||||
sslChangeHelper2: '设置面板 SSL 后将自动重启 1Panel 服务,是否继续?',
|
|
||||||
unBindDomainHelper: '解除域名绑定可能造成系统不安全,是否继续?',
|
unBindDomainHelper: '解除域名绑定可能造成系统不安全,是否继续?',
|
||||||
bindDomainHelper: '设置域名绑定后,仅能通过设置中域名访问 1Panel 服务',
|
bindDomainHelper: '设置域名绑定后,仅能通过设置中域名访问 1Panel 服务',
|
||||||
bindDomainHelper1: '绑定域名为空时,则取消域名绑定',
|
bindDomainHelper1: '绑定域名为空时,则取消域名绑定',
|
||||||
|
@ -34,7 +34,7 @@ const settingRouter = {
|
|||||||
hidden: true,
|
hidden: true,
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
activeMenu: 'Setting',
|
activeMenu: '/settings',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -44,7 +44,7 @@ const settingRouter = {
|
|||||||
hidden: true,
|
hidden: true,
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
activeMenu: 'Setting',
|
activeMenu: '/settings',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -54,7 +54,7 @@ const settingRouter = {
|
|||||||
hidden: true,
|
hidden: true,
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
activeMenu: 'Setting',
|
activeMenu: '/settings',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -64,7 +64,7 @@ const settingRouter = {
|
|||||||
hidden: true,
|
hidden: true,
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
activeMenu: 'Setting',
|
activeMenu: '/settings',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -74,7 +74,7 @@ const settingRouter = {
|
|||||||
component: () => import('@/views/setting/snapshot/index.vue'),
|
component: () => import('@/views/setting/snapshot/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
activeMenu: 'Setting',
|
activeMenu: '/settings',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -84,7 +84,7 @@ const settingRouter = {
|
|||||||
component: () => import('@/views/setting/expired.vue'),
|
component: () => import('@/views/setting/expired.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
activeMenu: 'Expired',
|
activeMenu: '/settings',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -225,7 +225,6 @@ const form = reactive({
|
|||||||
bindAddress: '',
|
bindAddress: '',
|
||||||
ssl: 'disable',
|
ssl: 'disable',
|
||||||
sslType: 'self',
|
sslType: 'self',
|
||||||
autoRestart: 'disable',
|
|
||||||
securityEntrance: '',
|
securityEntrance: '',
|
||||||
expirationDays: 0,
|
expirationDays: 0,
|
||||||
expirationTime: '',
|
expirationTime: '',
|
||||||
@ -250,7 +249,6 @@ const search = async () => {
|
|||||||
if (form.ssl === 'enable') {
|
if (form.ssl === 'enable') {
|
||||||
loadInfo();
|
loadInfo();
|
||||||
}
|
}
|
||||||
form.autoRestart = res.data.autoRestart;
|
|
||||||
form.securityEntrance = res.data.securityEntrance;
|
form.securityEntrance = res.data.securityEntrance;
|
||||||
form.expirationDays = Number(res.data.expirationDays);
|
form.expirationDays = Number(res.data.expirationDays);
|
||||||
form.expirationTime = res.data.expirationTime;
|
form.expirationTime = res.data.expirationTime;
|
||||||
@ -330,7 +328,6 @@ const handleSSL = async () => {
|
|||||||
ssl: form.ssl,
|
ssl: form.ssl,
|
||||||
sslType: form.sslType,
|
sslType: form.sslType,
|
||||||
sslInfo: sslInfo.value,
|
sslInfo: sslInfo.value,
|
||||||
autoRestart: form.autoRestart,
|
|
||||||
};
|
};
|
||||||
sslRef.value!.acceptParams(params);
|
sslRef.value!.acceptParams(params);
|
||||||
return;
|
return;
|
||||||
|
@ -112,14 +112,6 @@
|
|||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
<el-form-item v-if="form.sslType !== 'import'">
|
|
||||||
<el-checkbox true-value="enable" false-value="disable" v-model="form.autoRestart">
|
|
||||||
{{ $t('setting.sslAutoRestart') }}
|
|
||||||
</el-checkbox>
|
|
||||||
<span v-if="form.autoRestart === 'disable'" class="input-help">
|
|
||||||
{{ $t('setting.sslChangeHelper1') }}
|
|
||||||
</span>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -143,7 +135,7 @@ import i18n from '@/lang';
|
|||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
import { downloadSSL, updateSSL } from '@/api/modules/setting';
|
import { downloadSSL, updateSSL } from '@/api/modules/setting';
|
||||||
import { Rules } from '@/global/form-rules';
|
import { Rules } from '@/global/form-rules';
|
||||||
import { ElMessageBox, FormInstance } from 'element-plus';
|
import { FormInstance } from 'element-plus';
|
||||||
import { Setting } from '@/api/interface/setting';
|
import { Setting } from '@/api/interface/setting';
|
||||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||||
import { GlobalStore } from '@/store';
|
import { GlobalStore } from '@/store';
|
||||||
@ -162,7 +154,6 @@ const form = reactive({
|
|||||||
key: '',
|
key: '',
|
||||||
rootPath: '',
|
rootPath: '',
|
||||||
timeout: '',
|
timeout: '',
|
||||||
autoRestart: 'disable',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const rules = reactive({
|
const rules = reactive({
|
||||||
@ -179,7 +170,6 @@ const itemSSL = ref();
|
|||||||
interface DialogProps {
|
interface DialogProps {
|
||||||
sslType: string;
|
sslType: string;
|
||||||
sslInfo?: Setting.SSLInfo;
|
sslInfo?: Setting.SSLInfo;
|
||||||
autoRestart: string;
|
|
||||||
}
|
}
|
||||||
const acceptParams = async (params: DialogProps): Promise<void> => {
|
const acceptParams = async (params: DialogProps): Promise<void> => {
|
||||||
if (params.sslType.indexOf('-') !== -1) {
|
if (params.sslType.indexOf('-') !== -1) {
|
||||||
@ -202,7 +192,6 @@ const acceptParams = async (params: DialogProps): Promise<void> => {
|
|||||||
} else {
|
} else {
|
||||||
loadSSLs();
|
loadSSLs();
|
||||||
}
|
}
|
||||||
form.autoRestart = params.autoRestart;
|
|
||||||
drawerVisible.value = true;
|
drawerVisible.value = true;
|
||||||
};
|
};
|
||||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||||
@ -243,41 +232,31 @@ const onSaveSSL = async (formEl: FormInstance | undefined) => {
|
|||||||
if (!formEl) return;
|
if (!formEl) return;
|
||||||
formEl.validate(async (valid) => {
|
formEl.validate(async (valid) => {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
let msg = !form.autoRestart
|
let itemType = form.sslType;
|
||||||
? i18n.global.t('setting.sslChangeHelper1') + '\n\n\n' + 'qwdqwdqwd'
|
if (form.sslType === 'import') {
|
||||||
: i18n.global.t('setting.sslChangeHelper2');
|
itemType = form.itemSSLType === 'paste' ? 'import-paste' : 'import-local';
|
||||||
ElMessageBox.confirm(msg, i18n.global.t('setting.panelSSL'), {
|
}
|
||||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
let param = {
|
||||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
ssl: 'enable',
|
||||||
type: 'info',
|
sslType: itemType,
|
||||||
}).then(async () => {
|
domain: '',
|
||||||
let itemType = form.sslType;
|
sslID: form.sslID,
|
||||||
if (form.sslType === 'import') {
|
cert: form.cert,
|
||||||
itemType = form.itemSSLType === 'paste' ? 'import-paste' : 'import-local';
|
key: form.key,
|
||||||
}
|
};
|
||||||
let param = {
|
let href = window.location.href;
|
||||||
ssl: 'enable',
|
param.domain = href.split('//')[1].split(':')[0];
|
||||||
sslType: itemType,
|
await updateSSL(param).then(() => {
|
||||||
domain: '',
|
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||||
sslID: form.sslID,
|
|
||||||
cert: form.cert,
|
|
||||||
key: form.key,
|
|
||||||
autoRestart: form.autoRestart,
|
|
||||||
};
|
|
||||||
let href = window.location.href;
|
let href = window.location.href;
|
||||||
param.domain = href.split('//')[1].split(':')[0];
|
globalStore.isLogin = false;
|
||||||
await updateSSL(param).then(() => {
|
let address = href.split('://')[1];
|
||||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
if (globalStore.entrance) {
|
||||||
let href = window.location.href;
|
address = address.replaceAll('settings/safe', globalStore.entrance);
|
||||||
globalStore.isLogin = false;
|
} else {
|
||||||
let address = href.split('://')[1];
|
address = address.replaceAll('settings/safe', 'login');
|
||||||
if (globalStore.entrance) {
|
}
|
||||||
address = address.replaceAll('settings/safe', globalStore.entrance);
|
window.open(`https://${address}`, '_self');
|
||||||
} else {
|
|
||||||
address = address.replaceAll('settings/safe', 'login');
|
|
||||||
}
|
|
||||||
window.open(`https://${address}`, '_self');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
2
go.mod
2
go.mod
@ -15,7 +15,7 @@ require (
|
|||||||
github.com/gin-contrib/gzip v0.0.6
|
github.com/gin-contrib/gzip v0.0.6
|
||||||
github.com/gin-gonic/gin v1.9.1
|
github.com/gin-gonic/gin v1.9.1
|
||||||
github.com/glebarez/sqlite v1.10.0
|
github.com/glebarez/sqlite v1.10.0
|
||||||
github.com/go-acme/lego/v4 v4.20.2
|
github.com/go-acme/lego/v4 v4.20.4
|
||||||
github.com/go-gormigrate/gormigrate/v2 v2.1.1
|
github.com/go-gormigrate/gormigrate/v2 v2.1.1
|
||||||
github.com/go-playground/validator/v10 v10.18.0
|
github.com/go-playground/validator/v10 v10.18.0
|
||||||
github.com/go-redis/redis v6.15.9+incompatible
|
github.com/go-redis/redis v6.15.9+incompatible
|
||||||
|
4
go.sum
4
go.sum
@ -318,8 +318,8 @@ github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec
|
|||||||
github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc=
|
github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc=
|
||||||
github.com/glebarez/sqlite v1.10.0 h1:u4gt8y7OND/cCei/NMHmfbLxF6xP2wgKcT/BJf2pYkc=
|
github.com/glebarez/sqlite v1.10.0 h1:u4gt8y7OND/cCei/NMHmfbLxF6xP2wgKcT/BJf2pYkc=
|
||||||
github.com/glebarez/sqlite v1.10.0/go.mod h1:IJ+lfSOmiekhQsFTJRx/lHtGYmCdtAiTaf5wI9u5uHA=
|
github.com/glebarez/sqlite v1.10.0/go.mod h1:IJ+lfSOmiekhQsFTJRx/lHtGYmCdtAiTaf5wI9u5uHA=
|
||||||
github.com/go-acme/lego/v4 v4.20.2 h1:ZwO3oLZb8fL6up1OZVJP3yHuvqhozzlEmyqKmhrPchQ=
|
github.com/go-acme/lego/v4 v4.20.4 h1:yCQGBX9jOfMbriEQUocdYm7EBapdTp8nLXYG8k6SqSU=
|
||||||
github.com/go-acme/lego/v4 v4.20.2/go.mod h1:foauPlhnhoq8WUphaWx5U04uDc+JGhk4ZZtPz/Vqsjg=
|
github.com/go-acme/lego/v4 v4.20.4/go.mod h1:foauPlhnhoq8WUphaWx5U04uDc+JGhk4ZZtPz/Vqsjg=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
|
Loading…
Reference in New Issue
Block a user