mirror of
https://github.com/usual2970/certimate.git
synced 2025-10-05 14:04:54 +00:00
feat: letsencrypt staging environment
This commit is contained in:
@@ -1,22 +1,25 @@
|
||||
package applicant
|
||||
|
||||
const defaultSSLProvider = "letsencrypt"
|
||||
const (
|
||||
sslProviderLetsencrypt = "letsencrypt"
|
||||
sslProviderZeroSSL = "zerossl"
|
||||
sslProviderGts = "gts"
|
||||
sslProviderLetsEncrypt = "letsencrypt"
|
||||
sslProviderLetsEncryptStaging = "letsencrypt_staging"
|
||||
sslProviderZeroSSL = "zerossl"
|
||||
sslProviderGoogleTrustServices = "gts"
|
||||
)
|
||||
const defaultSSLProvider = sslProviderLetsEncrypt
|
||||
|
||||
const (
|
||||
zerosslUrl = "https://acme.zerossl.com/v2/DV90"
|
||||
letsencryptUrl = "https://acme-v02.api.letsencrypt.org/directory"
|
||||
gtsUrl = "https://dv.acme-v02.api.pki.goog/directory"
|
||||
letsencryptUrl = "https://acme-v02.api.letsencrypt.org/directory"
|
||||
letsencryptStagingUrl = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
zerosslUrl = "https://acme.zerossl.com/v2/DV90"
|
||||
gtsUrl = "https://dv.acme-v02.api.pki.goog/directory"
|
||||
)
|
||||
|
||||
var sslProviderUrls = map[string]string{
|
||||
sslProviderLetsencrypt: letsencryptUrl,
|
||||
sslProviderZeroSSL: zerosslUrl,
|
||||
sslProviderGts: gtsUrl,
|
||||
sslProviderLetsEncrypt: letsencryptUrl,
|
||||
sslProviderLetsEncryptStaging: letsencryptStagingUrl,
|
||||
sslProviderZeroSSL: zerosslUrl,
|
||||
sslProviderGoogleTrustServices: gtsUrl,
|
||||
}
|
||||
|
||||
type acmeSSLProviderConfig struct {
|
||||
@@ -25,11 +28,11 @@ type acmeSSLProviderConfig struct {
|
||||
}
|
||||
|
||||
type acmeSSLProviderConfigContent struct {
|
||||
Zerossl acmeSSLProviderEab `json:"zerossl"`
|
||||
Gts acmeSSLProviderEab `json:"gts"`
|
||||
ZeroSSL acmeSSLProviderEabConfig `json:"zerossl"`
|
||||
GoogleTrustServices acmeSSLProviderEabConfig `json:"gts"`
|
||||
}
|
||||
|
||||
type acmeSSLProviderEab struct {
|
||||
type acmeSSLProviderEabConfig struct {
|
||||
EabHmacKey string `json:"eabHmacKey"`
|
||||
EabKid string `json:"eabKid"`
|
||||
}
|
||||
|
@@ -5,7 +5,6 @@ import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-acme/lego/v4/lego"
|
||||
@@ -39,12 +38,12 @@ func newAcmeUser(ca, email string) (*acmeUser, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keyStr, err := x509.ConvertECPrivateKeyToPEM(key)
|
||||
keyPEM, err := x509.ConvertECPrivateKeyToPEM(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
applyUser.privkey = keyStr
|
||||
applyUser.privkey = keyPEM
|
||||
return applyUser, nil
|
||||
}
|
||||
|
||||
@@ -80,30 +79,30 @@ type acmeAccountRepository interface {
|
||||
Save(ca, email, key string, resource *registration.Resource) error
|
||||
}
|
||||
|
||||
func registerAcmeUser(client *lego.Client, sslProvider *acmeSSLProviderConfig, user *acmeUser) (*registration.Resource, error) {
|
||||
func registerAcmeUser(client *lego.Client, sslProviderConfig *acmeSSLProviderConfig, user *acmeUser) (*registration.Resource, error) {
|
||||
// TODO: fix 潜在的并发问题
|
||||
|
||||
var reg *registration.Resource
|
||||
var err error
|
||||
switch sslProvider.Provider {
|
||||
switch sslProviderConfig.Provider {
|
||||
case sslProviderZeroSSL:
|
||||
reg, err = client.Registration.RegisterWithExternalAccountBinding(registration.RegisterEABOptions{
|
||||
TermsOfServiceAgreed: true,
|
||||
Kid: sslProvider.Config.Zerossl.EabKid,
|
||||
HmacEncoded: sslProvider.Config.Zerossl.EabHmacKey,
|
||||
Kid: sslProviderConfig.Config.ZeroSSL.EabKid,
|
||||
HmacEncoded: sslProviderConfig.Config.ZeroSSL.EabHmacKey,
|
||||
})
|
||||
case sslProviderGts:
|
||||
case sslProviderGoogleTrustServices:
|
||||
reg, err = client.Registration.RegisterWithExternalAccountBinding(registration.RegisterEABOptions{
|
||||
TermsOfServiceAgreed: true,
|
||||
Kid: sslProvider.Config.Gts.EabKid,
|
||||
HmacEncoded: sslProvider.Config.Gts.EabHmacKey,
|
||||
Kid: sslProviderConfig.Config.GoogleTrustServices.EabKid,
|
||||
HmacEncoded: sslProviderConfig.Config.GoogleTrustServices.EabHmacKey,
|
||||
})
|
||||
|
||||
case sslProviderLetsencrypt:
|
||||
case sslProviderLetsEncrypt, sslProviderLetsEncryptStaging:
|
||||
reg, err = client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||
|
||||
default:
|
||||
err = errors.New("unknown ssl provider")
|
||||
err = fmt.Errorf("unsupported ssl provider: %s", sslProviderConfig.Provider)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -112,13 +111,13 @@ func registerAcmeUser(client *lego.Client, sslProvider *acmeSSLProviderConfig, u
|
||||
|
||||
repo := repository.NewAcmeAccountRepository()
|
||||
|
||||
resp, err := repo.GetByCAAndEmail(sslProvider.Provider, user.GetEmail())
|
||||
resp, err := repo.GetByCAAndEmail(sslProviderConfig.Provider, user.GetEmail())
|
||||
if err == nil {
|
||||
user.privkey = resp.Key
|
||||
return resp.Resource, nil
|
||||
}
|
||||
|
||||
if err := repo.Save(sslProvider.Provider, user.GetEmail(), user.getPrivateKeyPEM(), reg); err != nil {
|
||||
if err := repo.Save(sslProviderConfig.Provider, user.GetEmail(), user.getPrivateKeyPEM(), reg); err != nil {
|
||||
return nil, fmt.Errorf("failed to save registration: %w", err)
|
||||
}
|
||||
|
||||
|
@@ -77,29 +77,33 @@ func apply(challengeProvider challenge.Provider, applyConfig *applyConfig) (*App
|
||||
settingsRepo := repository.NewSettingsRepository()
|
||||
settings, _ := settingsRepo.GetByName(context.Background(), "sslProvider")
|
||||
|
||||
sslProvider := &acmeSSLProviderConfig{
|
||||
sslProviderConfig := &acmeSSLProviderConfig{
|
||||
Config: acmeSSLProviderConfigContent{},
|
||||
Provider: defaultSSLProvider,
|
||||
}
|
||||
if settings != nil {
|
||||
if err := json.Unmarshal([]byte(settings.Content), sslProvider); err != nil {
|
||||
if err := json.Unmarshal([]byte(settings.Content), sslProviderConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if sslProviderConfig.Provider == "" {
|
||||
sslProviderConfig.Provider = defaultSSLProvider
|
||||
}
|
||||
|
||||
myUser, err := newAcmeUser(sslProviderConfig.Provider, applyConfig.ContactEmail)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Some unified lego environment variables are configured here.
|
||||
// link: https://github.com/go-acme/lego/issues/1867
|
||||
os.Setenv("LEGO_DISABLE_CNAME_SUPPORT", strconv.FormatBool(applyConfig.DisableFollowCNAME))
|
||||
|
||||
myUser, err := newAcmeUser(sslProvider.Provider, applyConfig.ContactEmail)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config := lego.NewConfig(myUser)
|
||||
|
||||
// This CA URL is configured for a local dev instance of Boulder running in Docker in a VM.
|
||||
config.CADirURL = sslProviderUrls[sslProvider.Provider]
|
||||
config.CADirURL = sslProviderUrls[sslProviderConfig.Provider]
|
||||
config.Certificate.KeyType = parseKeyAlgorithm(applyConfig.KeyAlgorithm)
|
||||
|
||||
// A client facilitates communication with the CA server.
|
||||
@@ -118,29 +122,29 @@ func apply(challengeProvider challenge.Provider, applyConfig *applyConfig) (*App
|
||||
|
||||
// New users will need to register
|
||||
if !myUser.hasRegistration() {
|
||||
reg, err := registerAcmeUser(client, sslProvider, myUser)
|
||||
reg, err := registerAcmeUser(client, sslProviderConfig, myUser)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to register: %w", err)
|
||||
}
|
||||
myUser.Registration = reg
|
||||
}
|
||||
|
||||
request := certificate.ObtainRequest{
|
||||
certRequest := certificate.ObtainRequest{
|
||||
Domains: strings.Split(applyConfig.Domains, ";"),
|
||||
Bundle: true,
|
||||
}
|
||||
certificates, err := client.Certificate.Obtain(request)
|
||||
certResource, err := client.Certificate.Obtain(certRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ApplyCertResult{
|
||||
PrivateKey: string(certificates.PrivateKey),
|
||||
Certificate: string(certificates.Certificate),
|
||||
IssuerCertificate: string(certificates.IssuerCertificate),
|
||||
CSR: string(certificates.CSR),
|
||||
ACMECertUrl: certificates.CertURL,
|
||||
ACMECertStableUrl: certificates.CertStableURL,
|
||||
PrivateKey: string(certResource.PrivateKey),
|
||||
Certificate: string(certResource.Certificate),
|
||||
IssuerCertificate: string(certResource.IssuerCertificate),
|
||||
CSR: string(certResource.CSR),
|
||||
ACMECertUrl: certResource.CertURL,
|
||||
ACMECertStableUrl: certResource.CertStableURL,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user