mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-30 19:06:33 +02:00
core/autocert: fix filter chain, handshake (#5151)
core/autocert: fix filter chain, handshake (#5150) * core/autocert: fix filter chain, handshake * only enable http challenges on port 80 Co-authored-by: Caleb Doxsey <cdoxsey@pomerium.com>
This commit is contained in:
parent
4c7c4320af
commit
0733f1ab4b
3 changed files with 76 additions and 8 deletions
|
@ -150,6 +150,8 @@ func (b *Builder) buildMainListener(
|
||||||
li.Address = buildAddress(cfg.Options.Addr, 443)
|
li.Address = buildAddress(cfg.Options.Addr, 443)
|
||||||
li.ListenerFilters = append(li.ListenerFilters, TLSInspectorFilter())
|
li.ListenerFilters = append(li.ListenerFilters, TLSInspectorFilter())
|
||||||
|
|
||||||
|
li.FilterChains = append(li.FilterChains, b.buildACMETLSALPNFilterChain())
|
||||||
|
|
||||||
allCertificates, err := getAllCertificates(cfg)
|
allCertificates, err := getAllCertificates(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -51,7 +51,11 @@ type Manager struct {
|
||||||
certmagic *certmagic.Config
|
certmagic *certmagic.Config
|
||||||
acmeMgr atomic.Pointer[certmagic.ACMEIssuer]
|
acmeMgr atomic.Pointer[certmagic.ACMEIssuer]
|
||||||
srv *http.Server
|
srv *http.Server
|
||||||
|
|
||||||
|
acmeTLSALPNLock sync.Mutex
|
||||||
|
acmeTLSALPNPort string
|
||||||
acmeTLSALPNListener net.Listener
|
acmeTLSALPNListener net.Listener
|
||||||
|
acmeTLSALPNConfig *tls.Config
|
||||||
|
|
||||||
*ocspCache
|
*ocspCache
|
||||||
|
|
||||||
|
@ -155,6 +159,7 @@ func (mgr *Manager) getCertMagicConfig(ctx context.Context, cfg *config.Config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
acmeMgr := certmagic.NewACMEIssuer(mgr.certmagic, mgr.acmeTemplate)
|
acmeMgr := certmagic.NewACMEIssuer(mgr.certmagic, mgr.acmeTemplate)
|
||||||
|
acmeMgr.DisableHTTPChallenge = !shouldEnableHTTPChallenge(cfg)
|
||||||
err = configureCertificateAuthority(acmeMgr, cfg.Options.AutocertOptions)
|
err = configureCertificateAuthority(acmeMgr, cfg.Options.AutocertOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -342,20 +347,34 @@ func (mgr *Manager) updateServer(ctx context.Context, cfg *config.Config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mgr *Manager) updateACMETLSALPNServer(ctx context.Context, cfg *config.Config) {
|
func (mgr *Manager) updateACMETLSALPNServer(ctx context.Context, cfg *config.Config) {
|
||||||
addr := net.JoinHostPort("127.0.0.1", cfg.ACMETLSALPNPort)
|
mgr.acmeTLSALPNLock.Lock()
|
||||||
|
defer mgr.acmeTLSALPNLock.Unlock()
|
||||||
|
|
||||||
|
// store the updated TLS config
|
||||||
|
mgr.acmeTLSALPNConfig = mgr.certmagic.TLSConfig().Clone()
|
||||||
|
// if the port hasn't changed, we're done
|
||||||
|
if mgr.acmeTLSALPNPort == cfg.ACMETLSALPNPort {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the updated port
|
||||||
|
mgr.acmeTLSALPNPort = cfg.ACMETLSALPNPort
|
||||||
|
|
||||||
if mgr.acmeTLSALPNListener != nil {
|
if mgr.acmeTLSALPNListener != nil {
|
||||||
_ = mgr.acmeTLSALPNListener.Close()
|
_ = mgr.acmeTLSALPNListener.Close()
|
||||||
mgr.acmeTLSALPNListener = nil
|
mgr.acmeTLSALPNListener = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConfig := mgr.certmagic.TLSConfig()
|
// start the listener
|
||||||
ln, err := tls.Listen("tcp", addr, tlsConfig)
|
addr := net.JoinHostPort("127.0.0.1", cfg.ACMETLSALPNPort)
|
||||||
|
ln, err := net.Listen("tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(ctx).Err(err).Msg("failed to run acme tls alpn server")
|
log.Error(ctx).Err(err).Msg("failed to run acme tls alpn server")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mgr.acmeTLSALPNListener = ln
|
mgr.acmeTLSALPNListener = ln
|
||||||
|
|
||||||
|
// accept connections
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
conn, err := ln.Accept()
|
conn, err := ln.Accept()
|
||||||
|
@ -364,6 +383,20 @@ func (mgr *Manager) updateACMETLSALPNServer(ctx context.Context, cfg *config.Con
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initiate the TLS handshake
|
||||||
|
mgr.acmeTLSALPNLock.Lock()
|
||||||
|
tlsConfig := mgr.acmeTLSALPNConfig.Clone()
|
||||||
|
mgr.acmeTLSALPNLock.Unlock()
|
||||||
|
|
||||||
|
orig := tlsConfig.GetCertificate
|
||||||
|
tlsConfig.GetCertificate = func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||||
|
log.Info(ctx).Str("server-name", chi.ServerName).
|
||||||
|
Msg("received request for ACME TLS ALPN certificate")
|
||||||
|
return orig(chi)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = tls.Server(conn, tlsConfig).HandshakeContext(ctx)
|
||||||
_ = conn.Close()
|
_ = conn.Close()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -469,3 +502,16 @@ func sourceHostnames(cfg *config.Config) []string {
|
||||||
|
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func shouldEnableHTTPChallenge(cfg *config.Config) bool {
|
||||||
|
if cfg == nil || cfg.Options == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
_, p, err := net.SplitHostPort(cfg.Options.HTTPRedirectAddr)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return p == "80"
|
||||||
|
}
|
||||||
|
|
|
@ -630,3 +630,23 @@ func Test_configureTrustedRoots(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestShouldEnableHTTPChallenge(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
assert.False(t, shouldEnableHTTPChallenge(nil))
|
||||||
|
assert.False(t, shouldEnableHTTPChallenge(&config.Config{}))
|
||||||
|
assert.False(t, shouldEnableHTTPChallenge(&config.Config{Options: &config.Options{}}))
|
||||||
|
assert.False(t, shouldEnableHTTPChallenge(&config.Config{Options: &config.Options{
|
||||||
|
HTTPRedirectAddr: ":8080",
|
||||||
|
}}))
|
||||||
|
assert.False(t, shouldEnableHTTPChallenge(&config.Config{Options: &config.Options{
|
||||||
|
HTTPRedirectAddr: "127.0.0.1:8080",
|
||||||
|
}}))
|
||||||
|
assert.True(t, shouldEnableHTTPChallenge(&config.Config{Options: &config.Options{
|
||||||
|
HTTPRedirectAddr: ":80",
|
||||||
|
}}))
|
||||||
|
assert.True(t, shouldEnableHTTPChallenge(&config.Config{Options: &config.Options{
|
||||||
|
HTTPRedirectAddr: "127.0.0.1:80",
|
||||||
|
}}))
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue