Skip to content

Commit ef7d672

Browse files
fix: 解决证书面板过期问题 (1Panel-dev#3102)
1 parent 89014ea commit ef7d672

File tree

7 files changed

+125
-162
lines changed

7 files changed

+125
-162
lines changed

backend/app/api/v1/website_ca.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ func (b *BaseApi) ObtainWebsiteCA(c *gin.Context) {
110110
if err := helper.CheckBindAndValidate(&req, c); err != nil {
111111
return
112112
}
113-
if err := websiteCAService.ObtainSSL(req); err != nil {
113+
if _, err := websiteCAService.ObtainSSL(req); err != nil {
114114
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
115115
return
116116
}
@@ -131,7 +131,7 @@ func (b *BaseApi) RenewWebsiteCA(c *gin.Context) {
131131
if err := helper.CheckBindAndValidate(&req, c); err != nil {
132132
return
133133
}
134-
if err := websiteCAService.ObtainSSL(request.WebsiteCAObtain{
134+
if _, err := websiteCAService.ObtainSSL(request.WebsiteCAObtain{
135135
SSLID: req.SSLID,
136136
Renew: true,
137137
Unit: "year",

backend/app/service/setting.go

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding/json"
77
"encoding/pem"
88
"fmt"
9+
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
910
"net"
1011
"os"
1112
"path"
@@ -21,7 +22,6 @@ import (
2122
"github.com/1Panel-dev/1Panel/backend/utils/common"
2223
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
2324
"github.com/1Panel-dev/1Panel/backend/utils/files"
24-
"github.com/1Panel-dev/1Panel/backend/utils/ssl"
2525
"github.com/gin-gonic/gin"
2626
"github.com/robfig/cron/v3"
2727
)
@@ -204,7 +204,6 @@ func (u *SettingService) UpdateSSL(c *gin.Context, req dto.SSLUpdate) error {
204204
}()
205205
return nil
206206
}
207-
208207
if _, err := os.Stat(secretDir); err != nil && os.IsNotExist(err) {
209208
if err = os.MkdirAll(secretDir, os.ModePerm); err != nil {
210209
return err
@@ -213,49 +212,61 @@ func (u *SettingService) UpdateSSL(c *gin.Context, req dto.SSLUpdate) error {
213212
if err := settingRepo.Update("SSLType", req.SSLType); err != nil {
214213
return err
215214
}
216-
if req.SSLType == "self" {
215+
var (
216+
secret string
217+
key string
218+
)
219+
220+
switch req.SSLType {
221+
case "self":
217222
if len(req.Domain) == 0 {
218223
return fmt.Errorf("load domain failed")
219224
}
220-
if err := ssl.GenerateSSL(req.Domain); err != nil {
221-
return err
222-
}
223-
}
224-
if req.SSLType == "select" {
225-
sslInfo, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(req.SSLID))
225+
defaultCA, err := websiteCARepo.GetFirst(commonRepo.WithByName("1Panel"))
226226
if err != nil {
227227
return err
228228
}
229-
req.Cert = sslInfo.Pem
230-
req.Key = sslInfo.PrivateKey
231-
req.SSLType = "import"
232-
if err := settingRepo.Update("SSLID", strconv.Itoa(int(req.SSLID))); err != nil {
233-
return err
234-
}
235-
}
236-
if req.SSLType == "import" {
237-
cert, err := os.OpenFile(path.Join(secretDir, "server.crt.tmp"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
229+
websiteSSL, err := NewIWebsiteCAService().ObtainSSL(request.WebsiteCAObtain{
230+
ID: defaultCA.ID,
231+
KeyType: "P256",
232+
Domains: req.Domain,
233+
Time: 1,
234+
Unit: "year",
235+
AutoRenew: true,
236+
})
238237
if err != nil {
239238
return err
240239
}
241-
defer cert.Close()
242-
if _, err := cert.WriteString(req.Cert); err != nil {
240+
secret = websiteSSL.Pem
241+
key = websiteSSL.PrivateKey
242+
if err := settingRepo.Update("SSLID", strconv.Itoa(int(websiteSSL.ID))); err != nil {
243243
return err
244244
}
245-
key, err := os.OpenFile(path.Join(secretDir, "server.key.tmp"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
245+
case "select":
246+
websiteSSL, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(req.SSLID))
246247
if err != nil {
247248
return err
248249
}
249-
if _, err := key.WriteString(req.Key); err != nil {
250+
secret = websiteSSL.Pem
251+
key = websiteSSL.PrivateKey
252+
if err := settingRepo.Update("SSLID", strconv.Itoa(int(req.SSLID))); err != nil {
250253
return err
251254
}
252-
defer key.Close()
255+
case "import":
256+
secret = req.Cert
257+
key = req.Key
258+
}
259+
260+
fileOp := files.NewFileOp()
261+
if err := fileOp.WriteFile(path.Join(secretDir, "server.crt.tmp"), strings.NewReader(secret), 0600); err != nil {
262+
return err
263+
}
264+
if err := fileOp.WriteFile(path.Join(secretDir, "server.key.tmp"), strings.NewReader(key), 0600); err != nil {
265+
return err
253266
}
254267
if err := checkCertValid(req.Domain); err != nil {
255268
return err
256269
}
257-
258-
fileOp := files.NewFileOp()
259270
if err := fileOp.Rename(path.Join(secretDir, "server.crt.tmp"), path.Join(secretDir, "server.crt")); err != nil {
260271
return err
261272
}

backend/app/service/website_ca.go

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type IWebsiteCAService interface {
3737
Create(create request.WebsiteCACreate) (*request.WebsiteCACreate, error)
3838
GetCA(id uint) (*response.WebsiteCADTO, error)
3939
Delete(id uint) error
40-
ObtainSSL(req request.WebsiteCAObtain) error
40+
ObtainSSL(req request.WebsiteCAObtain) (*model.WebsiteSSL, error)
4141
}
4242

4343
func NewIWebsiteCAService() IWebsiteCAService {
@@ -169,10 +169,17 @@ func (w WebsiteCAService) Delete(id uint) error {
169169
if len(ssls) > 0 {
170170
return buserr.New("ErrDeleteCAWithSSL")
171171
}
172+
exist, err := websiteCARepo.GetFirst(commonRepo.WithByID(id))
173+
if err != nil {
174+
return err
175+
}
176+
if exist.Name == "1Panel" {
177+
return buserr.New("ErrDefaultCA")
178+
}
172179
return websiteCARepo.DeleteBy(commonRepo.WithByID(id))
173180
}
174181

175-
func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
182+
func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) (*model.WebsiteSSL, error) {
176183
var (
177184
domains []string
178185
ips []net.IP
@@ -183,11 +190,11 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
183190
if req.Renew {
184191
websiteSSL, err = websiteSSLRepo.GetFirst(commonRepo.WithByID(req.SSLID))
185192
if err != nil {
186-
return err
193+
return nil, err
187194
}
188195
ca, err = websiteCARepo.GetFirst(commonRepo.WithByID(websiteSSL.CaID))
189196
if err != nil {
190-
return err
197+
return nil, err
191198
}
192199
existDomains := []string{websiteSSL.PrimaryDomain}
193200
if websiteSSL.Domains != "" {
@@ -203,7 +210,7 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
203210
} else {
204211
ca, err = websiteCARepo.GetFirst(commonRepo.WithByID(req.ID))
205212
if err != nil {
206-
return err
213+
return nil, err
207214
}
208215
websiteSSL = &model.WebsiteSSL{
209216
Provider: constant.SelfSigned,
@@ -214,7 +221,7 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
214221
}
215222
if req.PushDir {
216223
if !files.NewFileOp().Stat(req.Dir) {
217-
return buserr.New(constant.ErrLinkPathNotFound)
224+
return nil, buserr.New(constant.ErrLinkPathNotFound)
218225
}
219226
websiteSSL.Dir = req.Dir
220227
}
@@ -223,7 +230,7 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
223230
for _, domain := range domainArray {
224231
if !common.IsValidDomain(domain) {
225232
err = buserr.WithName("ErrDomainFormat", domain)
226-
return err
233+
return nil, err
227234
} else {
228235
if ipAddress := net.ParseIP(domain); ipAddress == nil {
229236
domains = append(domains, domain)
@@ -241,32 +248,32 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
241248

242249
rootCertBlock, _ := pem.Decode([]byte(ca.CSR))
243250
if rootCertBlock == nil {
244-
return buserr.New("ErrSSLCertificateFormat")
251+
return nil, buserr.New("ErrSSLCertificateFormat")
245252
}
246253
rootCsr, err := x509.ParseCertificate(rootCertBlock.Bytes)
247254
if err != nil {
248-
return err
255+
return nil, err
249256
}
250257
rootPrivateKeyBlock, _ := pem.Decode([]byte(ca.PrivateKey))
251258
if rootPrivateKeyBlock == nil {
252-
return buserr.New("ErrSSLCertificateFormat")
259+
return nil, buserr.New("ErrSSLCertificateFormat")
253260
}
254261

255262
var rootPrivateKey any
256263
if ssl.KeyType(websiteSSL.KeyType) == certcrypto.EC256 || ssl.KeyType(websiteSSL.KeyType) == certcrypto.EC384 {
257264
rootPrivateKey, err = x509.ParseECPrivateKey(rootPrivateKeyBlock.Bytes)
258265
if err != nil {
259-
return err
266+
return nil, err
260267
}
261268
} else {
262269
rootPrivateKey, err = x509.ParsePKCS1PrivateKey(rootPrivateKeyBlock.Bytes)
263270
if err != nil {
264-
return err
271+
return nil, err
265272
}
266273
}
267274
interPrivateKey, interPublicKey, _, err := createPrivateKey(websiteSSL.KeyType)
268275
if err != nil {
269-
return err
276+
return nil, err
270277
}
271278
notAfter := time.Now()
272279
if req.Unit == "year" {
@@ -287,16 +294,16 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
287294
}
288295
interDer, err := x509.CreateCertificate(rand.Reader, interCsr, rootCsr, interPublicKey, rootPrivateKey)
289296
if err != nil {
290-
return err
297+
return nil, err
291298
}
292299
interCert, err := x509.ParseCertificate(interDer)
293300
if err != nil {
294-
return err
301+
return nil, err
295302
}
296303

297304
_, publicKey, privateKeyBytes, err := createPrivateKey(websiteSSL.KeyType)
298305
if err != nil {
299-
return err
306+
return nil, err
300307
}
301308

302309
csr := &x509.Certificate{
@@ -314,11 +321,11 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
314321

315322
der, err := x509.CreateCertificate(rand.Reader, csr, interCert, publicKey, interPrivateKey)
316323
if err != nil {
317-
return err
324+
return nil, err
318325
}
319326
cert, err := x509.ParseCertificate(der)
320327
if err != nil {
321-
return err
328+
return nil, err
322329
}
323330

324331
certBlock := &pem.Block{
@@ -335,11 +342,11 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
335342

336343
if req.Renew {
337344
if err := websiteSSLRepo.Save(websiteSSL); err != nil {
338-
return err
345+
return nil, err
339346
}
340347
} else {
341348
if err := websiteSSLRepo.Create(context.Background(), websiteSSL); err != nil {
342-
return err
349+
return nil, err
343350
}
344351
}
345352

@@ -348,7 +355,7 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
348355
logger := log.New(logFile, "", log.LstdFlags)
349356
logger.Println(i18n.GetMsgWithMap("ApplySSLSuccess", map[string]interface{}{"domain": strings.Join(domains, ",")}))
350357
saveCertificateFile(websiteSSL, logger)
351-
return nil
358+
return websiteSSL, nil
352359
}
353360

354361
func createPrivateKey(keyType string) (privateKey any, publicKey any, privateKeyBytes []byte, err error) {

backend/cron/job/ssl.go

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import (
77
"github.com/1Panel-dev/1Panel/backend/constant"
88
"github.com/1Panel-dev/1Panel/backend/global"
99
"github.com/1Panel-dev/1Panel/backend/utils/common"
10+
"github.com/1Panel-dev/1Panel/backend/utils/files"
11+
"path"
12+
"strconv"
13+
"strings"
1014
"time"
1115
)
1216

@@ -17,7 +21,25 @@ func NewSSLJob() *ssl {
1721
return &ssl{}
1822
}
1923

24+
func getSystemSSL() (bool, uint) {
25+
settingRepo := repo.NewISettingRepo()
26+
sslSetting, err := settingRepo.Get(settingRepo.WithByKey("SSL"))
27+
if err != nil {
28+
global.LOG.Errorf("load service ssl from setting failed, err: %v", err)
29+
return false, 0
30+
}
31+
if sslSetting.Value == "enable" {
32+
sslID, _ := settingRepo.Get(settingRepo.WithByKey("SSLID"))
33+
idValue, _ := strconv.Atoi(sslID.Value)
34+
if idValue > 0 {
35+
return true, uint(idValue)
36+
}
37+
}
38+
return false, 0
39+
}
40+
2041
func (ssl *ssl) Run() {
42+
systemSSLEnable, sslID := getSystemSSL()
2143
sslRepo := repo.NewISSLRepo()
2244
sslService := service.NewIWebsiteSSLService()
2345
sslList, _ := sslRepo.List()
@@ -34,7 +56,7 @@ func (ssl *ssl) Run() {
3456
global.LOG.Errorf("Update the SSL certificate for the [%s] domain", s.PrimaryDomain)
3557
if s.Provider == constant.SelfSigned {
3658
caService := service.NewIWebsiteCAService()
37-
if err := caService.ObtainSSL(request.WebsiteCAObtain{
59+
if _, err := caService.ObtainSSL(request.WebsiteCAObtain{
3860
ID: s.CaID,
3961
SSLID: s.ID,
4062
Renew: true,
@@ -52,6 +74,19 @@ func (ssl *ssl) Run() {
5274
continue
5375
}
5476
}
77+
if systemSSLEnable && sslID == s.ID {
78+
websiteSSL, _ := sslRepo.GetFirst(repo.NewCommonRepo().WithByID(s.ID))
79+
fileOp := files.NewFileOp()
80+
secretDir := path.Join(global.CONF.System.BaseDir, "1panel/secret")
81+
if err := fileOp.WriteFile(path.Join(secretDir, "server.crt"), strings.NewReader(websiteSSL.Pem), 0600); err != nil {
82+
global.LOG.Errorf("Failed to update the SSL certificate File for 1Panel System domain [%s] , err:%s", s.PrimaryDomain, err.Error())
83+
continue
84+
}
85+
if err := fileOp.WriteFile(path.Join(secretDir, "server.key"), strings.NewReader(websiteSSL.PrivateKey), 0600); err != nil {
86+
global.LOG.Errorf("Failed to update the SSL certificate for 1Panel System domain [%s] , err:%s", s.PrimaryDomain, err.Error())
87+
continue
88+
}
89+
}
5590
global.LOG.Errorf("The SSL certificate for the [%s] domain has been successfully updated", s.PrimaryDomain)
5691
}
5792
}

backend/init/migration/migrate.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ func Init() {
5858
migrations.AddWebsiteCA,
5959
migrations.AddDockerSockPath,
6060
migrations.AddDatabaseSSL,
61+
migrations.AddDefaultCA,
6162
})
6263
if err := m.Migrate(); err != nil {
6364
global.LOG.Error(err)

backend/init/migration/migrations/v_1_9.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package migrations
22

33
import (
4+
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
45
"github.com/1Panel-dev/1Panel/backend/app/model"
6+
"github.com/1Panel-dev/1Panel/backend/app/service"
57
"github.com/go-gormigrate/gormigrate/v2"
68
"gorm.io/gorm"
79
)
@@ -55,3 +57,23 @@ var AddDatabaseSSL = &gormigrate.Migration{
5557
return nil
5658
},
5759
}
60+
61+
var AddDefaultCA = &gormigrate.Migration{
62+
ID: "20231129-add-default-ca",
63+
Migrate: func(tx *gorm.DB) error {
64+
caService := service.NewIWebsiteCAService()
65+
if _, err := caService.Create(request.WebsiteCACreate{
66+
CommonName: "1Panel-CA",
67+
Country: "CN",
68+
KeyType: "P256",
69+
Name: "1Panel",
70+
Organization: "FIT2CLOUD",
71+
OrganizationUint: "1Panel",
72+
Province: "Beijing",
73+
City: "Beijing",
74+
}); err != nil {
75+
return err
76+
}
77+
return nil
78+
},
79+
}

0 commit comments

Comments
 (0)