From 22a86038929923429679b189b5fce160fd9ef2e9 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 22 Dec 2021 10:16:01 +0100 Subject: [PATCH] internal: add custom proxy certificates support to embedded outpost Signed-off-by: Jens Langhammer --- internal/outpost/proxyv2/proxyv2.go | 20 ++++++++++++++------ internal/web/{ssl.go => tls.go} | 23 ++++++++++++++++++----- 2 files changed, 32 insertions(+), 11 deletions(-) rename internal/web/{ssl.go => tls.go} (63%) diff --git a/internal/outpost/proxyv2/proxyv2.go b/internal/outpost/proxyv2/proxyv2.go index d6d44d530..afa5b8d7f 100644 --- a/internal/outpost/proxyv2/proxyv2.go +++ b/internal/outpost/proxyv2/proxyv2.go @@ -88,17 +88,25 @@ func (ps *ProxyServer) Type() string { func (ps *ProxyServer) TimerFlowCacheExpiry() {} -func (ps *ProxyServer) getCertificates(info *tls.ClientHelloInfo) (*tls.Certificate, error) { - app, ok := ps.apps[info.ServerName] +func (ps *ProxyServer) GetCertificate(serverName string) *tls.Certificate { + app, ok := ps.apps[serverName] if !ok { - ps.log.WithField("server-name", info.ServerName).Debug("app does not exist") - return &ps.defaultCert, nil + ps.log.WithField("server-name", serverName).Debug("app does not exist") + return nil } if app.Cert == nil { - ps.log.WithField("server-name", info.ServerName).Debug("app does not have a certificate") + ps.log.WithField("server-name", serverName).Debug("app does not have a certificate") + return nil + } + return app.Cert +} + +func (ps *ProxyServer) getCertificates(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + appCert := ps.GetCertificate(info.ServerName) + if appCert == nil { return &ps.defaultCert, nil } - return app.Cert, nil + return appCert, nil } // ServeHTTP constructs a net.Listener and starts handling HTTP requests diff --git a/internal/web/ssl.go b/internal/web/tls.go similarity index 63% rename from internal/web/ssl.go rename to internal/web/tls.go index bf6fc4bf4..da1c9d4a1 100644 --- a/internal/web/ssl.go +++ b/internal/web/tls.go @@ -9,16 +9,29 @@ import ( "goauthentik.io/internal/crypto" ) -// ServeHTTPS constructs a net.Listener and starts handling HTTPS requests -func (ws *WebServer) listenTLS() { +func (ws *WebServer) GetCertificate() func(ch *tls.ClientHelloInfo) (*tls.Certificate, error) { cert, err := crypto.GenerateSelfSignedCert() if err != nil { ws.log.WithError(err).Error("failed to generate default cert") } + return func(ch *tls.ClientHelloInfo) (*tls.Certificate, error) { + if ws.ProxyServer != nil { + appCert := ws.ProxyServer.GetCertificate(ch.ServerName) + if appCert != nil { + return appCert, nil + } + } + ws.log.Trace("using default, self-signed certificate") + return &cert, nil + } +} + +// ServeHTTPS constructs a net.Listener and starts handling HTTPS requests +func (ws *WebServer) listenTLS() { tlsConfig := &tls.Config{ - MinVersion: tls.VersionTLS12, - MaxVersion: tls.VersionTLS12, - Certificates: []tls.Certificate{cert}, + MinVersion: tls.VersionTLS12, + MaxVersion: tls.VersionTLS12, + GetCertificate: ws.GetCertificate(), } ln, err := net.Listen("tcp", config.G.Web.ListenTLS)