Files
upstream-centrifugo/internal/app/tls.go
upstream-mirror b352a9a30d
Some checks failed
test / Lint (push) Failing after 3s
test / Test with Go 1.26.8 (push) Failing after 2s
snapshot of https://github.com/centrifugal/centrifugo.git (master, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:17:21 +05:00

82 lines
2.4 KiB
Go

package app
import (
"crypto/tls"
stdlog "log"
"net/http"
"sync"
"time"
"github.com/centrifugal/centrifugo/v6/internal/config"
"github.com/rs/zerolog/log"
"golang.org/x/crypto/acme"
"golang.org/x/crypto/acme/autocert"
)
var startHTTPChallengeServerOnce sync.Once
func GetTLSConfig(cfg config.Config) (*tls.Config, error) {
tlsEnabled := cfg.HTTP.TLS.Enabled
tlsAutocertEnabled := cfg.HTTP.TLSAutocert.Enabled
tlsAutocertHostWhitelist := cfg.HTTP.TLSAutocert.HostWhitelist
tlsAutocertCacheDir := cfg.HTTP.TLSAutocert.CacheDir
tlsAutocertEmail := cfg.HTTP.TLSAutocert.Email
tlsAutocertServerName := cfg.HTTP.TLSAutocert.ServerName
tlsAutocertHTTP := cfg.HTTP.TLSAutocert.HTTP
tlsAutocertHTTPAddr := cfg.HTTP.TLSAutocert.HTTPAddr
if tlsAutocertEnabled {
certManager := autocert.Manager{
Prompt: autocert.AcceptTOS,
Email: tlsAutocertEmail,
}
if tlsAutocertHostWhitelist != nil {
certManager.HostPolicy = autocert.HostWhitelist(tlsAutocertHostWhitelist...)
}
if tlsAutocertCacheDir != "" {
certManager.Cache = autocert.DirCache(tlsAutocertCacheDir)
}
if tlsAutocertHTTP {
startHTTPChallengeServerOnce.Do(func() {
// getTLSConfig can be called several times.
acmeHTTPServer := &http.Server{
Handler: certManager.HTTPHandler(nil),
Addr: tlsAutocertHTTPAddr,
ErrorLog: stdlog.New(&httpErrorLogWriter{log.Logger}, "", 0),
ReadHeaderTimeout: 10 * time.Second,
ReadTimeout: 30 * time.Second,
WriteTimeout: 10 * time.Second,
}
go func() {
log.Info().Msgf("serving ACME http_01 challenge on %s", tlsAutocertHTTPAddr)
if err := acmeHTTPServer.ListenAndServe(); err != nil {
log.Fatal().Err(err).Msgf("can't create server on %s to serve acme http challenge", tlsAutocertHTTPAddr)
}
}()
})
}
return &tls.Config{
MinVersion: tls.VersionTLS12,
GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
// See https://github.com/centrifugal/centrifugo/issues/144#issuecomment-279393819
if tlsAutocertServerName != "" && hello.ServerName == "" {
hello.ServerName = tlsAutocertServerName
}
return certManager.GetCertificate(hello)
},
NextProtos: []string{
"h2", "http/1.1", acme.ALPNProto,
},
}, nil
} else if tlsEnabled {
// Autocert disabled - just try to use provided SSL cert and key files.
return cfg.HTTP.TLS.ToGoTLSConfig("http_server")
}
return nil, nil
}