diff --git a/backend/app/dto/request/website_ssl.go b/backend/app/dto/request/website_ssl.go
index bcb8b4a28..f4d125104 100644
--- a/backend/app/dto/request/website_ssl.go
+++ b/backend/app/dto/request/website_ssl.go
@@ -12,6 +12,7 @@ type WebsiteSSLCreate struct {
Provider string `json:"provider" validate:"required"`
AcmeAccountID uint `json:"acmeAccountId" validate:"required"`
DnsAccountID uint `json:"dnsAccountId"`
+ AutoRenew bool `json:"autoRenew" validate:"required"`
}
type WebsiteDNSReq struct {
diff --git a/backend/app/model/website_ssl.go b/backend/app/model/website_ssl.go
index 92d48aae8..0d13048da 100644
--- a/backend/app/model/website_ssl.go
+++ b/backend/app/model/website_ssl.go
@@ -4,19 +4,21 @@ import "time"
type WebsiteSSL struct {
BaseModel
- PrimaryDomain string `gorm:"type:varchar(256);not null" json:"primaryDomain"`
- PrivateKey string `gorm:"type:longtext;not null" json:"privateKey"`
- Pem string `gorm:"type:longtext;not null" json:"pem"`
- Domains string `gorm:"type:varchar(256);not null" json:"domains"`
- CertURL string `gorm:"type:varchar(256);not null" json:"certURL"`
- Type string `gorm:"type:varchar(64);not null" json:"type"`
- Provider string `gorm:"type:varchar(64);not null" json:"provider"`
- Organization string `gorm:"type:varchar(64);not null" json:"organization"`
- DnsAccountID uint `gorm:"type:integer;not null" json:"dnsAccountId"`
- AcmeAccountID uint `gorm:"type:integer;not null" json:"acmeAccountId"`
- AcmeAccount WebsiteAcmeAccount `json:"acmeAccount"`
- ExpireDate time.Time `json:"expireDate"`
- StartDate time.Time `json:"startDate"`
+ PrimaryDomain string `gorm:"type:varchar(256);not null" json:"primaryDomain"`
+ PrivateKey string `gorm:"type:longtext;not null" json:"privateKey"`
+ Pem string `gorm:"type:longtext;not null" json:"pem"`
+ Domains string `gorm:"type:varchar(256);not null" json:"domains"`
+ CertURL string `gorm:"type:varchar(256);not null" json:"certURL"`
+ Type string `gorm:"type:varchar(64);not null" json:"type"`
+ Provider string `gorm:"type:varchar(64);not null" json:"provider"`
+ Organization string `gorm:"type:varchar(64);not null" json:"organization"`
+ DnsAccountID uint `gorm:"type:integer;not null" json:"dnsAccountId"`
+ AcmeAccountID uint `gorm:"type:integer;not null" json:"acmeAccountId"`
+ AutoRenew bool `gorm:"type:varchar(64);not null" json:"autoRenew"`
+ ExpireDate time.Time `json:"expireDate"`
+ StartDate time.Time `json:"startDate"`
+
+ AcmeAccount WebsiteAcmeAccount `json:"acmeAccount"`
}
func (w WebsiteSSL) TableName() string {
diff --git a/backend/app/service/nginx_utils.go b/backend/app/service/nginx_utils.go
index e3306c523..bb0f9023b 100644
--- a/backend/app/service/nginx_utils.go
+++ b/backend/app/service/nginx_utils.go
@@ -205,7 +205,6 @@ func nginxCheckAndReload(oldContent string, filePath string, containerName strin
_ = files.NewFileOp().WriteFile(filePath, strings.NewReader(oldContent), 0644)
return err
}
-
if err := opNginx(containerName, constant.NginxReload); err != nil {
_ = files.NewFileOp().WriteFile(filePath, strings.NewReader(oldContent), 0644)
return err
diff --git a/backend/app/service/website_ssl.go b/backend/app/service/website_ssl.go
index 26262bdfd..819ff2d0f 100644
--- a/backend/app/service/website_ssl.go
+++ b/backend/app/service/website_ssl.go
@@ -9,6 +9,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/constant"
+ "github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/ssl"
"path"
"strings"
@@ -17,6 +18,21 @@ import (
type WebsiteSSLService struct {
}
+type IWebsiteSSLService interface {
+ Page(search request.WebsiteSSLSearch) (int64, []response.WebsiteSSLDTO, error)
+ GetSSL(id uint) (*response.WebsiteSSLDTO, error)
+ Search() ([]response.WebsiteSSLDTO, error)
+ Create(create request.WebsiteSSLCreate) (request.WebsiteSSLCreate, error)
+ Renew(sslId uint) error
+ GetDNSResolve(req request.WebsiteDNSReq) ([]response.WebsiteDNSRes, error)
+ GetWebsiteSSL(websiteId uint) (response.WebsiteSSLDTO, error)
+ Delete(id uint) error
+}
+
+func NewIWebsiteSSLService() IWebsiteSSLService {
+ return &WebsiteSSLService{}
+}
+
func (w WebsiteSSLService) Page(search request.WebsiteSSLSearch) (int64, []response.WebsiteSSLDTO, error) {
total, sslList, err := websiteSSLRepo.Page(search.Page, search.PageSize, commonRepo.WithOrderBy("created_at desc"))
if err != nil {
@@ -151,8 +167,6 @@ func (w WebsiteSSLService) Renew(sslId uint) error {
if err := client.UseHTTP(path.Join(constant.AppInstallDir, constant.AppNginx, appInstall.Name, "root")); err != nil {
return err
}
- case constant.DnsManual:
-
}
resource, err := client.RenewSSL(websiteSSL.CertURL)
@@ -172,7 +186,26 @@ func (w WebsiteSSLService) Renew(sslId uint) error {
websiteSSL.Type = cert.Issuer.CommonName
websiteSSL.Organization = cert.Issuer.Organization[0]
- return websiteSSLRepo.Save(websiteSSL)
+ if err := websiteSSLRepo.Save(websiteSSL); err != nil {
+ return err
+ }
+
+ websites, _ := websiteRepo.GetBy(websiteRepo.WithWebsiteSSLID(sslId))
+ for _, website := range websites {
+ if err := createPemFile(website, websiteSSL); err != nil {
+ global.LOG.Errorf("create website [%s] ssl file failed! err:%s", website.PrimaryDomain, err.Error())
+ }
+ }
+ if len(websites) > 0 {
+ nginxInstall, err := getAppInstallByKey(constant.AppNginx)
+ if err != nil {
+ return err
+ }
+ if err := opNginx(nginxInstall.ContainerName, constant.NginxReload); err != nil {
+ return buserr.New(constant.ErrSSLApply)
+ }
+ }
+ return nil
}
func (w WebsiteSSLService) GetDNSResolve(req request.WebsiteDNSReq) ([]response.WebsiteDNSRes, error) {
diff --git a/backend/constant/errs.go b/backend/constant/errs.go
index 450aeb9c4..98d597d3c 100644
--- a/backend/constant/errs.go
+++ b/backend/constant/errs.go
@@ -66,4 +66,5 @@ var (
var (
ErrSSLCannotDelete = "ErrSSLCannotDelete"
ErrAccountCannotDelete = "ErrAccountCannotDelete"
+ ErrSSLApply = "ErrSSLApply"
)
diff --git a/backend/cron/cron.go b/backend/cron/cron.go
index 6a85d485e..048355e2a 100644
--- a/backend/cron/cron.go
+++ b/backend/cron/cron.go
@@ -22,6 +22,10 @@ func Run() {
if err != nil {
global.LOG.Errorf("can not add website corn job: %s", err.Error())
}
+ _, err = Cron.AddJob("@daily", job.NewSSLJob())
+ if err != nil {
+ global.LOG.Errorf("can not add ssl corn job: %s", err.Error())
+ }
Cron.Start()
global.Cron = Cron
diff --git a/backend/cron/job/ssl.go b/backend/cron/job/ssl.go
new file mode 100644
index 000000000..8792cbc06
--- /dev/null
+++ b/backend/cron/job/ssl.go
@@ -0,0 +1,36 @@
+package job
+
+import (
+ "github.com/1Panel-dev/1Panel/backend/app/repo"
+ "github.com/1Panel-dev/1Panel/backend/app/service"
+ "github.com/1Panel-dev/1Panel/backend/global"
+ "time"
+)
+
+type ssl struct {
+}
+
+func NewSSLJob() *ssl {
+ return &ssl{}
+}
+
+func (ssl *ssl) Run() {
+ sslRepo := repo.NewISSLRepo()
+ sslService := service.NewIWebsiteSSLService()
+ sslList, _ := sslRepo.List()
+ global.LOG.Info("ssl renew cron job start...")
+ now := time.Now()
+ for _, s := range sslList {
+ if !s.AutoRenew || s.Provider == "manual" || s.Provider == "dnsManual" {
+ continue
+ }
+ sum := s.ExpireDate.Sub(now)
+ if sum.Hours() < 168 {
+ if err := sslService.Renew(s.ID); err != nil {
+ global.LOG.Errorf("renew doamin [%s] ssl failed err:%s", s.PrimaryDomain, err.Error())
+ }
+ }
+ }
+
+ global.LOG.Info("ssl renew cron job end...")
+}
diff --git a/backend/cron/job/website.go b/backend/cron/job/website.go
index fa3c751f7..9a09a50c1 100644
--- a/backend/cron/job/website.go
+++ b/backend/cron/job/website.go
@@ -18,7 +18,7 @@ func NewWebsiteJob() *website {
func (w *website) Run() {
websites, _ := repo.NewIWebsiteRepo().List()
- global.LOG.Info("website cron job start....")
+ global.LOG.Info("website cron job start...")
now := time.Now()
if len(websites) > 0 {
neverExpireDate, _ := time.Parse(constant.DateLayout, constant.DefaultDate)
@@ -36,7 +36,7 @@ func (w *website) Run() {
}
wg.Wait()
}
- global.LOG.Info("website cron job end")
+ global.LOG.Info("website cron job end...")
}
func stopWebsite(websiteId uint, wg *sync.WaitGroup) {
diff --git a/backend/i18n/lang/en.yaml b/backend/i18n/lang/en.yaml
index 5b438ff5b..d4d339291 100644
--- a/backend/i18n/lang/en.yaml
+++ b/backend/i18n/lang/en.yaml
@@ -34,4 +34,5 @@ ErrAppDelete: 'Other Website use this App'
#ssl
ErrSSLCannotDelete: "The certificate is being used by the website and cannot be removed"
-ErrAccountCannotDelete: "The certificate associated with the account cannot be deleted"
\ No newline at end of file
+ErrAccountCannotDelete: "The certificate associated with the account cannot be deleted"
+ErrSSLApply: "The certificate continues to be signed successfully, but openresty reload fails, please check the configuration!"
\ No newline at end of file
diff --git a/backend/i18n/lang/zh.yaml b/backend/i18n/lang/zh.yaml
index b820ed461..8f7c20c43 100644
--- a/backend/i18n/lang/zh.yaml
+++ b/backend/i18n/lang/zh.yaml
@@ -33,4 +33,5 @@ ErrAppDelete: '其他网站使用此应用,不能删除'
#ssl
ErrSSLCannotDelete: "证书正在被网站使用,无法删除"
-ErrAccountCannotDelete: "账号关联证书,无法删除"
\ No newline at end of file
+ErrAccountCannotDelete: "账号关联证书,无法删除"
+ErrSSLApply: "证书续签成功,openresty reload失败,请检查配置!"
\ No newline at end of file
diff --git a/frontend/src/api/interface/website.ts b/frontend/src/api/interface/website.ts
index 429d7e448..57099181c 100644
--- a/frontend/src/api/interface/website.ts
+++ b/frontend/src/api/interface/website.ts
@@ -12,6 +12,7 @@ export namespace Website {
webSiteGroupId: number;
otherDomains: string;
defaultServer: boolean;
+ autoRenew: boolean;
appinstall?: NewAppInstall;
webSiteSSL: SSL;
}
diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts
index 48b7532ed..88a9c1316 100644
--- a/frontend/src/lang/modules/zh.ts
+++ b/frontend/src/lang/modules/zh.ts
@@ -999,6 +999,9 @@ export default {
startDate: '生效时间',
organization: '签发机构',
renewConfirm: '是否确定续签?',
+ autoRenew: '自动续签',
+ autoRenewHelper: '距离到期时间7天自动续签',
+ renewSuccess: '续签成功',
},
firewall: {
ccDeny: 'CC 防护',
diff --git a/frontend/src/views/website/ssl/create/index.vue b/frontend/src/views/website/ssl/create/index.vue
index 6748459b6..0cb01aa00 100644
--- a/frontend/src/views/website/ssl/create/index.vue
+++ b/frontend/src/views/website/ssl/create/index.vue
@@ -4,7 +4,7 @@
:title="$t('commons.button.create')"
:destroy-on-close="true"
:close-on-click-modal="false"
- width="60%"
+ width="50%"
:before-close="handleClose"
>
+
+
+