Documentation
¶
Index ¶
- Constants
- Variables
- func Due(notAfter, now time.Time, force bool) bool
- func EnsureState(sslDir string) error
- func EnsureWebroot(sslDir string) error
- func Install(ctx context.Context, r InstallReq) (map[string]int, error)
- func Issue(ctx context.Context, r IssueReq) (cert, key string, err error)
- func IssueHTTP01(ctx context.Context, r IssueReq) (cert, key string, err error)
- func Lock(sslDir string, wait time.Duration) (release func(), err error)
- func NeedsTOS(sslDir string, staging bool, contact string) bool
- func ParseINI(data []byte) map[string]string
- func ProbeWebroot(ctx context.Context, sslDir, addr, host string, ...) error
- func Refuse(fix, format string, a ...any) error
- func Repair(sslDir string, targets []string) error
- func Save(sslDir string, f File) error
- func SecretNames(provider string) (names []string, ok bool)
- func StateDir(sslDir string) string
- func ValidTarget(t string) bool
- func WebrootDir(sslDir string) string
- type Certbot
- type Error
- type File
- type Hooks
- type Input
- type InstallReq
- type IssueReq
- type Lineage
- type NginxReloader
- type ProbeFunc
- type Reloader
- type Resolution
Constants ¶
const ( ProdDirectory = "https://acme-v02.api.letsencrypt.org/directory" StagingDirectory = "https://acme-staging-v02.api.letsencrypt.org/directory" )
Directory URLs.
const ( SchemaVersion = "1" ChallengeDNS = "dns-01" RenewWindow = 30 * 24 * time.Hour )
Contract constants; RenewWindow is how close to expiry a lineage is due.
const ChallengeHTTP = "http-01"
ChallengeHTTP is the lineage challenge name for HTTP-01.
const ChallengePrefix = "/.well-known/acme-challenge/"
ChallengePrefix is the URL prefix HTTP-01 uses.
const NginxChallengeLocation = `` /* 663-byte string literal not displayed */
NginxChallengeLocation is the location block (4-space indented, newline terminated) placed in the default server and in every server block that listens on port 80, before any catch-all redirect or proxy. `^~` on the ACME prefix only, so no application path is shadowed; a request is served only when it is a bare token ([A-Za-z0-9_-]+) and a GET or HEAD, and never through a symlink below the webroot.
const WebrootName = ".acme-webroot"
WebrootName is the directory under the served ssl dir that holds challenge files; inside nginx it is NginxSSLContainerPath + "/" + WebrootName.
Variables ¶
var LegoImage = lockedLego()
LegoImage is the pinned ACME client image: goacme/lego at its multi-arch index digest, read from the image lock.
Functions ¶
func Due ¶
Due reports whether a certificate expiring at notAfter is due: force, or 30 days or fewer left.
func EnsureState ¶
EnsureState creates the 0700 state dir and its `*` .gitignore if absent.
func EnsureWebroot ¶
EnsureWebroot creates the webroot and its challenge directory (0755: nginx runs as another user and must traverse it).
func Install ¶
Install writes a new generation per target, switches them, reloads, verifies and prunes. A failure after the switch restores every previous generation.
func IssueHTTP01 ¶
IssueHTTP01 issues r.Domains over HTTP-01 (no wildcard: the CA only validates a wildcard over DNS-01) and returns the certificate and key paths. r.Provider is ignored; r.Secret is never called.
func Lock ¶
Lock takes the exclusive run lock, waiting up to wait, and returns its release func. A busy lock returns an *Error naming the holder's pid.
func ParseINI ¶
ParseINI parses `key = value` lines (`#`/`;` comments, `[sections]` ignored, whitespace trimmed) into one flat map.
func ProbeWebroot ¶
func ProbeWebroot(ctx context.Context, sslDir, addr, host string, get func(*http.Request) (*http.Response, error)) error
ProbeWebroot writes a random token file into the webroot, GETs it from addr (host:port of the served nginx over plain HTTP) with Host: host, and removes it. A nil error means the served nginx answers the challenge location from the webroot. get defaults to a short-timeout HTTP client.
func Repair ¶
Repair re-links each target whose link is missing, dangling or mismatched to its newest valid generation; a real directory (not yet converted) is left.
func SecretNames ¶
SecretNames returns the secret names a provider needs; ok is false for an unknown provider. Provider "exec" (test hook) needs none.
func ValidTarget ¶
ValidTarget reports whether t is a safe lineage target: certificates/<one plain name>, never `.`, empty, absolute, hidden or containing `..`.
Types ¶
type Certbot ¶
Certbot is one certbot lineage as found on disk; Err is set when its live certificate could not be read.
func ReadCertbot ¶
ReadCertbot lists the lineages under dir (renewal/*.conf), sorted by name.
type File ¶
type File struct {
SchemaVersion string `json:"schema_version"`
Contact string `json:"contact"`
Lineages []Lineage `json:"lineages"`
}
File is the lineages.json document.
type Hooks ¶
type Hooks struct{ Directory, CABundle, Network, Resolvers, Fault string }
Hooks are the test-only knobs read from NSELF_ACME_*.
type Input ¶
type Input struct {
ProjectDir, FrontedBy, ProjectName, NginxContainer, Contact, AgeKeyPath string
// NoSecrets is set for runs that handle no DNS credential (HTTP-01): `age` and the age key are not required.
NoSecrets bool
FindNginx func(context.Context, docker.ServiceMatch) (string, error)
Mounts func(context.Context, string) ([]docker.Mount, error)
LookPath func(string) (string, error)
}
Input is what Resolve needs; the func fields default to the docker funnel and exec.LookPath.
type InstallReq ¶
type InstallReq struct {
SSLDir string
Targets []string // dirs relative to SSLDir, e.g. certificates/api-example-org
Cert, Key []byte
Reloader Reloader
Verify func(context.Context) error
Fault string
Exit func(int)
}
InstallReq is one install of one certificate into one or more targets. Verify (optional) runs after the reload; Fault and Exit are the test hook.
type IssueReq ¶
type IssueReq struct {
SSLDir, Name, Provider, Contact string
Domains []string
Staging, AcceptTOS bool
Hooks Hooks
Secret func(name string) (string, error)
Run func(context.Context, docker.RunSpec) (string, string, error)
}
IssueReq describes one issuance. AcceptTOS adds --accept-tos (set only when NeedsTOS and the terms were agreed); Secret reads the secret store.
type Lineage ¶
type Lineage struct {
Name string `json:"name"`
Domains []string `json:"domains"`
Challenge string `json:"challenge"`
DNSProvider string `json:"dns_provider"`
CredentialSecrets []string `json:"credential_secrets"`
Targets []string `json:"targets"`
KeyType string `json:"key_type"`
AdoptedFrom *string `json:"adopted_from"`
LastIssued *string `json:"last_issued"`
}
Lineage is one managed certificate.
func Plan ¶
func Plan(cbs []Certbot, hosts map[string]string, provider, only string) (adopt []Lineage, refused []string)
Plan maps certbot lineages onto served targets. provider is the DNS provider of the supplied credential ("" when none); only, when set, limits adoption to that lineage. Refusals are "<name>: <reason and remediation>".
func PlanWith ¶
func PlanWith(cbs []Certbot, hosts map[string]string, provider, only string, probe ProbeFunc) (adopt []Lineage, refused []string)
PlanWith is Plan with an HTTP-01 probe. With a probe, a webroot lineage and no DNS credential, every name is probed: all answering adopts the lineage as http-01, any failure refuses it with the remediation.
type NginxReloader ¶
type NginxReloader struct {
Container string
Exec func(ctx context.Context, container string, cmd []string) (string, string, error)
}
NginxReloader runs `nginx -t` then `nginx -s reload` in Container (Exec defaults to docker.ExecCapture; no socket, no restart).
type ProbeFunc ¶
ProbeFunc reports whether the served nginx answers the HTTP-01 challenge location for host (see ProbeWebroot); nil means http-01 adoption is off.
type Resolution ¶
type Resolution struct{ Root, SSLDir, NginxDir, Container, Contact, AgeBin, AgeKey string }
Resolution is the printed answer to "where does this write, who reloads".
func Resolve ¶
func Resolve(ctx context.Context, in Input) (*Resolution, error)
Resolve runs the preflight list in order and returns the first failure.
func (*Resolution) Print ¶
func (r *Resolution) Print(w io.Writer)
Print writes the resolution, one fact per line.