mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 10:25:52 +02:00
feat(server): implement tls certificate hot-reload
This commit is contained in:
parent
269397e114
commit
de1860718e
4 changed files with 64 additions and 11 deletions
|
@ -3,14 +3,13 @@ package settings
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
|
||||||
|
|
||||||
|
"github.com/0xJacky/Nginx-UI/internal/cert"
|
||||||
"github.com/0xJacky/Nginx-UI/internal/cron"
|
"github.com/0xJacky/Nginx-UI/internal/cron"
|
||||||
"github.com/0xJacky/Nginx-UI/internal/nginx"
|
"github.com/0xJacky/Nginx-UI/internal/nginx"
|
||||||
"github.com/0xJacky/Nginx-UI/internal/system"
|
"github.com/0xJacky/Nginx-UI/internal/system"
|
||||||
"github.com/0xJacky/Nginx-UI/settings"
|
"github.com/0xJacky/Nginx-UI/settings"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/jpillora/overseer"
|
|
||||||
"github.com/uozi-tech/cosy"
|
"github.com/uozi-tech/cosy"
|
||||||
cSettings "github.com/uozi-tech/cosy/settings"
|
cSettings "github.com/uozi-tech/cosy/settings"
|
||||||
)
|
)
|
||||||
|
@ -84,9 +83,9 @@ func SaveSettings(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate SSL certificates if HTTPS is enabled
|
// Validate SSL certificates if HTTPS is enabled
|
||||||
needRestart := false
|
needReloadCert := false
|
||||||
if json.Server.EnableHTTPS != cSettings.ServerSettings.EnableHTTPS {
|
if json.Server.EnableHTTPS != cSettings.ServerSettings.EnableHTTPS {
|
||||||
needRestart = true
|
needReloadCert = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if json.Server.EnableHTTPS {
|
if json.Server.EnableHTTPS {
|
||||||
|
@ -112,10 +111,9 @@ func SaveSettings(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if needRestart {
|
if needReloadCert {
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(2 * time.Second)
|
cert.ReloadServerTLSCertificate()
|
||||||
overseer.Restart()
|
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
dnsproviders "github.com/go-acme/lego/v4/providers/dns"
|
dnsproviders "github.com/go-acme/lego/v4/providers/dns"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/uozi-tech/cosy/logger"
|
"github.com/uozi-tech/cosy/logger"
|
||||||
|
cSettings "github.com/uozi-tech/cosy/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -174,6 +175,11 @@ func IssueCert(payload *ConfigPayload, logChan chan string, errChan chan error)
|
||||||
|
|
||||||
l.Println("[INFO] [Nginx UI] Finished")
|
l.Println("[INFO] [Nginx UI] Finished")
|
||||||
|
|
||||||
|
if payload.GetCertificatePath() == cSettings.ServerSettings.SSLCert &&
|
||||||
|
payload.GetCertificateKeyPath() == cSettings.ServerSettings.SSLKey {
|
||||||
|
ReloadServerTLSCertificate()
|
||||||
|
}
|
||||||
|
|
||||||
// Wait log to be written
|
// Wait log to be written
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
36
internal/cert/server_tls.go
Normal file
36
internal/cert/server_tls.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package cert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"errors"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
cSettings "github.com/uozi-tech/cosy/settings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var tlsCert atomic.Value
|
||||||
|
|
||||||
|
// LoadServerTLSCertificate loads the TLS certificate
|
||||||
|
func LoadServerTLSCertificate() error {
|
||||||
|
return ReloadServerTLSCertificate()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReloadServerTLSCertificate reloads the TLS certificate
|
||||||
|
func ReloadServerTLSCertificate() error {
|
||||||
|
newCert, err := tls.LoadX509KeyPair(cSettings.ServerSettings.SSLCert, cSettings.ServerSettings.SSLKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsCert.Store(newCert)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetServerTLSCertificate returns the current TLS certificate
|
||||||
|
func GetServerTLSCertificate() (*tls.Certificate, error) {
|
||||||
|
cert, ok := tlsCert.Load().(*tls.Certificate)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("no certificate available")
|
||||||
|
}
|
||||||
|
return cert, nil
|
||||||
|
}
|
21
main.go
21
main.go
|
@ -1,11 +1,13 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/0xJacky/Nginx-UI/internal/cert"
|
||||||
"github.com/0xJacky/Nginx-UI/internal/cmd"
|
"github.com/0xJacky/Nginx-UI/internal/cmd"
|
||||||
"github.com/0xJacky/Nginx-UI/internal/kernel"
|
"github.com/0xJacky/Nginx-UI/internal/kernel"
|
||||||
"github.com/0xJacky/Nginx-UI/model"
|
"github.com/0xJacky/Nginx-UI/model"
|
||||||
|
@ -56,12 +58,23 @@ func Program(confPath string) func(state overseer.State) {
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
if cSettings.ServerSettings.EnableHTTPS {
|
if cSettings.ServerSettings.EnableHTTPS {
|
||||||
// Convert SSL certificate and key paths to absolute paths if they are relative
|
// Load TLS certificate
|
||||||
sslCert := cSettings.ServerSettings.SSLCert
|
err = cert.LoadServerTLSCertificate()
|
||||||
sslKey := cSettings.ServerSettings.SSLKey
|
if err != nil {
|
||||||
|
logger.Fatalf("Failed to load TLS certificate: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsConfig := &tls.Config{
|
||||||
|
GetCertificate: func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||||
|
return cert.GetServerTLSCertificate()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
srv.TLSConfig = tlsConfig
|
||||||
|
|
||||||
logger.Info("Starting HTTPS server")
|
logger.Info("Starting HTTPS server")
|
||||||
err = srv.ServeTLS(state.Listener, sslCert, sslKey)
|
err = srv.ServeTLS(state.Listener, "", "")
|
||||||
} else {
|
} else {
|
||||||
logger.Info("Starting HTTP server")
|
logger.Info("Starting HTTP server")
|
||||||
err = srv.Serve(state.Listener)
|
err = srv.Serve(state.Listener)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue