fix: auto certificate may be blocked by errors #182

This commit is contained in:
0xJacky 2023-11-28 11:21:49 +08:00
parent 50b4fbcda4
commit b475d8b609
No known key found for this signature in database
GPG key ID: B6E4A6E4A561BAF0
8 changed files with 99 additions and 95 deletions

View file

@ -2,7 +2,7 @@ package system
import ( import (
"github.com/0xJacky/Nginx-UI/api" "github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/internal/boot" "github.com/0xJacky/Nginx-UI/internal/kernal"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/0xJacky/Nginx-UI/settings" "github.com/0xJacky/Nginx-UI/settings"
@ -58,7 +58,7 @@ func InstallNginxUI(c *gin.Context) {
} }
// Init model // Init model
boot.InitDatabase() kernal.InitDatabase()
pwd, _ := bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost) pwd, _ := bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost)

4
go.mod
View file

@ -14,10 +14,10 @@ require (
github.com/gin-contrib/static v0.0.1 github.com/gin-contrib/static v0.0.1
github.com/gin-gonic/gin v1.9.1 github.com/gin-gonic/gin v1.9.1
github.com/go-acme/lego/v4 v4.14.0 github.com/go-acme/lego/v4 v4.14.0
github.com/go-co-op/gocron v1.33.1 github.com/go-co-op/gocron v1.36.0
github.com/go-playground/validator/v10 v10.15.3 github.com/go-playground/validator/v10 v10.15.3
github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/google/uuid v1.3.1 github.com/google/uuid v1.4.0
github.com/gorilla/websocket v1.5.0 github.com/gorilla/websocket v1.5.0
github.com/hpcloud/tail v1.0.0 github.com/hpcloud/tail v1.0.0
github.com/jpillora/overseer v1.1.6 github.com/jpillora/overseer v1.1.6

4
go.sum
View file

@ -242,6 +242,8 @@ github.com/go-acme/lego/v4 v4.14.0/go.mod h1:zjmvNCDLGz7GrC1OqdVpVmZFKSRabEDtWbd
github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s= github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s=
github.com/go-co-op/gocron v1.33.1 h1:wjX+Dg6Ae29a/f9BSQjY1Rl+jflTpW9aDyMqseCj78c= github.com/go-co-op/gocron v1.33.1 h1:wjX+Dg6Ae29a/f9BSQjY1Rl+jflTpW9aDyMqseCj78c=
github.com/go-co-op/gocron v1.33.1/go.mod h1:NLi+bkm4rRSy1F8U7iacZOz0xPseMoIOnvabGoSe/no= github.com/go-co-op/gocron v1.33.1/go.mod h1:NLi+bkm4rRSy1F8U7iacZOz0xPseMoIOnvabGoSe/no=
github.com/go-co-op/gocron v1.36.0 h1:sEmAwg57l4JWQgzaVWYfKZ+w13uHOqeOtwjo72Ll5Wc=
github.com/go-co-op/gocron v1.36.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
@ -378,6 +380,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM=
github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=

View file

@ -50,7 +50,7 @@ func (t *AutoCertErrorLog) Exit(text string, err error) {
func (t *AutoCertErrorLog) ToString() (content string) { func (t *AutoCertErrorLog) ToString() (content string) {
for _, v := range t.buffer { for _, v := range t.buffer {
content += fmt.Sprintf("[AutoCert Error] %s\n", v) content += fmt.Sprintf("[Error] %s\n", v)
} }
return return
@ -103,6 +103,8 @@ func AutoObtain() {
ChallengeMethod: certModel.ChallengeMethod, ChallengeMethod: certModel.ChallengeMethod,
DNSCredentialID: certModel.DnsCredentialID, DNSCredentialID: certModel.DnsCredentialID,
} }
// logChan and errChan should be closed inside IssueCert
go IssueCert(payload, logChan, errChan) go IssueCert(payload, logChan, errChan)
go handleIssueCertLogChan(logChan) go handleIssueCertLogChan(logChan)
@ -121,8 +123,6 @@ func AutoObtain() {
} else { } else {
certModel.ClearLog() certModel.ClearLog()
} }
close(logChan)
} }
logger.Info("AutoCert Worker End") logger.Info("AutoCert Worker End")
} }

View file

@ -1,30 +1,30 @@
package cert package cert
import ( import (
"crypto" "crypto"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/elliptic" "crypto/elliptic"
"crypto/rand" "crypto/rand"
"crypto/tls" "crypto/tls"
"github.com/0xJacky/Nginx-UI/internal/cert/dns" "github.com/0xJacky/Nginx-UI/internal/cert/dns"
"github.com/0xJacky/Nginx-UI/internal/logger" "github.com/0xJacky/Nginx-UI/internal/logger"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/0xJacky/Nginx-UI/settings" "github.com/0xJacky/Nginx-UI/settings"
"github.com/go-acme/lego/v4/certcrypto" "github.com/go-acme/lego/v4/certcrypto"
"github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/certificate"
"github.com/go-acme/lego/v4/challenge/http01" "github.com/go-acme/lego/v4/challenge/http01"
"github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/lego"
lego_log "github.com/go-acme/lego/v4/log" lego_log "github.com/go-acme/lego/v4/log"
dns_providers "github.com/go-acme/lego/v4/providers/dns" dns_providers "github.com/go-acme/lego/v4/providers/dns"
"github.com/go-acme/lego/v4/registration" "github.com/go-acme/lego/v4/registration"
"github.com/pkg/errors" "github.com/pkg/errors"
"io" "io"
"log" "log"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
) )
const ( const (
@ -74,6 +74,9 @@ func IssueCert(payload *ConfigPayload, logChan chan string, errChan chan error)
} }
}() }()
defer close(logChan)
defer close(errChan)
// Use a channel to receive lego log // Use a channel to receive lego log
logChannel := make(chan []byte, 1024) logChannel := make(chan []byte, 1024)
defer close(logChannel) defer close(logChannel)
@ -94,7 +97,7 @@ func IssueCert(payload *ConfigPayload, logChan chan string, errChan chan error)
Key: privateKey, Key: privateKey,
} }
// Hijack lego's log // Hijack the (logger) of lego
cw := &channelWriter{ch: logChannel} cw := &channelWriter{ch: logChannel}
multiWriter := io.MultiWriter(os.Stderr, cw) multiWriter := io.MultiWriter(os.Stderr, cw)
l := log.New(os.Stderr, "", log.LstdFlags) l := log.New(os.Stderr, "", log.LstdFlags)
@ -235,12 +238,9 @@ func IssueCert(payload *ConfigPayload, logChan chan string, errChan chan error)
return return
} }
close(errChan)
logChan <- "Reloading nginx" logChan <- "Reloading nginx"
nginx.Reload() nginx.Reload()
logChan <- "Finished" logChan <- "Finished"
close(logChan)
} }

View file

@ -1,7 +1,7 @@
package boot package kernal
import ( import (
analytic2 "github.com/0xJacky/Nginx-UI/internal/analytic" "github.com/0xJacky/Nginx-UI/internal/analytic"
"github.com/0xJacky/Nginx-UI/internal/cert" "github.com/0xJacky/Nginx-UI/internal/cert"
"github.com/0xJacky/Nginx-UI/internal/logger" "github.com/0xJacky/Nginx-UI/internal/logger"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
@ -14,7 +14,7 @@ import (
"time" "time"
) )
func Kernel() { func Boot() {
defer recovery() defer recovery()
async := []func(){ async := []func(){
@ -24,7 +24,7 @@ func Kernel() {
} }
syncs := []func(){ syncs := []func(){
analytic2.RecordServerAnalytic, analytic.RecordServerAnalytic,
} }
for _, v := range async { for _, v := range async {
@ -39,7 +39,7 @@ func Kernel() {
func InitAfterDatabase() { func InitAfterDatabase() {
syncs := []func(){ syncs := []func(){
InitAutoObtainCert, InitAutoObtainCert,
analytic2.RetrieveNodesStatus, analytic.RetrieveNodesStatus,
} }
for _, v := range syncs { for _, v := range syncs {

View file

@ -3,7 +3,7 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/0xJacky/Nginx-UI/internal/boot" "github.com/0xJacky/Nginx-UI/internal/kernal"
"github.com/0xJacky/Nginx-UI/internal/logger" "github.com/0xJacky/Nginx-UI/internal/logger"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/internal/upgrader" "github.com/0xJacky/Nginx-UI/internal/upgrader"
@ -21,7 +21,7 @@ func Program(state overseer.State) {
logger.Infof("Nginx configuration directory: %s", nginx.GetConfPath()) logger.Infof("Nginx configuration directory: %s", nginx.GetConfPath())
boot.Kernel() kernal.Boot()
if state.Listener != nil { if state.Listener != nil {
err := http.Serve(state.Listener, router.InitRouter()) err := http.Serve(state.Listener, router.InitRouter())

View file

@ -1,70 +1,70 @@
package router package router
import ( import (
"github.com/0xJacky/Nginx-UI/api/analytic" "github.com/0xJacky/Nginx-UI/api/analytic"
"github.com/0xJacky/Nginx-UI/api/certificate" "github.com/0xJacky/Nginx-UI/api/certificate"
"github.com/0xJacky/Nginx-UI/api/cluster" "github.com/0xJacky/Nginx-UI/api/cluster"
"github.com/0xJacky/Nginx-UI/api/config" "github.com/0xJacky/Nginx-UI/api/config"
"github.com/0xJacky/Nginx-UI/api/nginx" "github.com/0xJacky/Nginx-UI/api/nginx"
"github.com/0xJacky/Nginx-UI/api/openai" "github.com/0xJacky/Nginx-UI/api/openai"
"github.com/0xJacky/Nginx-UI/api/sites" "github.com/0xJacky/Nginx-UI/api/sites"
"github.com/0xJacky/Nginx-UI/api/system" "github.com/0xJacky/Nginx-UI/api/system"
"github.com/0xJacky/Nginx-UI/api/template" "github.com/0xJacky/Nginx-UI/api/template"
"github.com/0xJacky/Nginx-UI/api/terminal" "github.com/0xJacky/Nginx-UI/api/terminal"
"github.com/0xJacky/Nginx-UI/api/user" "github.com/0xJacky/Nginx-UI/api/user"
"github.com/gin-contrib/static" "github.com/gin-contrib/static"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"net/http" "net/http"
) )
func InitRouter() *gin.Engine { func InitRouter() *gin.Engine {
r := gin.New() r := gin.New()
r.Use(gin.Logger()) r.Use(gin.Logger())
r.Use(recovery()) r.Use(recovery())
r.Use(cacheJs()) r.Use(cacheJs())
//r.Use(OperationSync()) //r.Use(OperationSync())
r.Use(static.Serve("/", mustFS(""))) r.Use(static.Serve("/", mustFS("")))
r.NoRoute(func(c *gin.Context) { r.NoRoute(func(c *gin.Context) {
c.JSON(http.StatusNotFound, gin.H{ c.JSON(http.StatusNotFound, gin.H{
"message": "not found", "message": "not found",
}) })
}) })
root := r.Group("/api") root := r.Group("/api")
{ {
system.InitPublicRouter(root) system.InitPublicRouter(root)
user.InitAuthRouter(root) user.InitAuthRouter(root)
// Authorization required not websocket request // Authorization required not websocket request
g := root.Group("/", authRequired(), proxy()) g := root.Group("/", authRequired(), proxy())
{ {
analytic.InitRouter(g) analytic.InitRouter(g)
user.InitManageUserRouter(g) user.InitManageUserRouter(g)
nginx.InitRouter(g) nginx.InitRouter(g)
sites.InitRouter(g) sites.InitRouter(g)
config.InitRouter(g) config.InitRouter(g)
template.InitRouter(g) template.InitRouter(g)
certificate.InitCertificateRouter(g) certificate.InitCertificateRouter(g)
certificate.InitDNSCredentialRouter(g) certificate.InitDNSCredentialRouter(g)
system.InitPrivateRouter(g) system.InitPrivateRouter(g)
openai.InitRouter(g) openai.InitRouter(g)
cluster.InitRouter(g) cluster.InitRouter(g)
} }
// Authorization required and websocket request // Authorization required and websocket request
w := root.Group("/", authRequired(), proxyWs()) w := root.Group("/", authRequired(), proxyWs())
{ {
analytic.InitWebSocketRouter(w) analytic.InitWebSocketRouter(w)
terminal.InitRouter(w) terminal.InitRouter(w)
nginx.InitNginxLogRouter(w) nginx.InitNginxLogRouter(w)
} }
} }
return r return r
} }