[Temporarily Fix] SSL Can NOT Renew (#310)

This commit is contained in:
HanaHime 2025-11-04 17:09:02 +09:00 committed by GitHub
parent e7bb01ae6d
commit 17acb40929
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 82 additions and 6 deletions

View File

@ -6,6 +6,9 @@ import (
"github.com/Jinnrry/pmail/signal"
log "github.com/sirupsen/logrus"
"time"
// 新增:HTTP 就绪探测
"net/http"
"fmt"
)
var expiredTime time.Time
@ -56,8 +59,33 @@ func sslCheck() {
// 每天检查一遍SSL证书是否即将过期,即将过期就重新生成
func sslUpdateLoop() {
for {
// 等待 HTTP 就绪后再执行 ACME 续期,避免挑战失败
waitHTTPReady()
ssl.Update(true)
// 每24小时检测一次证书有效期
time.Sleep(24 * time.Hour)
}
}
// 新增:HTTP 就绪探测(最多等待 ~90 秒)
func waitHTTPReady() {
port := 80
if config.Instance != nil && config.Instance.HttpPort > 0 {
port = config.Instance.HttpPort
}
url := fmt.Sprintf("http://127.0.0.1:%d/api/ping", port)
for i := 0; i < 90; i++ {
resp, err := http.Get(url)
if err == nil && resp != nil && resp.StatusCode == http.StatusOK {
resp.Body.Close()
log.Infof("HTTP ready: %s", url)
return
}
if resp != nil {
resp.Body.Close()
}
time.Sleep(1 * time.Second)
}
log.Warnf("HTTP not ready after 90s, skipping SSL update this round")
}

View File

@ -67,6 +67,8 @@ func HttpStart() {
}
if config.Instance.HttpsEnabled != 2 {
// 在重定向模式下,也必须显式处理 ACME 挑战,避免跳转导致验证失败
mux.HandleFunc("/.well-known/", controllers.AcmeChallenge)
mux.HandleFunc("/api/ping", controllers.Ping)
mux.HandleFunc("/", controllers.Interceptor)
httpServer = &http.Server{

View File

@ -15,6 +15,7 @@ import (
olog "log"
"net/http"
"time"
"errors"
log "github.com/sirupsen/logrus"
"github.com/spf13/cast"
@ -57,7 +58,14 @@ func HttpsStart() {
}
err := httpsServer.ListenAndServeTLS(config.Instance.SSLPublicKeyPath, config.Instance.SSLPrivateKeyPath)
if err != nil {
panic(err)
if errors.Is(err, http.ErrServerClosed) {
// 正常关闭(重启或停机)
log.Infof("Https Server closed normally on port :%d", HttpsPort)
} else {
// 异常错误仍然打印并退出
log.Errorf("Https Server error on port :%d, %+v", HttpsPort, err)
panic(err)
}
}
}
}
@ -68,6 +76,8 @@ func HttpsStop() {
}
}
// 新增:分类处理关闭错误
// 注入context
func contextIterceptor(h controllers.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {

View File

@ -2,6 +2,11 @@ package res_init
import (
"encoding/json"
"os"
"time"
"fmt"
"github.com/Jinnrry/pmail/config"
"github.com/Jinnrry/pmail/db"
"github.com/Jinnrry/pmail/dto/parsemail"
@ -15,8 +20,8 @@ import (
"github.com/Jinnrry/pmail/signal"
"github.com/Jinnrry/pmail/utils/file"
log "github.com/sirupsen/logrus"
"os"
"time"
// 新增:HTTP 就绪探测
"net/http"
)
func Init(serverVersion string) {
@ -31,8 +36,9 @@ func Init(serverVersion string) {
for {
config.Init()
// 启动前检查一遍证书
ssl.Update(false)
// 移除:启动前立即更新证书的调用,避免 HTTP 未启动时触发 ACME
// ssl.Update(false)
parsemail.Init()
err := db.Init(serverVersion)
if err != nil {
@ -47,6 +53,13 @@ func Init(serverVersion string) {
// http server start
go http_server.HttpsStart()
go http_server.HttpStart()
// 等待 HTTP 服务就绪后再执行证书检查/续期,避免 ACME 验证失败
waitHTTPReady()
// 启动后检查一遍证书(非重启模式)
ssl.Update(false)
// pop3 server start
go pop3_server.Start()
go pop3_server.StartWithTls()
@ -104,3 +117,26 @@ func dirInit() {
}
}
}
// 新增:HTTP 就绪探测(最多等待 ~90 秒)
func waitHTTPReady() {
port := 80
if config.Instance != nil && config.Instance.HttpPort > 0 {
port = config.Instance.HttpPort
}
url := fmt.Sprintf("http://127.0.0.1:%d/api/ping", port)
for i := 0; i < 90; i++ {
resp, err := http.Get(url)
if err == nil && resp != nil && resp.StatusCode == http.StatusOK {
resp.Body.Close()
log.Infof("HTTP ready: %s", url)
return
}
if resp != nil {
resp.Body.Close()
}
time.Sleep(1 * time.Second)
}
log.Warnf("HTTP not ready after 90s, skipping immediate SSL update")
}

View File

@ -80,7 +80,7 @@ func SetSSL(sslType, priKey, crtKey string) error {
func renewCertificate(privateKey *ecdsa.PrivateKey, cfg *config.Config) error {
myUser := MyUser{
Email: "i@" + cfg.Domain,
Email: "SSLMaster@" + cfg.Domain,
key: privateKey,
}