certstore

package
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 31, 2026 License: Apache-2.0 Imports: 45 Imported by: 0

Documentation

Overview

Package certstore implements an HTTP provider for solving the HTTP-01 challenge.

Challenges are held in local process memory rather than in the memberlist ring: the ACME HTTP-01 token is a random, single-use value, so storing one KV key per challenge would gossip every ephemeral token cluster-wide and leak a per-key worker goroutine that dskit never reaps. Instead the leader (which runs the ACME order) keeps the key authorization locally, and validation requests that land on a follower are forwarded to the leader (see httpChallengeHandler).

Index

Constants

View Source
const (
	CertificatePrefix = "certificate"
	TokenPrefix       = "token"
	RateLimitPrefix   = "ratelimit"
)

Key prefixes

Variables

View Source
var (
	AcmeClient = make(map[string]*lego.Client)
	// AcmeAccount stores the account data per issuer for creating fresh clients
	AcmeAccount = make(map[string]*Account)
)
View Source
var (
	AmCertificateRingKey = "collectors/certificate"
	AmChallengeRingKey   = "collectors/challenge"
	AmTokenRingKey       = "collectors/token"
	AmStore              *CertStore
)
View Source
var (
	// ErrNotFound is returned when a requested certificate, token or challenge
	// does not exist in the KV ring. Callers should use errors.Is to detect it
	// rather than matching on the error message text.
	ErrNotFound = errors.New("not found")

	// ErrPendingDeletion is returned when an entry still exists in the KV ring
	// but has been marked for deletion (DeletedAt > 0). Callers should use
	// errors.Is to detect it rather than matching on the error message text.
	ErrPendingDeletion = errors.New("pending deletion")
)

Functions

func CheckCertExpiration

func CheckCertExpiration(amStore *CertStore, logger log.Logger) error

func Cleanup

func Cleanup(logger log.Logger, interval time.Duration, certExpDays int, cleanupCertRevokeLastVersion bool)

func CleanupCertificateVersions

func CleanupCertificateVersions(logger log.Logger, certExpDays int, cleanupCertRevokeLastVersion bool)

func CleanupTokens

func CleanupTokens(logger log.Logger)

func CreateRemoteCertificateResource

func CreateRemoteCertificateResource(ctx context.Context, certData *models.Certificate, logger log.Logger) (*models.Certificate, error)

func DeleteRemoteCertificateResource

func DeleteRemoteCertificateResource(ctx context.Context, certData *models.Certificate, logger log.Logger) error

func GenerateCertificateKey

func GenerateCertificateKey(owner, issuer, name, domain string) string

GenerateCertificateKey creates a hierarchical key for certificates in the KV ring.

func GenerateCertificatePath added in v0.8.0

func GenerateCertificatePath(prefix, owner, issuer, name, domain string) string

GenerateCertificatePath builds a slash-separated path. Named certs (name != ""): prefix/owner/name — issuer and domain are in the value, not the key. Unnamed certs: prefix/owner/issuer/domain (backward compatible).

func GenerateRateLimitKey added in v0.7.0

func GenerateRateLimitKey(owner, issuer, name, domain string) string

GenerateRateLimitKey creates a hierarchical key for rate limits. Named certs use name as the stable identifier (issuer and domain excluded); unnamed certs use issuer+domain.

func GenerateTokenKey

func GenerateTokenKey(tokenID string) string

GenerateTokenKey creates a hierarchical key for tokens

func GetCertificateKeysForOwner

func GetCertificateKeysForOwner(owner string) string

GetCertificateKeysForOwner generates a prefix to list all certificates for an owner

func GetCertificateKeysForOwnerAndIssuer

func GetCertificateKeysForOwnerAndIssuer(owner, issuer string) string

GetCertificateKeysForOwnerAndIssuer generates a prefix to list certificates for owner+issuer

func GetTokenKeysForOwner

func GetTokenKeysForOwner(owner string) string

GetTokenKeysForOwner generates a prefix to list all tokens for an owner

func MapInterfaceToCertMap

func MapInterfaceToCertMap(data map[string]interface{}) models.CertMap

func NewAcmeClientForIssuer added in v0.6.7

func NewAcmeClientForIssuer(logger log.Logger, issuer string) (*lego.Client, error)

NewAcmeClientForIssuer creates a fresh lego.Client for the given issuer using the cached account data. This ensures each certificate request gets an isolated client with no residual challenge providers.

func NewHTTPChallengeProviderByName

func NewHTTPChallengeProviderByName(name, config string, logger log.Logger) (challenge.Provider, error)

NewHTTPChallengeProviderByName Factory for HTTP providers.

func NewStatusCodeRetryPolicy

func NewStatusCodeRetryPolicy(customLogger *logrus.Logger, retryStatusCodes []int) retryablehttp.CheckRetry

NewStatusCodeRetryPolicy creates a CheckRetry function that retries on connection errors, 5xx status codes (default behavior), and any additional status codes provided in the `retryStatusCodes` list.

func OnStartup

func OnStartup(logger log.Logger) error

func ParseTokenKey

func ParseTokenKey(key string) (tokenID string, err error)

ParseTokenKey extracts components from a token key

func ReapDeletedRingEntries added in v0.8.1

func ReapDeletedRingEntries(logger log.Logger)

ReapDeletedRingEntries removes certificate and token KV ring entries that were marked for deletion (DeletedAt > 0) more than tombstoneReapAge ago but whose final Delete never completed — for example when the process died between the mark-deleted CAS and the Delete in DeleteCertificate/DeleteToken. Without this sweep such a tombstone lingers forever and GetCertificate/GetToken keep reporting "pending deletion" (HTTP 409).

func RevokeCertificateWithVerification added in v0.6.5

func RevokeCertificateWithVerification(ctx context.Context, logger log.Logger, issuerAcmeClient *lego.Client, certBytes []byte, issuer, owner, domain, name string, version *int) (bool, error)

RevokeCertificateWithVerification revokes a certificate and handles common error cases. Returns (safeToDestroy bool, error):

  • (true, nil): Certificate already revoked/expired in previous cycle - safe to destroy
  • (false, nil): Certificate freshly revoked this cycle - wait for next cycle before destroying
  • (false, error): Revocation failed - do not proceed with destruction

func SaveResource

func SaveResource(logger log.Logger, filepath string, certRes *certificate.Resource)

func Setup

func Setup(logger log.Logger, customLogger *logrus.Logger, cfg config.Config, version string) error

func WatchCertExpiration

func WatchCertExpiration(logger log.Logger, interval time.Duration)

func WatchConfigFileChanges

func WatchConfigFileChanges(logger log.Logger, customLogger *logrus.Logger, interval time.Duration, configPath, version string)

func WatchIssuerHealth

func WatchIssuerHealth(logger log.Logger, customLogger *logrus.Logger, interval time.Duration, version string)

func WatchRateLimitCleanup added in v0.7.0

func WatchRateLimitCleanup(logger log.Logger, interval time.Duration)

WatchRateLimitCleanup periodically cleans up expired rate limit entries. Entries older than the configured rate limit window are deleted to prevent unbounded growth.

func WatchTokenExpiration

func WatchTokenExpiration(logger log.Logger, interval time.Duration)

Types

type Account

type Account struct {
	Email        string                 `json:"email"`
	Registration *registration.Resource `json:"registration"`
	// contains filtered or unexported fields
}

Account represents a users local saved credentials.

func (*Account) GetEmail

func (a *Account) GetEmail() string

GetEmail returns the email address for the account.

func (*Account) GetPrivateKey

func (a *Account) GetPrivateKey() crypto.PrivateKey

GetPrivateKey returns the private RSA account key.

func (*Account) GetRegistration

func (a *Account) GetRegistration() *registration.Resource

GetRegistration returns the server registration.

type CertStore

type CertStore struct {
	RingConfig ring.AcmeManagerRing
	Logger     log.Logger
}

func (*CertStore) DeleteCertificate

func (c *CertStore) DeleteCertificate(owner, issuer, name, domain string) error

Delete certificate marks the entry deleted (CAS sets DeletedAt) and then Deletes it from the ring. These two steps are not atomic: if the process dies between them, a tombstone (DeletedAt > 0) lingers and GetCertificate reports "pending deletion" (409) until the periodic reaper (ReapDeletedRingEntries) removes it. This is an accepted eventual-consistency window.

func (*CertStore) DeleteChallenge

func (c *CertStore) DeleteChallenge(token string) error

DeleteChallenge removes a challenge from local memory.

func (*CertStore) DeleteRateLimit added in v0.7.0

func (c *CertStore) DeleteRateLimit(owner, issuer, name, domain string) error

Delete rate limit

func (*CertStore) DeleteRateLimitByKey added in v0.8.0

func (c *CertStore) DeleteRateLimitByKey(key string) error

DeleteRateLimitByKey deletes a rate limit entry by its full KV key. Used when the key is already known (e.g. from ListAllRateLimits iteration).

func (*CertStore) DeleteToken

func (c *CertStore) DeleteToken(tokenID string) error

Delete token marks the entry deleted (CAS sets DeletedAt) and then Deletes it from the ring. As with DeleteCertificate these steps are not atomic: a crash in between leaves a tombstone (DeletedAt > 0) that GetToken reports as "pending deletion" (409) until the periodic reaper (ReapDeletedRingEntries) removes it. This is an accepted eventual-consistency window.

func (*CertStore) GetCertificate

func (c *CertStore) GetCertificate(owner, issuer, name, domain string) (*models.Certificate, error)

Get certificate

func (*CertStore) GetChallenge

func (c *CertStore) GetChallenge(token string) (string, error)

GetChallenge returns the key authorization for the given token from local memory, wrapping ErrNotFound when absent (matched by the HTTP-01 handler to return 404, and by followers to forward to the leader).

func (*CertStore) GetRateLimit added in v0.7.0

func (c *CertStore) GetRateLimit(owner, issuer, name, domain string) (*models.RateLimit, error)

Get rate limit

func (*CertStore) GetToken

func (c *CertStore) GetToken(tokenID string) (*models.Token, error)

Get token

func (*CertStore) ListAllCertificates

func (c *CertStore) ListAllCertificates() (map[string]*models.Certificate, error)

List all certificates

func (*CertStore) ListAllRateLimits added in v0.7.0

func (c *CertStore) ListAllRateLimits() (map[string]*models.RateLimit, error)

List all rate limits

func (*CertStore) ListAllTokens

func (c *CertStore) ListAllTokens() (map[string]*models.Token, error)

List all tokens

func (*CertStore) ListCertificateKVRingKeys

func (c *CertStore) ListCertificateKVRingKeys(prefix string) ([]string, error)

func (*CertStore) ListCertificatesForOwner

func (c *CertStore) ListCertificatesForOwner(owner string) ([]*models.Certificate, error)

List all certificates for an owner

func (*CertStore) ListRateLimitKVRingKeys added in v0.7.0

func (c *CertStore) ListRateLimitKVRingKeys(prefix string) ([]string, error)

func (*CertStore) ListTokenKVRingKeys

func (c *CertStore) ListTokenKVRingKeys() ([]string, error)

func (*CertStore) PutCertificate

func (c *CertStore) PutCertificate(cert *models.Certificate) error

Store certificate

func (*CertStore) PutChallenge

func (c *CertStore) PutChallenge(token, keyAuth string) error

PutChallenge stores a challenge key authorization in local process memory.

func (*CertStore) PutRateLimit added in v0.7.0

func (c *CertStore) PutRateLimit(rateLimit *models.RateLimit, name string) error

Store rate limit

func (*CertStore) PutToken

func (c *CertStore) PutToken(tokenID string, token *models.Token) error

Store token

type CertificateCollector

type CertificateCollector struct {
	Logger log.Logger
}

func NewCertificateCollector

func NewCertificateCollector(logger log.Logger) *CertificateCollector

func (*CertificateCollector) Collect

func (c *CertificateCollector) Collect(ch chan<- prometheus.Metric)

func (*CertificateCollector) Describe

func (c *CertificateCollector) Describe(_ chan<- *prometheus.Desc)

type HTTPProvider

type HTTPProvider struct {
	// contains filtered or unexported fields
}

HTTPProvider implements lego's challenge.Provider for the `http-01` challenge.

func NewKVRingProvider

func NewKVRingProvider(logger log.Logger) (*HTTPProvider, error)

NewKVRingProvider returns an HTTPProvider instance. The name is kept for config backward-compatibility (challenge provider "kvring"); challenges are now served from local memory with leader forwarding, not from the ring.

func (*HTTPProvider) CleanUp

func (w *HTTPProvider) CleanUp(_ context.Context, _, token, _ string) error

CleanUp removes the challenge for the given token.

func (*HTTPProvider) Present

func (w *HTTPProvider) Present(_ context.Context, _, token, keyAuth string) error

Present makes the token available at `HTTP01ChallengePath(token)`.

type KVCollector added in v0.9.0

type KVCollector struct {
	Logger log.Logger
}

KVCollector reports how many keys the Ring KV store holds per key type.

func NewKVCollector added in v0.9.0

func NewKVCollector(logger log.Logger) *KVCollector

func (*KVCollector) Collect added in v0.9.0

func (c *KVCollector) Collect(ch chan<- prometheus.Metric)

Collect emits one series per key type. Counts include entries that were marked for deletion but not yet garbage-collected: the memberlist KV List is a raw prefix scan over the local store and never inspects the Deleted flag, so tombstones remain visible until ObsoleteEntriesTimeout elapses.

func (*KVCollector) Describe added in v0.9.0

func (c *KVCollector) Describe(_ chan<- *prometheus.Desc)

type NodeCollector

type NodeCollector struct {
	Logger log.Logger
}

func NewNodeCollector

func NewNodeCollector(logger log.Logger) *NodeCollector

func (*NodeCollector) Collect

func (nc *NodeCollector) Collect(ch chan<- prometheus.Metric)

func (*NodeCollector) Describe

func (nc *NodeCollector) Describe(_ chan<- *prometheus.Desc)

type TokenCollector added in v0.9.0

type TokenCollector struct {
	Logger log.Logger
}

func NewTokenCollector added in v0.9.0

func NewTokenCollector(logger log.Logger) *TokenCollector

func (*TokenCollector) Collect added in v0.9.0

func (c *TokenCollector) Collect(ch chan<- prometheus.Metric)

func (*TokenCollector) Describe added in v0.9.0

func (c *TokenCollector) Describe(_ chan<- *prometheus.Desc)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL