Improve ACME account registration URI management
This commit is contained in:
parent
2d946d7ee7
commit
3f5772c62a
6 changed files with 44 additions and 24 deletions
|
@ -8,12 +8,14 @@ import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containous/traefik/log"
|
"github.com/containous/traefik/log"
|
||||||
|
acmeprovider "github.com/containous/traefik/provider/acme"
|
||||||
"github.com/containous/traefik/types"
|
"github.com/containous/traefik/types"
|
||||||
acme "github.com/xenolf/lego/acmev2"
|
acme "github.com/xenolf/lego/acmev2"
|
||||||
)
|
)
|
||||||
|
@ -42,6 +44,11 @@ func (a *Account) Init() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = a.RemoveAccountV1Values()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Unable to remove ACME Account V1 values during account initialization: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
for _, cert := range a.ChallengeCerts {
|
for _, cert := range a.ChallengeCerts {
|
||||||
if cert.certificate == nil {
|
if cert.certificate == nil {
|
||||||
certificate, err := tls.X509KeyPair(cert.Certificate, cert.PrivateKey)
|
certificate, err := tls.X509KeyPair(cert.Certificate, cert.PrivateKey)
|
||||||
|
@ -103,6 +110,29 @@ func (a *Account) GetPrivateKey() crypto.PrivateKey {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveAccountV1Values removes ACME account V1 values
|
||||||
|
func (a *Account) RemoveAccountV1Values() error {
|
||||||
|
// Check if ACME Account is in ACME V1 format
|
||||||
|
if a.Registration != nil {
|
||||||
|
isOldRegistration, err := regexp.MatchString(acmeprovider.RegistrationURLPathV1Regexp, a.Registration.URI)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if isOldRegistration {
|
||||||
|
a.reset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Account) reset() {
|
||||||
|
log.Debug("Reset ACME account object.")
|
||||||
|
a.Email = ""
|
||||||
|
a.Registration = nil
|
||||||
|
a.PrivateKey = nil
|
||||||
|
}
|
||||||
|
|
||||||
// Certificate is used to store certificate info
|
// Certificate is used to store certificate info
|
||||||
type Certificate struct {
|
type Certificate struct {
|
||||||
Domain string
|
Domain string
|
||||||
|
|
|
@ -178,6 +178,10 @@ func (a *ACME) leadershipListener(elected bool) error {
|
||||||
|
|
||||||
account := object.(*Account)
|
account := object.(*Account)
|
||||||
account.Init()
|
account.Init()
|
||||||
|
// Reset Account values if caServer changed, thus registration URI can be updated
|
||||||
|
if account != nil && account.Registration != nil && !strings.HasPrefix(account.Registration.URI, a.CAServer) {
|
||||||
|
account.reset()
|
||||||
|
}
|
||||||
|
|
||||||
var needRegister bool
|
var needRegister bool
|
||||||
if account == nil || len(account.Email) == 0 {
|
if account == nil || len(account.Email) == 0 {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
|
||||||
|
|
||||||
"github.com/containous/traefik/log"
|
"github.com/containous/traefik/log"
|
||||||
"github.com/containous/traefik/provider/acme"
|
"github.com/containous/traefik/provider/acme"
|
||||||
|
@ -51,24 +50,6 @@ func (s *LocalStore) Get() (*Account, error) {
|
||||||
return account, nil
|
return account, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveAccountV1Values removes ACME account V1 values
|
|
||||||
func RemoveAccountV1Values(account *Account) error {
|
|
||||||
// Check if ACME Account is in ACME V1 format
|
|
||||||
if account != nil && account.Registration != nil {
|
|
||||||
isOldRegistration, err := regexp.MatchString(acme.RegistrationURLPathV1Regexp, account.Registration.URI)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if isOldRegistration {
|
|
||||||
account.Email = ""
|
|
||||||
account.Registration = nil
|
|
||||||
account.PrivateKey = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConvertToNewFormat converts old acme.json format to the new one and store the result into the file (used for the backward compatibility)
|
// ConvertToNewFormat converts old acme.json format to the new one and store the result into the file (used for the backward compatibility)
|
||||||
func ConvertToNewFormat(fileName string) {
|
func ConvertToNewFormat(fileName string) {
|
||||||
localStore := acme.NewLocalStore(fileName)
|
localStore := acme.NewLocalStore(fileName)
|
||||||
|
@ -99,13 +80,13 @@ func ConvertToNewFormat(fileName string) {
|
||||||
if account != nil && len(account.Email) > 0 {
|
if account != nil && len(account.Email) > 0 {
|
||||||
err = backupACMEFile(fileName, account)
|
err = backupACMEFile(fileName, account)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Unable to create a backup for the V1 formatted ACME file: %s", err.Error())
|
log.Errorf("Unable to create a backup for the V1 formatted ACME file: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = RemoveAccountV1Values(account)
|
err = account.RemoveAccountV1Values()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Unable to remove ACME Account V1 values: %s", err.Error())
|
log.Errorf("Unable to remove ACME Account V1 values during format conversion: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ func migrateACMEData(fileName string) (*acme.Account, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = acme.RemoveAccountV1Values(account)
|
err = account.RemoveAccountV1Values()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ func (s *LocalStore) get() (*StoredData, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if isOldRegistration {
|
if isOldRegistration {
|
||||||
|
log.Debug("Reset ACME account.")
|
||||||
s.storedData.Account = nil
|
s.storedData.Account = nil
|
||||||
s.SaveDataChan <- s.storedData
|
s.SaveDataChan <- s.storedData
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,11 @@ func (p *Provider) init() error {
|
||||||
return fmt.Errorf("unable to get ACME account : %v", err)
|
return fmt.Errorf("unable to get ACME account : %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset Account if caServer changed, thus registration URI can be updated
|
||||||
|
if p.account != nil && p.account.Registration != nil && !strings.HasPrefix(p.account.Registration.URI, p.CAServer) {
|
||||||
|
p.account = nil
|
||||||
|
}
|
||||||
|
|
||||||
p.certificates, err = p.Store.GetCertificates()
|
p.certificates, err = p.Store.GetCertificates()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get ACME certificates : %v", err)
|
return fmt.Errorf("unable to get ACME certificates : %v", err)
|
||||||
|
@ -315,7 +320,6 @@ func (p *Provider) getClient() (*acme.Client, error) {
|
||||||
}
|
}
|
||||||
p.client = client
|
p.client = client
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.client, nil
|
return p.client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue