mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
fix: 解决证书面板过期问题 (#3102)
This commit is contained in:
parent
82881273ea
commit
fa9d855523
@ -110,7 +110,7 @@ func (b *BaseApi) ObtainWebsiteCA(c *gin.Context) {
|
|||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := websiteCAService.ObtainSSL(req); err != nil {
|
if _, err := websiteCAService.ObtainSSL(req); err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -131,7 +131,7 @@ func (b *BaseApi) RenewWebsiteCA(c *gin.Context) {
|
|||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := websiteCAService.ObtainSSL(request.WebsiteCAObtain{
|
if _, err := websiteCAService.ObtainSSL(request.WebsiteCAObtain{
|
||||||
SSLID: req.SSLID,
|
SSLID: req.SSLID,
|
||||||
Renew: true,
|
Renew: true,
|
||||||
Unit: "year",
|
Unit: "year",
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@ -21,7 +22,6 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
|
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/ssl"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/robfig/cron/v3"
|
"github.com/robfig/cron/v3"
|
||||||
)
|
)
|
||||||
@ -204,7 +204,6 @@ func (u *SettingService) UpdateSSL(c *gin.Context, req dto.SSLUpdate) error {
|
|||||||
}()
|
}()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := os.Stat(secretDir); err != nil && os.IsNotExist(err) {
|
if _, err := os.Stat(secretDir); err != nil && os.IsNotExist(err) {
|
||||||
if err = os.MkdirAll(secretDir, os.ModePerm); err != nil {
|
if err = os.MkdirAll(secretDir, os.ModePerm); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -213,49 +212,61 @@ func (u *SettingService) UpdateSSL(c *gin.Context, req dto.SSLUpdate) error {
|
|||||||
if err := settingRepo.Update("SSLType", req.SSLType); err != nil {
|
if err := settingRepo.Update("SSLType", req.SSLType); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if req.SSLType == "self" {
|
var (
|
||||||
|
secret string
|
||||||
|
key string
|
||||||
|
)
|
||||||
|
|
||||||
|
switch req.SSLType {
|
||||||
|
case "self":
|
||||||
if len(req.Domain) == 0 {
|
if len(req.Domain) == 0 {
|
||||||
return fmt.Errorf("load domain failed")
|
return fmt.Errorf("load domain failed")
|
||||||
}
|
}
|
||||||
if err := ssl.GenerateSSL(req.Domain); err != nil {
|
defaultCA, err := websiteCARepo.GetFirst(commonRepo.WithByName("1Panel"))
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if req.SSLType == "select" {
|
|
||||||
sslInfo, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(req.SSLID))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
req.Cert = sslInfo.Pem
|
websiteSSL, err := NewIWebsiteCAService().ObtainSSL(request.WebsiteCAObtain{
|
||||||
req.Key = sslInfo.PrivateKey
|
ID: defaultCA.ID,
|
||||||
req.SSLType = "import"
|
KeyType: "P256",
|
||||||
|
Domains: req.Domain,
|
||||||
|
Time: 1,
|
||||||
|
Unit: "year",
|
||||||
|
AutoRenew: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
secret = websiteSSL.Pem
|
||||||
|
key = websiteSSL.PrivateKey
|
||||||
|
if err := settingRepo.Update("SSLID", strconv.Itoa(int(websiteSSL.ID))); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case "select":
|
||||||
|
websiteSSL, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(req.SSLID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
secret = websiteSSL.Pem
|
||||||
|
key = websiteSSL.PrivateKey
|
||||||
if err := settingRepo.Update("SSLID", strconv.Itoa(int(req.SSLID))); err != nil {
|
if err := settingRepo.Update("SSLID", strconv.Itoa(int(req.SSLID))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
case "import":
|
||||||
|
secret = req.Cert
|
||||||
|
key = req.Key
|
||||||
}
|
}
|
||||||
if req.SSLType == "import" {
|
|
||||||
cert, err := os.OpenFile(path.Join(secretDir, "server.crt.tmp"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
fileOp := files.NewFileOp()
|
||||||
if err != nil {
|
if err := fileOp.WriteFile(path.Join(secretDir, "server.crt.tmp"), strings.NewReader(secret), 0600); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cert.Close()
|
if err := fileOp.WriteFile(path.Join(secretDir, "server.key.tmp"), strings.NewReader(key), 0600); err != nil {
|
||||||
if _, err := cert.WriteString(req.Cert); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
key, err := os.OpenFile(path.Join(secretDir, "server.key.tmp"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := key.WriteString(req.Key); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer key.Close()
|
|
||||||
}
|
|
||||||
if err := checkCertValid(req.Domain); err != nil {
|
if err := checkCertValid(req.Domain); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fileOp := files.NewFileOp()
|
|
||||||
if err := fileOp.Rename(path.Join(secretDir, "server.crt.tmp"), path.Join(secretDir, "server.crt")); err != nil {
|
if err := fileOp.Rename(path.Join(secretDir, "server.crt.tmp"), path.Join(secretDir, "server.crt")); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ type IWebsiteCAService interface {
|
|||||||
Create(create request.WebsiteCACreate) (*request.WebsiteCACreate, error)
|
Create(create request.WebsiteCACreate) (*request.WebsiteCACreate, error)
|
||||||
GetCA(id uint) (*response.WebsiteCADTO, error)
|
GetCA(id uint) (*response.WebsiteCADTO, error)
|
||||||
Delete(id uint) error
|
Delete(id uint) error
|
||||||
ObtainSSL(req request.WebsiteCAObtain) error
|
ObtainSSL(req request.WebsiteCAObtain) (*model.WebsiteSSL, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIWebsiteCAService() IWebsiteCAService {
|
func NewIWebsiteCAService() IWebsiteCAService {
|
||||||
@ -169,10 +169,17 @@ func (w WebsiteCAService) Delete(id uint) error {
|
|||||||
if len(ssls) > 0 {
|
if len(ssls) > 0 {
|
||||||
return buserr.New("ErrDeleteCAWithSSL")
|
return buserr.New("ErrDeleteCAWithSSL")
|
||||||
}
|
}
|
||||||
|
exist, err := websiteCARepo.GetFirst(commonRepo.WithByID(id))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if exist.Name == "1Panel" {
|
||||||
|
return buserr.New("ErrDefaultCA")
|
||||||
|
}
|
||||||
return websiteCARepo.DeleteBy(commonRepo.WithByID(id))
|
return websiteCARepo.DeleteBy(commonRepo.WithByID(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) (*model.WebsiteSSL, error) {
|
||||||
var (
|
var (
|
||||||
domains []string
|
domains []string
|
||||||
ips []net.IP
|
ips []net.IP
|
||||||
@ -183,11 +190,11 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
|||||||
if req.Renew {
|
if req.Renew {
|
||||||
websiteSSL, err = websiteSSLRepo.GetFirst(commonRepo.WithByID(req.SSLID))
|
websiteSSL, err = websiteSSLRepo.GetFirst(commonRepo.WithByID(req.SSLID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
ca, err = websiteCARepo.GetFirst(commonRepo.WithByID(websiteSSL.CaID))
|
ca, err = websiteCARepo.GetFirst(commonRepo.WithByID(websiteSSL.CaID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
existDomains := []string{websiteSSL.PrimaryDomain}
|
existDomains := []string{websiteSSL.PrimaryDomain}
|
||||||
if websiteSSL.Domains != "" {
|
if websiteSSL.Domains != "" {
|
||||||
@ -203,7 +210,7 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
|||||||
} else {
|
} else {
|
||||||
ca, err = websiteCARepo.GetFirst(commonRepo.WithByID(req.ID))
|
ca, err = websiteCARepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
websiteSSL = &model.WebsiteSSL{
|
websiteSSL = &model.WebsiteSSL{
|
||||||
Provider: constant.SelfSigned,
|
Provider: constant.SelfSigned,
|
||||||
@ -214,7 +221,7 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
|||||||
}
|
}
|
||||||
if req.PushDir {
|
if req.PushDir {
|
||||||
if !files.NewFileOp().Stat(req.Dir) {
|
if !files.NewFileOp().Stat(req.Dir) {
|
||||||
return buserr.New(constant.ErrLinkPathNotFound)
|
return nil, buserr.New(constant.ErrLinkPathNotFound)
|
||||||
}
|
}
|
||||||
websiteSSL.Dir = req.Dir
|
websiteSSL.Dir = req.Dir
|
||||||
}
|
}
|
||||||
@ -223,7 +230,7 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
|||||||
for _, domain := range domainArray {
|
for _, domain := range domainArray {
|
||||||
if !common.IsValidDomain(domain) {
|
if !common.IsValidDomain(domain) {
|
||||||
err = buserr.WithName("ErrDomainFormat", domain)
|
err = buserr.WithName("ErrDomainFormat", domain)
|
||||||
return err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
if ipAddress := net.ParseIP(domain); ipAddress == nil {
|
if ipAddress := net.ParseIP(domain); ipAddress == nil {
|
||||||
domains = append(domains, domain)
|
domains = append(domains, domain)
|
||||||
@ -241,32 +248,32 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
|||||||
|
|
||||||
rootCertBlock, _ := pem.Decode([]byte(ca.CSR))
|
rootCertBlock, _ := pem.Decode([]byte(ca.CSR))
|
||||||
if rootCertBlock == nil {
|
if rootCertBlock == nil {
|
||||||
return buserr.New("ErrSSLCertificateFormat")
|
return nil, buserr.New("ErrSSLCertificateFormat")
|
||||||
}
|
}
|
||||||
rootCsr, err := x509.ParseCertificate(rootCertBlock.Bytes)
|
rootCsr, err := x509.ParseCertificate(rootCertBlock.Bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
rootPrivateKeyBlock, _ := pem.Decode([]byte(ca.PrivateKey))
|
rootPrivateKeyBlock, _ := pem.Decode([]byte(ca.PrivateKey))
|
||||||
if rootPrivateKeyBlock == nil {
|
if rootPrivateKeyBlock == nil {
|
||||||
return buserr.New("ErrSSLCertificateFormat")
|
return nil, buserr.New("ErrSSLCertificateFormat")
|
||||||
}
|
}
|
||||||
|
|
||||||
var rootPrivateKey any
|
var rootPrivateKey any
|
||||||
if ssl.KeyType(websiteSSL.KeyType) == certcrypto.EC256 || ssl.KeyType(websiteSSL.KeyType) == certcrypto.EC384 {
|
if ssl.KeyType(websiteSSL.KeyType) == certcrypto.EC256 || ssl.KeyType(websiteSSL.KeyType) == certcrypto.EC384 {
|
||||||
rootPrivateKey, err = x509.ParseECPrivateKey(rootPrivateKeyBlock.Bytes)
|
rootPrivateKey, err = x509.ParseECPrivateKey(rootPrivateKeyBlock.Bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rootPrivateKey, err = x509.ParsePKCS1PrivateKey(rootPrivateKeyBlock.Bytes)
|
rootPrivateKey, err = x509.ParsePKCS1PrivateKey(rootPrivateKeyBlock.Bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
interPrivateKey, interPublicKey, _, err := createPrivateKey(websiteSSL.KeyType)
|
interPrivateKey, interPublicKey, _, err := createPrivateKey(websiteSSL.KeyType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
notAfter := time.Now()
|
notAfter := time.Now()
|
||||||
if req.Unit == "year" {
|
if req.Unit == "year" {
|
||||||
@ -287,16 +294,16 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
|||||||
}
|
}
|
||||||
interDer, err := x509.CreateCertificate(rand.Reader, interCsr, rootCsr, interPublicKey, rootPrivateKey)
|
interDer, err := x509.CreateCertificate(rand.Reader, interCsr, rootCsr, interPublicKey, rootPrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
interCert, err := x509.ParseCertificate(interDer)
|
interCert, err := x509.ParseCertificate(interDer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, publicKey, privateKeyBytes, err := createPrivateKey(websiteSSL.KeyType)
|
_, publicKey, privateKeyBytes, err := createPrivateKey(websiteSSL.KeyType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
csr := &x509.Certificate{
|
csr := &x509.Certificate{
|
||||||
@ -314,11 +321,11 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
|||||||
|
|
||||||
der, err := x509.CreateCertificate(rand.Reader, csr, interCert, publicKey, interPrivateKey)
|
der, err := x509.CreateCertificate(rand.Reader, csr, interCert, publicKey, interPrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
cert, err := x509.ParseCertificate(der)
|
cert, err := x509.ParseCertificate(der)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
certBlock := &pem.Block{
|
certBlock := &pem.Block{
|
||||||
@ -335,11 +342,11 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
|||||||
|
|
||||||
if req.Renew {
|
if req.Renew {
|
||||||
if err := websiteSSLRepo.Save(websiteSSL); err != nil {
|
if err := websiteSSLRepo.Save(websiteSSL); err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := websiteSSLRepo.Create(context.Background(), websiteSSL); err != nil {
|
if err := websiteSSLRepo.Create(context.Background(), websiteSSL); err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,7 +355,7 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
|||||||
logger := log.New(logFile, "", log.LstdFlags)
|
logger := log.New(logFile, "", log.LstdFlags)
|
||||||
logger.Println(i18n.GetMsgWithMap("ApplySSLSuccess", map[string]interface{}{"domain": strings.Join(domains, ",")}))
|
logger.Println(i18n.GetMsgWithMap("ApplySSLSuccess", map[string]interface{}{"domain": strings.Join(domains, ",")}))
|
||||||
saveCertificateFile(websiteSSL, logger)
|
saveCertificateFile(websiteSSL, logger)
|
||||||
return nil
|
return websiteSSL, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createPrivateKey(keyType string) (privateKey any, publicKey any, privateKeyBytes []byte, err error) {
|
func createPrivateKey(keyType string) (privateKey any, publicKey any, privateKeyBytes []byte, err error) {
|
||||||
|
@ -7,6 +7,10 @@ import (
|
|||||||
"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/common"
|
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||||
|
"path"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,7 +21,25 @@ func NewSSLJob() *ssl {
|
|||||||
return &ssl{}
|
return &ssl{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSystemSSL() (bool, uint) {
|
||||||
|
settingRepo := repo.NewISettingRepo()
|
||||||
|
sslSetting, err := settingRepo.Get(settingRepo.WithByKey("SSL"))
|
||||||
|
if err != nil {
|
||||||
|
global.LOG.Errorf("load service ssl from setting failed, err: %v", err)
|
||||||
|
return false, 0
|
||||||
|
}
|
||||||
|
if sslSetting.Value == "enable" {
|
||||||
|
sslID, _ := settingRepo.Get(settingRepo.WithByKey("SSLID"))
|
||||||
|
idValue, _ := strconv.Atoi(sslID.Value)
|
||||||
|
if idValue > 0 {
|
||||||
|
return true, uint(idValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, 0
|
||||||
|
}
|
||||||
|
|
||||||
func (ssl *ssl) Run() {
|
func (ssl *ssl) Run() {
|
||||||
|
systemSSLEnable, sslID := getSystemSSL()
|
||||||
sslRepo := repo.NewISSLRepo()
|
sslRepo := repo.NewISSLRepo()
|
||||||
sslService := service.NewIWebsiteSSLService()
|
sslService := service.NewIWebsiteSSLService()
|
||||||
sslList, _ := sslRepo.List()
|
sslList, _ := sslRepo.List()
|
||||||
@ -34,7 +56,7 @@ func (ssl *ssl) Run() {
|
|||||||
global.LOG.Errorf("Update the SSL certificate for the [%s] domain", s.PrimaryDomain)
|
global.LOG.Errorf("Update the SSL certificate for the [%s] domain", s.PrimaryDomain)
|
||||||
if s.Provider == constant.SelfSigned {
|
if s.Provider == constant.SelfSigned {
|
||||||
caService := service.NewIWebsiteCAService()
|
caService := service.NewIWebsiteCAService()
|
||||||
if err := caService.ObtainSSL(request.WebsiteCAObtain{
|
if _, err := caService.ObtainSSL(request.WebsiteCAObtain{
|
||||||
ID: s.CaID,
|
ID: s.CaID,
|
||||||
SSLID: s.ID,
|
SSLID: s.ID,
|
||||||
Renew: true,
|
Renew: true,
|
||||||
@ -52,6 +74,19 @@ 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
|
||||||
|
}
|
||||||
|
}
|
||||||
global.LOG.Errorf("The SSL certificate for the [%s] domain has been successfully updated", s.PrimaryDomain)
|
global.LOG.Errorf("The SSL certificate for the [%s] domain has been successfully updated", s.PrimaryDomain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ func Init() {
|
|||||||
migrations.AddWebsiteCA,
|
migrations.AddWebsiteCA,
|
||||||
migrations.AddDockerSockPath,
|
migrations.AddDockerSockPath,
|
||||||
migrations.AddDatabaseSSL,
|
migrations.AddDatabaseSSL,
|
||||||
|
migrations.AddDefaultCA,
|
||||||
})
|
})
|
||||||
if err := m.Migrate(); err != nil {
|
if err := m.Migrate(); err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package migrations
|
package migrations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/service"
|
||||||
"github.com/go-gormigrate/gormigrate/v2"
|
"github.com/go-gormigrate/gormigrate/v2"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
@ -55,3 +57,23 @@ var AddDatabaseSSL = &gormigrate.Migration{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var AddDefaultCA = &gormigrate.Migration{
|
||||||
|
ID: "20231129-add-default-ca",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
caService := service.NewIWebsiteCAService()
|
||||||
|
if _, err := caService.Create(request.WebsiteCACreate{
|
||||||
|
CommonName: "1Panel-CA",
|
||||||
|
Country: "CN",
|
||||||
|
KeyType: "P256",
|
||||||
|
Name: "1Panel",
|
||||||
|
Organization: "FIT2CLOUD",
|
||||||
|
OrganizationUint: "1Panel",
|
||||||
|
Province: "Beijing",
|
||||||
|
City: "Beijing",
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -1,113 +0,0 @@
|
|||||||
package ssl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/x509"
|
|
||||||
"crypto/x509/pkix"
|
|
||||||
"encoding/pem"
|
|
||||||
"math/big"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GenerateSSL(domain string) error {
|
|
||||||
rootPrivateKey, _ := rsa.GenerateKey(rand.Reader, 2048)
|
|
||||||
ipItem := net.ParseIP(domain)
|
|
||||||
isIP := false
|
|
||||||
if len(ipItem) != 0 {
|
|
||||||
isIP = true
|
|
||||||
}
|
|
||||||
|
|
||||||
rootTemplate := x509.Certificate{
|
|
||||||
SerialNumber: big.NewInt(1),
|
|
||||||
Subject: pkix.Name{CommonName: "1Panel Root CA"},
|
|
||||||
NotBefore: time.Now(),
|
|
||||||
NotAfter: time.Now().AddDate(10, 0, 0),
|
|
||||||
BasicConstraintsValid: true,
|
|
||||||
IsCA: true,
|
|
||||||
KeyUsage: x509.KeyUsageCertSign,
|
|
||||||
}
|
|
||||||
if isIP {
|
|
||||||
rootTemplate.IPAddresses = []net.IP{ipItem}
|
|
||||||
} else {
|
|
||||||
rootTemplate.DNSNames = []string{domain}
|
|
||||||
}
|
|
||||||
|
|
||||||
rootCertBytes, _ := x509.CreateCertificate(rand.Reader, &rootTemplate, &rootTemplate, &rootPrivateKey.PublicKey, rootPrivateKey)
|
|
||||||
rootCertBlock := &pem.Block{
|
|
||||||
Type: "CERTIFICATE",
|
|
||||||
Bytes: rootCertBytes,
|
|
||||||
}
|
|
||||||
|
|
||||||
interPrivateKey, _ := rsa.GenerateKey(rand.Reader, 2048)
|
|
||||||
interTemplate := x509.Certificate{
|
|
||||||
SerialNumber: big.NewInt(2),
|
|
||||||
Subject: pkix.Name{CommonName: "1Panel Intermediate CA"},
|
|
||||||
NotBefore: time.Now(),
|
|
||||||
NotAfter: time.Now().AddDate(10, 0, 0),
|
|
||||||
BasicConstraintsValid: true,
|
|
||||||
IsCA: true,
|
|
||||||
KeyUsage: x509.KeyUsageCertSign,
|
|
||||||
}
|
|
||||||
if isIP {
|
|
||||||
interTemplate.IPAddresses = []net.IP{ipItem}
|
|
||||||
} else {
|
|
||||||
interTemplate.DNSNames = []string{domain}
|
|
||||||
}
|
|
||||||
|
|
||||||
interCertBytes, _ := x509.CreateCertificate(rand.Reader, &interTemplate, &rootTemplate, &interPrivateKey.PublicKey, rootPrivateKey)
|
|
||||||
interCertBlock := &pem.Block{
|
|
||||||
Type: "CERTIFICATE",
|
|
||||||
Bytes: interCertBytes,
|
|
||||||
}
|
|
||||||
|
|
||||||
clientPrivateKey, _ := rsa.GenerateKey(rand.Reader, 2048)
|
|
||||||
clientTemplate := x509.Certificate{
|
|
||||||
SerialNumber: big.NewInt(3),
|
|
||||||
Subject: pkix.Name{CommonName: domain},
|
|
||||||
NotBefore: time.Now(),
|
|
||||||
NotAfter: time.Now().AddDate(10, 0, 0),
|
|
||||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
|
||||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
|
||||||
}
|
|
||||||
if isIP {
|
|
||||||
clientTemplate.IPAddresses = []net.IP{ipItem}
|
|
||||||
} else {
|
|
||||||
clientTemplate.DNSNames = []string{domain}
|
|
||||||
}
|
|
||||||
|
|
||||||
clientCertBytes, _ := x509.CreateCertificate(rand.Reader, &clientTemplate, &interTemplate, &clientPrivateKey.PublicKey, interPrivateKey)
|
|
||||||
clientCertBlock := &pem.Block{
|
|
||||||
Type: "CERTIFICATE",
|
|
||||||
Bytes: clientCertBytes,
|
|
||||||
}
|
|
||||||
|
|
||||||
pemBytes := []byte{}
|
|
||||||
pemBytes = append(pemBytes, pem.EncodeToMemory(clientCertBlock)...)
|
|
||||||
pemBytes = append(pemBytes, pem.EncodeToMemory(interCertBlock)...)
|
|
||||||
pemBytes = append(pemBytes, pem.EncodeToMemory(rootCertBlock)...)
|
|
||||||
certOut, err := os.OpenFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt.tmp"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer certOut.Close()
|
|
||||||
if _, err := certOut.Write(pemBytes); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
keyOut, err := os.OpenFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.key.tmp"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer keyOut.Close()
|
|
||||||
if err := pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(clientPrivateKey)}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user