Skip to content

Commit

Permalink
Add support for save metadata from file.
Browse files Browse the repository at this point in the history
  • Loading branch information
rekby committed May 20, 2019
2 parents 2a556cb + 0113468 commit 3a14518
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 19 deletions.
2 changes: 1 addition & 1 deletion cmd/a_main-packr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import (
)

type ConfigGeneral struct {
IssueTimeout int
AutoIssueForSubdomains string
StorageDir string
AcmeServer string
IssueTimeout int
StorageDir string
AcmeServer string
StoreJSONMetadata bool
}

//go:generate packr
Expand Down
5 changes: 4 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"os"
"runtime"
"time"

"github.com/rekby/lets-proxy2/internal/cert_manager"

Expand Down Expand Up @@ -57,7 +58,7 @@ func startProgram(config *configType) {
logger.Info("StartAutoRenew program version", zap.String("version", version()))

err := os.MkdirAll(config.General.StorageDir, defaultDirMode)
log.InfoFatal(logger, err, "Create storage dir")
log.InfoFatal(logger, err, "Create storage dir", zap.String("dir", config.General.StorageDir))

storage := &cache.DiskCache{Dir: config.General.StorageDir}
clientManager := acme_client_manager.New(ctx, storage)
Expand All @@ -66,6 +67,8 @@ func startProgram(config *configType) {
log.DebugFatal(logger, err, "Get acme client")

certManager := cert_manager.New(acmeClient, storage)
certManager.CertificateIssueTimeout = time.Duration(config.General.IssueTimeout) * time.Second
certManager.SaveJSONMeta = config.General.StoreJSONMetadata

certManager.DomainChecker, err = config.CheckDomains.CreateDomainChecker(ctx)
log.DebugFatal(logger, err, "Config domain checkers.")
Expand Down
6 changes: 3 additions & 3 deletions cmd/static/default-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
# Seconds for issue every certificate. Cancel issue and return error if timeout.
IssueTimeout = 300

# Comma separated for subdomains for try get common used subdomains in one certificate.
AutoIssueForSubdomains = "www"

# Path to dir, which will store state and certificates
StorageDir = "storage"

# Store .json info with certificate metadata near certificate.
StoreJSONMetadata = true

# Directory url of acme server.
#Test server: https://acme-staging-v02.api.letsencrypt.org/directory
AcmeServer = "https://acme-v01.api.letsencrypt.org/directory"
Expand Down
48 changes: 38 additions & 10 deletions internal/cert_manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
Expand Down Expand Up @@ -66,6 +67,7 @@ type Manager struct {
DomainChecker DomainChecker
EnableHTTPValidation bool
EnableTLSValidation bool
SaveJSONMeta bool

certForDomainAuthorize cache.Value

Expand Down Expand Up @@ -441,11 +443,21 @@ func (m *Manager) issueCertificate(ctx context.Context, certName certNameType, d

cert, err := validCertDer(domains, der, key, false, time.Now())
log.DebugDPanic(logger, err, "Check certificate is valid")
if err == nil {
storeCertificate(ctx, m.Cache, certName, cert)
return cert, nil
if err != nil {
return nil, err
}
err = storeCertificate(ctx, m.Cache, certName, cert)
log.DebugDPanic(logger, err, "Certificate stored")
if err != nil {
return nil, err
}
if m.SaveJSONMeta {
err = storeCertificateMeta(ctx, m.Cache, certName, cert)
if err != nil {
return nil, err
}
}
return nil, err
return cert, nil
}

func (m *Manager) renewCertInBackground(ctx context.Context, certName certNameType) {
Expand Down Expand Up @@ -585,11 +597,11 @@ func (m *Manager) deleteCertToken(ctx context.Context, key DomainName) {

// It isn't atomic syncronized - caller must not save two certificates with same name same time
func storeCertificate(ctx context.Context, cache cache.Cache, certName certNameType,
cert *tls.Certificate) {
cert *tls.Certificate) error {
logger := zc.L(ctx)
if cache == nil {
logger.Debug("Can't save certificate to nil cache")
return
return nil
}

locked, _ := isCertLocked(ctx, cache, certName)
Expand All @@ -605,7 +617,7 @@ func storeCertificate(ctx context.Context, cache cache.Cache, certName certNameT
err := pem.Encode(&certBuf, &pemBlock)
if err != nil {
logger.DPanic("Can't encode pem block of certificate", zap.Error(err), zap.Binary("block", block))
return
return err
}
}

Expand All @@ -619,11 +631,11 @@ func storeCertificate(ctx context.Context, cache cache.Cache, certName certNameT
err := pem.Encode(&privateKeyBuf, &pemBlock)
if err != nil {
logger.DPanic("Can't marshal rsa private key", zap.Error(err))
return
return err
}
default:
logger.DPanic("Unknow private key type", zap.String("type", reflect.TypeOf(cert.PrivateKey).String()))
return
return errors.New("unknow private key type")
}

if keyType == "" {
Expand All @@ -636,14 +648,30 @@ func storeCertificate(ctx context.Context, cache cache.Cache, certName certNameT
err := cache.Put(ctx, certKeyName, certBuf.Bytes())
if err != nil {
logger.Error("Can't store certificate file", zap.Error(err))
return
return err
}

err = cache.Put(ctx, keyKeyName, privateKeyBuf.Bytes())
if err != nil {
_ = cache.Delete(ctx, certKeyName)
logger.Error("Can't store certificate key file", zap.Error(err))
return err
}
return nil
}

func storeCertificateMeta(ctx context.Context, storage cache.Cache, key certNameType, certificate *tls.Certificate) error {
info := struct {
Domains []string
ExpireDate time.Time
}{
Domains: certificate.Leaf.DNSNames,
ExpireDate: certificate.Leaf.NotAfter,
}
infoBytes, _ := json.MarshalIndent(info, "", " ")
err := storage.Put(ctx, key.String()+".json", infoBytes)
log.DebugDPanicCtx(ctx, err, "Save cert metadata")
return err
}

func getCertificate(ctx context.Context, cache cache.Cache, certName certNameType, keyType keyType) (cert *tls.Certificate, err error) {
Expand Down

0 comments on commit 3a14518

Please sign in to comment.