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
- Variables
- func CheckCertExpiration(amStore *CertStore, logger log.Logger) error
- func Cleanup(logger log.Logger, interval time.Duration, certExpDays int, ...)
- func CleanupCertificateVersions(logger log.Logger, certExpDays int, cleanupCertRevokeLastVersion bool)
- func CleanupTokens(logger log.Logger)
- func CreateRemoteCertificateResource(ctx context.Context, certData *models.Certificate, logger log.Logger) (*models.Certificate, error)
- func DeleteRemoteCertificateResource(ctx context.Context, certData *models.Certificate, logger log.Logger) error
- func GenerateCertificateKey(owner, issuer, name, domain string) string
- func GenerateCertificatePath(prefix, owner, issuer, name, domain string) string
- func GenerateRateLimitKey(owner, issuer, name, domain string) string
- func GenerateTokenKey(tokenID string) string
- func GetCertificateKeysForOwner(owner string) string
- func GetCertificateKeysForOwnerAndIssuer(owner, issuer string) string
- func GetTokenKeysForOwner(owner string) string
- func MapInterfaceToCertMap(data map[string]interface{}) models.CertMap
- func NewAcmeClientForIssuer(logger log.Logger, issuer string) (*lego.Client, error)
- func NewHTTPChallengeProviderByName(name, config string, logger log.Logger) (challenge.Provider, error)
- func NewStatusCodeRetryPolicy(customLogger *logrus.Logger, retryStatusCodes []int) retryablehttp.CheckRetry
- func OnStartup(logger log.Logger) error
- func ParseTokenKey(key string) (tokenID string, err error)
- func ReapDeletedRingEntries(logger log.Logger)
- func RevokeCertificateWithVerification(ctx context.Context, logger log.Logger, issuerAcmeClient *lego.Client, ...) (bool, error)
- func SaveResource(logger log.Logger, filepath string, certRes *certificate.Resource)
- func Setup(logger log.Logger, customLogger *logrus.Logger, cfg config.Config, ...) error
- func WatchCertExpiration(logger log.Logger, interval time.Duration)
- func WatchConfigFileChanges(logger log.Logger, customLogger *logrus.Logger, interval time.Duration, ...)
- func WatchIssuerHealth(logger log.Logger, customLogger *logrus.Logger, interval time.Duration, ...)
- func WatchRateLimitCleanup(logger log.Logger, interval time.Duration)
- func WatchTokenExpiration(logger log.Logger, interval time.Duration)
- type Account
- type CertStore
- func (c *CertStore) DeleteCertificate(owner, issuer, name, domain string) error
- func (c *CertStore) DeleteChallenge(token string) error
- func (c *CertStore) DeleteRateLimit(owner, issuer, name, domain string) error
- func (c *CertStore) DeleteRateLimitByKey(key string) error
- func (c *CertStore) DeleteToken(tokenID string) error
- func (c *CertStore) GetCertificate(owner, issuer, name, domain string) (*models.Certificate, error)
- func (c *CertStore) GetChallenge(token string) (string, error)
- func (c *CertStore) GetRateLimit(owner, issuer, name, domain string) (*models.RateLimit, error)
- func (c *CertStore) GetToken(tokenID string) (*models.Token, error)
- func (c *CertStore) ListAllCertificates() (map[string]*models.Certificate, error)
- func (c *CertStore) ListAllRateLimits() (map[string]*models.RateLimit, error)
- func (c *CertStore) ListAllTokens() (map[string]*models.Token, error)
- func (c *CertStore) ListCertificateKVRingKeys(prefix string) ([]string, error)
- func (c *CertStore) ListCertificatesForOwner(owner string) ([]*models.Certificate, error)
- func (c *CertStore) ListRateLimitKVRingKeys(prefix string) ([]string, error)
- func (c *CertStore) ListTokenKVRingKeys() ([]string, error)
- func (c *CertStore) PutCertificate(cert *models.Certificate) error
- func (c *CertStore) PutChallenge(token, keyAuth string) error
- func (c *CertStore) PutRateLimit(rateLimit *models.RateLimit, name string) error
- func (c *CertStore) PutToken(tokenID string, token *models.Token) error
- type CertificateCollector
- type HTTPProvider
- type KVCollector
- type NodeCollector
- type TokenCollector
Constants ¶
const ( CertificatePrefix = "certificate" TokenPrefix = "token" RateLimitPrefix = "ratelimit" )
Key prefixes
Variables ¶
var ( AcmeClient = make(map[string]*lego.Client) // AcmeAccount stores the account data per issuer for creating fresh clients AcmeAccount = make(map[string]*Account) )
var ( AmCertificateRingKey = "collectors/certificate" AmChallengeRingKey = "collectors/challenge" AmTokenRingKey = "collectors/token" AmStore *CertStore )
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 CleanupTokens ¶
func CreateRemoteCertificateResource ¶
func CreateRemoteCertificateResource(ctx context.Context, certData *models.Certificate, logger log.Logger) (*models.Certificate, error)
func GenerateCertificateKey ¶
GenerateCertificateKey creates a hierarchical key for certificates in the KV ring.
func GenerateCertificatePath ¶ added in v0.8.0
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
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 ¶
GenerateTokenKey creates a hierarchical key for tokens
func GetCertificateKeysForOwner ¶
GetCertificateKeysForOwner generates a prefix to list all certificates for an owner
func GetCertificateKeysForOwnerAndIssuer ¶
GetCertificateKeysForOwnerAndIssuer generates a prefix to list certificates for owner+issuer
func GetTokenKeysForOwner ¶
GetTokenKeysForOwner generates a prefix to list all tokens for an owner
func MapInterfaceToCertMap ¶
func NewAcmeClientForIssuer ¶ added in v0.6.7
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 ParseTokenKey ¶
ParseTokenKey extracts components from a token key
func ReapDeletedRingEntries ¶ added in v0.8.1
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 WatchConfigFileChanges ¶
func WatchIssuerHealth ¶
func WatchRateLimitCleanup ¶ added in v0.7.0
WatchRateLimitCleanup periodically cleans up expired rate limit entries. Entries older than the configured rate limit window are deleted to prevent unbounded growth.
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) 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 ¶
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 ¶
DeleteChallenge removes a challenge from local memory.
func (*CertStore) DeleteRateLimit ¶ added in v0.7.0
Delete rate limit
func (*CertStore) DeleteRateLimitByKey ¶ added in v0.8.0
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 ¶
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 ¶
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
Get rate limit
func (*CertStore) ListAllCertificates ¶
func (c *CertStore) ListAllCertificates() (map[string]*models.Certificate, error)
List all certificates
func (*CertStore) ListAllRateLimits ¶ added in v0.7.0
List all rate limits
func (*CertStore) ListAllTokens ¶
List all tokens
func (*CertStore) ListCertificateKVRingKeys ¶
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 (*CertStore) ListTokenKVRingKeys ¶
func (*CertStore) PutCertificate ¶
func (c *CertStore) PutCertificate(cert *models.Certificate) error
Store certificate
func (*CertStore) PutChallenge ¶
PutChallenge stores a challenge key authorization in local process memory.
func (*CertStore) PutRateLimit ¶ added in v0.7.0
Store rate limit
type CertificateCollector ¶
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.
type KVCollector ¶ added in v0.9.0
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 ¶
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
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)