83 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			83 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package tenant_tls
 | |
| 
 | |
| import (
 | |
| 	"crypto/tls"
 | |
| 	"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
 | |
| 	tenants  []api.Tenant
 | |
| }
 | |
| 
 | |
| func NewWatcher(client *api.APIClient) *Watcher {
 | |
| 	cs := ak.NewCryptoStore(client.CryptoApi)
 | |
| 	l := log.WithField("logger", "authentik.router.tenant_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 Tenant TLS Checker")
 | |
| 	for ; true; <-ticker.C {
 | |
| 		w.Check()
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (w *Watcher) Check() {
 | |
| 	w.log.Info("updating tenant certificates")
 | |
| 	tenants, _, err := w.client.CoreApi.CoreTenantsListExecute(api.ApiCoreTenantsListRequest{})
 | |
| 	if err != nil {
 | |
| 		w.log.WithError(err).Warning("failed to get tenants")
 | |
| 		return
 | |
| 	}
 | |
| 	for _, t := range tenants.Results {
 | |
| 		if kp := t.WebCertificate.Get(); kp != nil {
 | |
| 			err := w.cs.AddKeypair(*kp)
 | |
| 			if err != nil {
 | |
| 				w.log.WithError(err).Warning("failed to add certificate")
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	w.tenants = tenants.Results
 | |
| }
 | |
| 
 | |
| func (w *Watcher) GetCertificate(ch *tls.ClientHelloInfo) (*tls.Certificate, error) {
 | |
| 	var bestSelection *api.Tenant
 | |
| 	for _, t := range w.tenants {
 | |
| 		if !t.WebCertificate.IsSet() {
 | |
| 			continue
 | |
| 		}
 | |
| 		if *t.Default {
 | |
| 			bestSelection = &t
 | |
| 		}
 | |
| 		if strings.HasSuffix(ch.ServerName, t.Domain) {
 | |
| 			bestSelection = &t
 | |
| 		}
 | |
| 	}
 | |
| 	if bestSelection == nil {
 | |
| 		return w.fallback, nil
 | |
| 	}
 | |
| 	cert := w.cs.Get(*bestSelection.WebCertificate.Get())
 | |
| 	return cert, nil
 | |
| }
 | 
