 65517f3b7f
			
		
	
	65517f3b7f
	
	
	
		
			
			* prepare client auth with inbuilt server Signed-off-by: Jens Langhammer <jens@goauthentik.io> * introduce better IPC auth Signed-off-by: Jens Langhammer <jens@goauthentik.io> * init Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start stage Signed-off-by: Jens Langhammer <jens@goauthentik.io> * only allow trusted proxies to set MTLS headers Signed-off-by: Jens Langhammer <jens@goauthentik.io> * more stage progress Signed-off-by: Jens Langhammer <jens@goauthentik.io> * dont fail if ipc_key doesn't exist Signed-off-by: Jens Langhammer <jens@goauthentik.io> * actually install app Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add some tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update API Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix unquote Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix int serial number not jsonable Signed-off-by: Jens Langhammer <jens@goauthentik.io> * init ui Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add UI Signed-off-by: Jens Langhammer <jens@goauthentik.io> * unrelated: fix git pull in makefile Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix parse helper Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add test for outpost Signed-off-by: Jens Langhammer <jens@goauthentik.io> * more tests and improvements Signed-off-by: Jens Langhammer <jens@goauthentik.io> * improve labels Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add support for multiple CAs on brand Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add support for multiple CAs to MTLS stage Signed-off-by: Jens Langhammer <jens@goauthentik.io> * dont log ipcuser secret views Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix go mod Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
		
			
				
	
	
		
			118 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package brand_tls
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"crypto/tls"
 | |
| 	"crypto/x509"
 | |
| 	"strings"
 | |
| 	"time"
 | |
| 
 | |
| 	log "github.com/sirupsen/logrus"
 | |
| 
 | |
| 	"goauthentik.io/api/v3"
 | |
| 	"goauthentik.io/internal/crypto"
 | |
| 	"goauthentik.io/internal/outpost/ak"
 | |
| )
 | |
| 
 | |
| type Watcher struct {
 | |
| 	client   *api.APIClient
 | |
| 	log      *log.Entry
 | |
| 	cs       *ak.CryptoStore
 | |
| 	fallback *tls.Certificate
 | |
| 	brands   []api.Brand
 | |
| }
 | |
| 
 | |
| func NewWatcher(client *api.APIClient) *Watcher {
 | |
| 	cs := ak.NewCryptoStore(client.CryptoApi)
 | |
| 	l := log.WithField("logger", "authentik.router.brand_tls")
 | |
| 	cert, err := crypto.GenerateSelfSignedCert()
 | |
| 	if err != nil {
 | |
| 		l.WithError(err).Error("failed to generate default cert")
 | |
| 	}
 | |
| 
 | |
| 	return &Watcher{
 | |
| 		client:   client,
 | |
| 		log:      l,
 | |
| 		cs:       cs,
 | |
| 		fallback: &cert,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (w *Watcher) Start() {
 | |
| 	ticker := time.NewTicker(time.Minute * 3)
 | |
| 	w.log.Info("Starting Brand TLS Checker")
 | |
| 	for ; true; <-ticker.C {
 | |
| 		w.Check()
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (w *Watcher) Check() {
 | |
| 	w.log.Info("updating brand certificates")
 | |
| 	brands, err := ak.Paginator(w.client.CoreApi.CoreBrandsList(context.Background()), ak.PaginatorOptions{
 | |
| 		PageSize: 100,
 | |
| 		Logger:   w.log,
 | |
| 	})
 | |
| 	if err != nil {
 | |
| 		w.log.WithError(err).Warning("failed to get brands")
 | |
| 		return
 | |
| 	}
 | |
| 	for _, b := range brands {
 | |
| 		kp := b.GetWebCertificate()
 | |
| 		if kp != "" {
 | |
| 			err := w.cs.AddKeypair(kp)
 | |
| 			if err != nil {
 | |
| 				w.log.WithError(err).WithField("kp", kp).Warning("failed to add web certificate")
 | |
| 			}
 | |
| 		}
 | |
| 		for _, crt := range b.GetClientCertificates() {
 | |
| 			if crt != "" {
 | |
| 				err := w.cs.AddKeypair(crt)
 | |
| 				if err != nil {
 | |
| 					w.log.WithError(err).WithField("kp", kp).Warning("failed to add client certificate")
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	w.brands = brands
 | |
| }
 | |
| 
 | |
| type CertificateConfig struct {
 | |
| 	Web    *tls.Certificate
 | |
| 	Client *x509.CertPool
 | |
| }
 | |
| 
 | |
| func (w *Watcher) GetCertificate(ch *tls.ClientHelloInfo) *CertificateConfig {
 | |
| 	var bestSelection *api.Brand
 | |
| 	config := CertificateConfig{
 | |
| 		Web: w.fallback,
 | |
| 	}
 | |
| 	for _, t := range w.brands {
 | |
| 		if !t.WebCertificate.IsSet() && len(t.GetClientCertificates()) < 1 {
 | |
| 			continue
 | |
| 		}
 | |
| 		if *t.Default {
 | |
| 			bestSelection = &t
 | |
| 		}
 | |
| 		if strings.HasSuffix(ch.ServerName, t.Domain) {
 | |
| 			bestSelection = &t
 | |
| 		}
 | |
| 	}
 | |
| 	if bestSelection == nil {
 | |
| 		return &config
 | |
| 	}
 | |
| 	if bestSelection.GetWebCertificate() != "" {
 | |
| 		if cert := w.cs.Get(bestSelection.GetWebCertificate()); cert != nil {
 | |
| 			config.Web = cert
 | |
| 		}
 | |
| 	}
 | |
| 	if len(bestSelection.GetClientCertificates()) > 0 {
 | |
| 		config.Client = x509.NewCertPool()
 | |
| 		for _, kp := range bestSelection.GetClientCertificates() {
 | |
| 			if cert := w.cs.Get(kp); cert != nil {
 | |
| 				config.Client.AddCert(cert.Leaf)
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return &config
 | |
| }
 |