chore: Restructure
This commit is contained in:
129
internal/server/tls.go
Normal file
129
internal/server/tls.go
Normal file
@@ -0,0 +1,129 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"git.polynom.me/rio/internal/certificates"
|
||||
"git.polynom.me/rio/internal/dns"
|
||||
|
||||
"github.com/go-acme/lego/v4/lego"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
// To access requestingDomains, first acquire the lock.
|
||||
requestingLock = sync.Mutex{}
|
||||
|
||||
// Domain -> _. Check if domain is a key here to see if we're already requeting
|
||||
// a certificate for it.
|
||||
requestingDomains = make(map[string]bool)
|
||||
)
|
||||
|
||||
func lockIfUnlockedDomain(domain string) bool {
|
||||
requestingLock.Lock()
|
||||
defer requestingLock.Unlock()
|
||||
|
||||
_, found := requestingDomains[domain]
|
||||
if !found {
|
||||
requestingDomains[domain] = true
|
||||
}
|
||||
|
||||
return found
|
||||
}
|
||||
|
||||
func unlockDomain(domain string) {
|
||||
requestingLock.Lock()
|
||||
defer requestingLock.Unlock()
|
||||
|
||||
delete(requestingDomains, domain)
|
||||
}
|
||||
|
||||
func MakeTlsConfig(pagesDomain, cachePath string, cache *certificates.CertificatesCache, acmeClient *lego.Client) *tls.Config {
|
||||
return &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
// Validate that we should even care about this domain
|
||||
if !strings.HasSuffix(info.ServerName, pagesDomain) {
|
||||
// Note: We do not check err here because err != nil
|
||||
// always implies that cname == "", which does not have
|
||||
// pagesDomain as a suffix.
|
||||
cname, _ := dns.LookupCNAME(info.ServerName)
|
||||
if !strings.HasSuffix(cname, pagesDomain) {
|
||||
log.Warnf("Got ServerName for Domain %s that we're not responsible for", info.ServerName)
|
||||
return cache.FallbackCertificate.TlsCertificate, nil
|
||||
}
|
||||
}
|
||||
|
||||
// If we want to access <user>.<pages domain>, then we can just
|
||||
// use a wildcard certificate.
|
||||
domain := info.ServerName
|
||||
/*if strings.HasSuffix(info.ServerName, pagesDomain) {
|
||||
domain = "*." + pagesDomain
|
||||
}*/
|
||||
|
||||
cert, found := cache.Certificates[info.ServerName]
|
||||
if found {
|
||||
if cert.IsValid() {
|
||||
return cert.TlsCertificate, nil
|
||||
} else {
|
||||
// If we're already working on the domain,
|
||||
// return the old certificate
|
||||
if lockIfUnlockedDomain(domain) {
|
||||
return cert.TlsCertificate, nil
|
||||
}
|
||||
defer unlockDomain(domain)
|
||||
|
||||
// TODO: Renew
|
||||
log.Debugf("Certificate for %s expired, renewing", domain)
|
||||
}
|
||||
} else {
|
||||
// Don't request if we're already requesting.
|
||||
if lockIfUnlockedDomain(domain) {
|
||||
return cache.FallbackCertificate.TlsCertificate, nil
|
||||
}
|
||||
defer unlockDomain(domain)
|
||||
|
||||
// Request new certificate
|
||||
log.Debugf("Obtaining new certificate for %s...", domain)
|
||||
cert, err := certificates.ObtainNewCertificate(
|
||||
[]string{domain},
|
||||
acmeClient,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf(
|
||||
"Failed to get certificate for %s: %v",
|
||||
domain,
|
||||
err,
|
||||
)
|
||||
return cache.FallbackCertificate.TlsCertificate, nil
|
||||
}
|
||||
|
||||
// Add to cache and flush
|
||||
cache.AddCert(cert, cachePath)
|
||||
return cert.TlsCertificate, nil
|
||||
}
|
||||
|
||||
log.Debugf("TLS ServerName: %s", info.ServerName)
|
||||
return cache.FallbackCertificate.TlsCertificate, nil
|
||||
},
|
||||
NextProtos: []string{
|
||||
"http/0.9",
|
||||
"http/1.0",
|
||||
"http/1.1",
|
||||
"h2",
|
||||
"h2c",
|
||||
},
|
||||
MinVersion: tls.VersionTLS12,
|
||||
CipherSuites: []uint16{
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user