Start work on own tls termination and http3 support
Some checks are pending
/ docker (push) Waiting to run
Some checks are pending
/ docker (push) Waiting to run
This commit is contained in:
parent
4a2462e24e
commit
68d7a5e8c3
10 changed files with 634 additions and 698 deletions
139
auth-new/tls.go
Normal file
139
auth-new/tls.go
Normal file
|
@ -0,0 +1,139 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-acme/lego/v4/certcrypto"
|
||||
"github.com/go-acme/lego/v4/certificate"
|
||||
"github.com/go-acme/lego/v4/challenge/http01"
|
||||
"github.com/go-acme/lego/v4/challenge/tlsalpn01"
|
||||
"github.com/go-acme/lego/v4/lego"
|
||||
"github.com/go-acme/lego/v4/registration"
|
||||
|
||||
"git.mstar.dev/mstar/linstrom/config"
|
||||
"git.mstar.dev/mstar/linstrom/storage-new/dbgen"
|
||||
"git.mstar.dev/mstar/linstrom/storage-new/models"
|
||||
)
|
||||
|
||||
type leUser struct {
|
||||
Email string
|
||||
Registration *registration.Resource
|
||||
Key crypto.PrivateKey
|
||||
}
|
||||
|
||||
func (l *leUser) GetEmail() string {
|
||||
return l.Email
|
||||
}
|
||||
|
||||
func (l *leUser) GetRegistration() *registration.Resource {
|
||||
return l.Registration
|
||||
}
|
||||
|
||||
func (l *leUser) GetPrivateKey() crypto.PrivateKey {
|
||||
return l.Key
|
||||
}
|
||||
|
||||
func TlsFromConfig() (*tls.Config, error) {
|
||||
if config.GlobalConfig.SSL.UseLetsEncrypt != nil && *config.GlobalConfig.SSL.UseLetsEncrypt {
|
||||
return tlsFromLetsEncrypt()
|
||||
}
|
||||
panic("Not implemented")
|
||||
}
|
||||
|
||||
func tlsFromLetsEncrypt() (*tls.Config, error) {
|
||||
metadata, err := dbgen.ServerMetadata.First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !metadata.LELastUpdate.Valid {
|
||||
return generateLetsEncryptCert(metadata)
|
||||
} else if metadata.LELastUpdate.Time.Add(time.Hour * 24 * 60).Before(time.Now()) {
|
||||
// Let's Encrypt certificates last for 90 days. It is recommended to renew every 60 days
|
||||
// See https://letsencrypt.org/docs/faq/#what-is-the-lifetime-for-let-s-encrypt-certificates-for-how-long-are-they-valid
|
||||
return generateLetsEncryptCert(metadata)
|
||||
}
|
||||
panic("Not implemented")
|
||||
}
|
||||
|
||||
// (Re-)Generate a Lets Encrypt certificate using the provided details in the config
|
||||
// Automatically stores the newly generated certificate in the db, encrypting beforehand
|
||||
func generateLetsEncryptCert(metadata *models.ServerMetadata) (*tls.Config, error) {
|
||||
// Follow https://go-acme.github.io/lego/usage/library/index.html
|
||||
var userPrivateKey *ecdsa.PrivateKey
|
||||
var err error
|
||||
if len(metadata.LEUserPrivKey) == 0 {
|
||||
userPrivateKey, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
marshalled, err := x509.MarshalECPrivateKey(userPrivateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
encryptedKey, err := Encrypt(
|
||||
[]byte(config.GlobalConfig.Storage.EncryptionKey),
|
||||
marshalled,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
metadata.LEUserPrivKey = encryptedKey
|
||||
} else {
|
||||
decryptedKey, err := Decrypt([]byte(config.GlobalConfig.Storage.EncryptionKey), metadata.LEUserPrivKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userPrivateKey, err = x509.ParseECPrivateKey(decryptedKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
user := leUser{Email: *config.GlobalConfig.SSL.AdminMail}
|
||||
leConfig := lego.NewConfig(&user)
|
||||
leConfig.CADirURL = strings.Replace(
|
||||
config.GlobalConfig.General.GetFullPublicUrl(),
|
||||
"https",
|
||||
"http",
|
||||
1,
|
||||
) + "/directory"
|
||||
leConfig.Certificate.KeyType = certcrypto.RSA2048
|
||||
|
||||
leClient, err := lego.NewClient(leConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO: Figure out these servers
|
||||
err = leClient.Challenge.SetHTTP01Provider(http01.NewProviderServer("", "5002"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = leClient.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "5001"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reg, err := leClient.Registration.Register(
|
||||
registration.RegisterOptions{TermsOfServiceAgreed: true},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user.Registration = reg
|
||||
req := certificate.ObtainRequest{
|
||||
Domains: []string{config.GlobalConfig.General.GetFullDomain()},
|
||||
Bundle: true,
|
||||
}
|
||||
certificates, err := leClient.Certificate.Obtain(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_ = certificates
|
||||
// TODO: Do something with certificates here
|
||||
panic("Not implemented")
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue