restore ability to run the server in a read-only file system (#6098)
This was temporarily lost after the introduction of the native MoQ QUIC listener.
This commit is contained in:
@@ -159,13 +159,11 @@ func (cl *CertLoader) Close() {
|
||||
cl.cert = nil
|
||||
}
|
||||
|
||||
// GetCertificate returns a function that returns the certificate for use in a tls.Config.
|
||||
func (cl *CertLoader) GetCertificate() func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
return func(_ *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
cl.certMu.RLock()
|
||||
defer cl.certMu.RUnlock()
|
||||
return cl.cert, nil
|
||||
}
|
||||
// GetCertificate returns the certificate for use in a tls.Config.
|
||||
func (cl *CertLoader) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
cl.certMu.RLock()
|
||||
defer cl.certMu.RUnlock()
|
||||
return cl.cert, nil
|
||||
}
|
||||
|
||||
func (cl *CertLoader) watch() {
|
||||
|
||||
@@ -28,10 +28,7 @@ func TestCertReload(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
defer loader.Close()
|
||||
|
||||
getCert := loader.GetCertificate()
|
||||
require.NotNil(t, getCert)
|
||||
|
||||
cert, err := getCert(nil)
|
||||
cert, err := loader.GetCertificate(nil)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, cert)
|
||||
require.Equal(t, &testData, cert)
|
||||
@@ -47,7 +44,7 @@ func TestCertReload(t *testing.T) {
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
cert, err = getCert(nil)
|
||||
cert, err = loader.GetCertificate(nil)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, cert)
|
||||
require.Equal(t, &testData, cert)
|
||||
|
||||
@@ -43,6 +43,7 @@ type Server struct {
|
||||
ServerCert string
|
||||
ServerKey string
|
||||
AllowAutoCert bool
|
||||
GetCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error)
|
||||
Handler http.Handler
|
||||
Parent logger.Writer
|
||||
|
||||
@@ -64,23 +65,31 @@ func (s *Server) Initialize() error {
|
||||
var tlsConfig *tls.Config
|
||||
|
||||
if s.Encryption {
|
||||
if s.ServerCert == "" {
|
||||
return fmt.Errorf("server cert is missing")
|
||||
}
|
||||
var getCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error)
|
||||
|
||||
s.loader = &certloader.CertLoader{
|
||||
CertPath: s.ServerCert,
|
||||
KeyPath: s.ServerKey,
|
||||
AllowAuto: s.AllowAutoCert,
|
||||
Parent: s.Parent,
|
||||
}
|
||||
err := s.loader.Initialize()
|
||||
if err != nil {
|
||||
return err
|
||||
if s.GetCertificate != nil {
|
||||
getCertificate = s.GetCertificate
|
||||
} else {
|
||||
if s.ServerCert == "" {
|
||||
return fmt.Errorf("server cert is missing")
|
||||
}
|
||||
|
||||
s.loader = &certloader.CertLoader{
|
||||
CertPath: s.ServerCert,
|
||||
KeyPath: s.ServerKey,
|
||||
AllowAuto: s.AllowAutoCert,
|
||||
Parent: s.Parent,
|
||||
}
|
||||
err := s.loader.Initialize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
getCertificate = s.loader.GetCertificate
|
||||
}
|
||||
|
||||
tlsConfig = &tls.Config{
|
||||
GetCertificate: s.loader.GetCertificate(),
|
||||
GetCertificate: getCertificate,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,8 +104,7 @@ type httpServerParent interface {
|
||||
type httpServer struct {
|
||||
http2Address string
|
||||
http3Address string
|
||||
serverCert string
|
||||
serverKey string
|
||||
getCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error)
|
||||
allowOrigins []string
|
||||
trustedProxies conf.IPNetworks
|
||||
udpReadBufferSize uint
|
||||
@@ -125,16 +124,14 @@ func (s *httpServer) initialize() error {
|
||||
routerHTTP2.Use(s.onRequestHTTPS2)
|
||||
|
||||
s.innerHTTP2 = &httpp.Server{
|
||||
Address: s.http2Address,
|
||||
AllowOrigins: s.allowOrigins,
|
||||
ReadTimeout: time.Duration(s.readTimeout),
|
||||
WriteTimeout: time.Duration(s.writeTimeout),
|
||||
Encryption: true,
|
||||
ServerKey: s.serverKey,
|
||||
ServerCert: s.serverCert,
|
||||
AllowAutoCert: true,
|
||||
Handler: routerHTTP2,
|
||||
Parent: s,
|
||||
Address: s.http2Address,
|
||||
AllowOrigins: s.allowOrigins,
|
||||
ReadTimeout: time.Duration(s.readTimeout),
|
||||
WriteTimeout: time.Duration(s.writeTimeout),
|
||||
Encryption: true,
|
||||
GetCertificate: s.getCertificate,
|
||||
Handler: routerHTTP2,
|
||||
Parent: s,
|
||||
}
|
||||
err := s.innerHTTP2.Initialize()
|
||||
if err != nil {
|
||||
|
||||
@@ -3,7 +3,6 @@ package moq
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -29,8 +28,7 @@ type nativeListenerParent interface {
|
||||
|
||||
type nativeListener struct {
|
||||
address string
|
||||
serverKey string
|
||||
serverCert string
|
||||
getCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error)
|
||||
udpReadBufferSize uint
|
||||
parent nativeListenerParent
|
||||
|
||||
@@ -65,16 +63,9 @@ func (s *nativeListener) initialize() error {
|
||||
}
|
||||
}
|
||||
|
||||
cert, err := tls.LoadX509KeyPair(s.serverCert, s.serverKey)
|
||||
if err != nil {
|
||||
s.ln.Close()
|
||||
ctxCancel()
|
||||
return fmt.Errorf("unable to load TLS keypair for native MoQ QUIC listener: %w", err)
|
||||
}
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
NextProtos: supportedMoqtALPNs,
|
||||
GetCertificate: s.getCertificate,
|
||||
NextProtos: supportedMoqtALPNs,
|
||||
}
|
||||
|
||||
listener, err := quic.Listen(s.ln, tlsConfig, &quic.Config{
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/bluenviron/mediamtx/internal/certloader"
|
||||
"github.com/bluenviron/mediamtx/internal/conf"
|
||||
"github.com/bluenviron/mediamtx/internal/defs"
|
||||
"github.com/bluenviron/mediamtx/internal/logger"
|
||||
@@ -95,6 +96,7 @@ type Server struct {
|
||||
|
||||
ctx context.Context
|
||||
ctxCancel context.CancelFunc
|
||||
loader *certloader.CertLoader
|
||||
httpServer *httpServer
|
||||
nativeListener *nativeListener
|
||||
sessions map[*session]struct{}
|
||||
@@ -121,11 +123,22 @@ func (s *Server) Initialize() error {
|
||||
s.chAPISessionsKick = make(chan serverAPISessionsKickReq)
|
||||
s.done = make(chan struct{})
|
||||
|
||||
s.loader = &certloader.CertLoader{
|
||||
CertPath: s.ServerCert,
|
||||
KeyPath: s.ServerKey,
|
||||
AllowAuto: true,
|
||||
Parent: s,
|
||||
}
|
||||
err := s.loader.Initialize()
|
||||
if err != nil {
|
||||
ctxCancel()
|
||||
return err
|
||||
}
|
||||
|
||||
s.httpServer = &httpServer{
|
||||
http2Address: s.HTTP2Address,
|
||||
http3Address: s.HTTP3Address,
|
||||
serverKey: s.ServerKey,
|
||||
serverCert: s.ServerCert,
|
||||
getCertificate: s.loader.GetCertificate,
|
||||
allowOrigins: s.AllowOrigins,
|
||||
trustedProxies: s.TrustedProxies,
|
||||
udpReadBufferSize: s.UDPReadBufferSize,
|
||||
@@ -134,22 +147,23 @@ func (s *Server) Initialize() error {
|
||||
pathManager: s.PathManager,
|
||||
parent: s,
|
||||
}
|
||||
err := s.httpServer.initialize()
|
||||
err = s.httpServer.initialize()
|
||||
if err != nil {
|
||||
s.loader.Close()
|
||||
ctxCancel()
|
||||
return err
|
||||
}
|
||||
|
||||
s.nativeListener = &nativeListener{
|
||||
address: s.QUICAddress,
|
||||
serverKey: s.ServerKey,
|
||||
serverCert: s.ServerCert,
|
||||
getCertificate: s.loader.GetCertificate,
|
||||
udpReadBufferSize: s.UDPReadBufferSize,
|
||||
parent: s,
|
||||
}
|
||||
err = s.nativeListener.initialize()
|
||||
if err != nil {
|
||||
s.httpServer.close()
|
||||
s.loader.Close()
|
||||
ctxCancel()
|
||||
return err
|
||||
}
|
||||
@@ -268,6 +282,10 @@ outer:
|
||||
|
||||
s.httpServer.close()
|
||||
|
||||
if s.loader != nil {
|
||||
s.loader.Close()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ func (s *Server) Initialize() error {
|
||||
}
|
||||
|
||||
net, addr := restrictnetwork.Restrict("tcp", s.Address)
|
||||
s.ln, err = tlsListen(net, addr, &tls.Config{GetCertificate: s.loader.GetCertificate()})
|
||||
s.ln, err = tlsListen(net, addr, &tls.Config{GetCertificate: s.loader.GetCertificate})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ func (s *Server) Initialize() error {
|
||||
return err
|
||||
}
|
||||
|
||||
s.srv.TLSConfig = &tls.Config{GetCertificate: s.loader.GetCertificate()}
|
||||
s.srv.TLSConfig = &tls.Config{GetCertificate: s.loader.GetCertificate}
|
||||
}
|
||||
|
||||
s.srv.Listen = func(network, address string) (net.Listener, error) {
|
||||
|
||||
Reference in New Issue
Block a user