Skip to content

Commit

Permalink
Add support for save metadata from file.
Browse files Browse the repository at this point in the history
Fix ignore issue timeout from config file.
Remove config of subdomains (really doeasn't supported now).

Close #64
  • Loading branch information
rekby committed May 20, 2019
1 parent 4988e8a commit 0113468
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 0113468

Please sign in to comment.