2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 11:27:17 +08:00

feat: 完善证书设置

This commit is contained in:
2026-01-08 21:26:31 +08:00
parent 2099d2ca57
commit 2d525e9680
10 changed files with 183 additions and 44 deletions

View File

@@ -9,7 +9,6 @@ import (
type SettingKey string
const (
SettingKeyIP SettingKey = "ip"
SettingKeyName SettingKey = "name"
SettingKeyVersion SettingKey = "version"
SettingKeyChannel SettingKey = "channel"
@@ -21,6 +20,7 @@ const (
SettingKeyOfflineMode SettingKey = "offline_mode"
SettingKeyAutoUpdate SettingKey = "auto_update"
SettingKeyWebserver SettingKey = "webserver"
SettingKeyPublicIPs SettingKey = "public_ips"
SettingHiddenMenu SettingKey = "hidden_menu"
SettingKeyCustomLogo SettingKey = "custom_logo"
)

View File

@@ -221,6 +221,14 @@ func (r *settingRepo) GetPanel() (*request.SettingPanel, error) {
if err != nil {
return nil, err
}
ip, err := r.Get(biz.SettingKeyPublicIPs)
if err != nil {
return nil, err
}
publicIP := make([]string, 0)
if err = json.Unmarshal([]byte(ip), &publicIP); err != nil {
return nil, err
}
crt, err := io.Read(filepath.Join(app.Root, "panel/storage/cert.pem"))
if err != nil {
@@ -247,6 +255,8 @@ func (r *settingRepo) GetPanel() (*request.SettingPanel, error) {
BackupPath: backupPath,
Port: r.conf.HTTP.Port,
HTTPS: r.conf.HTTP.TLS,
ACME: r.conf.HTTP.ACME,
PublicIP: publicIP,
Cert: crt,
Key: key,
}, nil
@@ -271,6 +281,13 @@ func (r *settingRepo) UpdatePanel(req *request.SettingPanel) (bool, error) {
if err := r.Set(biz.SettingKeyBackupPath, req.BackupPath); err != nil {
return false, err
}
publicIPBytes, err := json.Marshal(req.PublicIP)
if err != nil {
return false, err
}
if err = r.Set(biz.SettingKeyPublicIPs, string(publicIPBytes)); err != nil {
return false, err
}
// 下面是需要需要重启的设置
// 面板HTTPS
@@ -326,6 +343,7 @@ func (r *settingRepo) UpdatePanel(req *request.SettingPanel) (bool, error) {
conf.HTTP.Port = req.Port
conf.HTTP.Entrance = req.Entrance
conf.HTTP.TLS = req.HTTPS
conf.HTTP.ACME = req.ACME
conf.HTTP.IPHeader = req.IPHeader
conf.HTTP.BindDomain = req.BindDomain
conf.HTTP.BindIP = req.BindIP

View File

@@ -19,6 +19,8 @@ type SettingPanel struct {
BackupPath string `json:"backup_path" validate:"required"`
Port uint `json:"port" validate:"required|min:1|max:65535"`
HTTPS bool `json:"https"`
ACME bool `json:"acme"`
PublicIP []string `json:"public_ip"`
Cert string `json:"cert" validate:"required"`
Key string `json:"key" validate:"required"`
}

View File

@@ -1,13 +1,14 @@
package job
import (
"encoding/json"
"log/slog"
"path/filepath"
"time"
"github.com/acepanel/panel/internal/http/request"
"github.com/acepanel/panel/pkg/config"
"github.com/acepanel/panel/pkg/io"
"github.com/acepanel/panel/pkg/systemctl"
"github.com/acepanel/panel/pkg/tools"
"gorm.io/gorm"
"github.com/acepanel/panel/internal/app"
@@ -80,11 +81,16 @@ func (r *CertRenew) Run() {
return
}
ip, err := r.settingRepo.Get(biz.SettingKeyIP)
if err != nil || ip == "" {
ip, err := r.settingRepo.Get(biz.SettingKeyPublicIPs)
if err != nil {
r.log.Warn("[CertRenew] failed to get panel IP", slog.Any("err", err))
return
}
var ips []string
if err = json.Unmarshal([]byte(ip), &ips); err != nil || len(ips) == 0 {
r.log.Warn("[CertRenew] panel public IPs not set", slog.Any("err", err))
return
}
var user biz.User
if err = r.db.First(&user).Error; err != nil {
@@ -96,23 +102,22 @@ func (r *CertRenew) Run() {
r.log.Warn("[CertRenew] failed to get panel ACME account", slog.Any("err", err))
return
}
crt, key, err := r.certRepo.ObtainPanel(account, []string{ip})
crt, key, err := r.certRepo.ObtainPanel(account, ips)
if err != nil {
r.log.Warn("[CertRenew] failed to obtain ACME cert", slog.Any("err", err))
return
}
if err = io.Write(filepath.Join(app.Root, "panel/storage/cert.pem"), string(crt), 0644); err != nil {
r.log.Warn("[CertRenew] failed to write panel cert", slog.Any("err", err))
return
}
if err = io.Write(filepath.Join(app.Root, "panel/storage/cert.key"), string(key), 0644); err != nil {
r.log.Warn("[CertRenew] failed to write panel cert key", slog.Any("err", err))
if err = r.settingRepo.UpdateCert(&request.SettingCert{
Cert: string(crt),
Key: string(key),
}); err != nil {
r.log.Warn("[CertRenew] failed to update panel cert", slog.Any("err", err))
return
}
r.log.Info("[CertRenew] panel cert renewed successfully")
_ = systemctl.Restart("panel")
tools.RestartPanel()
}
}

View File

@@ -3,6 +3,7 @@ package service
import (
"bufio"
"context"
"encoding/json"
"errors"
"fmt"
"math/rand/v2"
@@ -361,9 +362,13 @@ func (s *CliService) HTTPSGenerate(ctx context.Context, cmd *cli.Command) error
}
if s.conf.HTTP.ACME {
ip, err := s.settingRepo.Get(biz.SettingKeyIP)
if err != nil || ip == "" {
return errors.New(s.t.Get("Please set the panel IP in settings first for ACME certificate generation: %v", err))
ip, err := s.settingRepo.Get(biz.SettingKeyPublicIPs)
if err != nil {
return err
}
var ips []string
if err = json.Unmarshal([]byte(ip), &ips); err != nil || len(ips) == 0 {
return errors.New(s.t.Get("Please set the panel IP in settings first for ACME certificate generation"))
}
var user biz.User
@@ -374,10 +379,11 @@ func (s *CliService) HTTPSGenerate(ctx context.Context, cmd *cli.Command) error
if err != nil {
return errors.New(s.t.Get("Failed to get ACME account: %v", err))
}
crt, key, err = s.certRepo.ObtainPanel(account, []string{ip})
crt, key, err = s.certRepo.ObtainPanel(account, ips)
if err != nil {
return errors.New(s.t.Get("Failed to obtain ACME certificate: %v", err))
}
fmt.Println(s.t.Get("Successfully obtained ACME certificate"))
}
if err = io.Write(filepath.Join(app.Root, "panel/storage/cert.pem"), string(crt), 0644); err != nil {
@@ -889,21 +895,25 @@ func (s *CliService) Init(ctx context.Context, cmd *cli.Command) error {
return errors.New(s.t.Get("Already initialized"))
}
ip := ""
ips := make([]string, 0)
acme := false
rv6, err := tools.GetPublicIPv6()
if err == nil {
ip = rv6
ips = append(ips, rv6)
acme = true
}
rv4, err := tools.GetPublicIPv4()
if err == nil {
ip = rv4
ips = append(ips, rv4)
acme = true
}
ip, err := json.Marshal(ips)
if err != nil {
ip = []byte("[]")
}
settings := []biz.Setting{
{Key: biz.SettingKeyIP, Value: ip},
{Key: biz.SettingKeyPublicIPs, Value: string(ip)},
{Key: biz.SettingKeyName, Value: "AcePanel"},
{Key: biz.SettingKeyChannel, Value: "stable"},
{Key: biz.SettingKeyVersion, Value: app.Version},

View File

@@ -1,20 +1,33 @@
package service
import (
"encoding/json"
"net/http"
"github.com/leonelquinteros/gotext"
"github.com/libtnb/chix"
"gorm.io/gorm"
"github.com/acepanel/panel/internal/biz"
"github.com/acepanel/panel/internal/http/request"
"github.com/acepanel/panel/pkg/tools"
)
type SettingService struct {
settingRepo biz.SettingRepo
t *gotext.Locale
db *gorm.DB
settingRepo biz.SettingRepo
certRepo biz.CertRepo
certAccountRepo biz.CertAccountRepo
}
func NewSettingService(setting biz.SettingRepo) *SettingService {
func NewSettingService(t *gotext.Locale, db *gorm.DB, setting biz.SettingRepo, cert biz.CertRepo, certAccount biz.CertAccountRepo) *SettingService {
return &SettingService{
settingRepo: setting,
t: t,
db: db,
settingRepo: setting,
certRepo: cert,
certAccountRepo: certAccount,
}
}
@@ -45,6 +58,54 @@ func (s *SettingService) Update(w http.ResponseWriter, r *http.Request) {
tools.RestartPanel()
}
Success(w, chix.M{
"restart": restart,
})
}
func (s *SettingService) ObtainCert(w http.ResponseWriter, r *http.Request) {
ip, err := s.settingRepo.Get(biz.SettingKeyPublicIPs)
if err != nil {
Error(w, http.StatusInternalServerError, "%v", err)
return
}
var ips []string
if err = json.Unmarshal([]byte(ip), &ips); err != nil {
Error(w, http.StatusInternalServerError, "%v", err)
return
}
if len(ips) == 0 {
Error(w, http.StatusBadRequest, s.t.Get("please set public ips first"))
return
}
var user biz.User
if err = s.db.First(&user).Error; err != nil {
Error(w, http.StatusInternalServerError, "%v", err)
return
}
account, err := s.certAccountRepo.GetDefault(user.ID)
if err != nil {
Error(w, http.StatusInternalServerError, "%v", err)
return
}
crt, key, err := s.certRepo.ObtainPanel(account, ips)
if err != nil {
Error(w, http.StatusInternalServerError, "%v", err)
return
}
if err = s.settingRepo.UpdateCert(&request.SettingCert{
Cert: string(crt),
Key: string(key),
}); err != nil {
Error(w, http.StatusInternalServerError, "%v", err)
return
}
tools.RestartPanel()
Success(w, nil)
}