Documentation
¶
Overview ¶
Package acme handles the agent side of the per-agent direct-TLS feature (plex.direct model). The agent generates and keeps its private key LOCALLY, builds a CSR for *.<hash>.agent.unarr.app, and sends only the CSR to the web-side broker (which runs the ACME order against Let's Encrypt via DNS-01 and returns the signed chain). The key never leaves the machine.
File layout under the agent state dir:
certs/agent.key ECDSA P-256 private key (PEM, persisted across renewals) certs/agent.crt issued certificate chain (PEM, hot-reloaded by the stream server)
Index ¶
- func BuildCSR(dataDir, hash, baseDomain string) (csrPEM string, err error)
- func GenerateHash() (string, error)
- func NeedsIssue(dataDir, hash, baseDomain string) bool
- func Paths(dataDir string) (keyPath, certPath string)
- func WildcardName(hash, baseDomain string) string
- func WriteCert(dataDir, certPEM string) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildCSR ¶
BuildCSR ensures the persistent key exists and returns a PEM CSR requesting the wildcard *.<hash>.<baseDomain> (plus the bare <hash>.<baseDomain> so a future non-wildcard use still validates). baseDomain e.g. "agent.unarr.app".
func GenerateHash ¶
GenerateHash returns a 32-hex-char (16-byte) high-entropy agent hash label.
func NeedsIssue ¶
NeedsIssue reports whether we should (re)request a cert: true when the cert is missing, unparseable, expired, within renewBefore of expiry, OR issued for a hash other than the current agent hash.
The hash-mismatch case is load-bearing: agent_hash can be regenerated (config reset / identity migration) while the OLD cert — for *.<oldHash>.<base>, not yet expired — stays on disk. The web then encodes every direct-TLS hostname under the NEW hash (<ip>.<newHash>.<base>), so the browser is served a cert whose CN/SAN don't match → TLS validation fails → direct-TLS is silently dead for up to the cert's ~90-day lifetime, forcing every remote https:// browser onto the (flaky) cloudflared funnel. Re-issuing whenever the on-disk cert doesn't cover the wildcard for the CURRENT hash makes direct-TLS self-heal on the next renewal tick. hash/baseDomain empty (direct-TLS not configured) skips the check and keeps the pure expiry semantics.
func WildcardName ¶
WildcardName is THE identity→SAN mapping for the per-agent cert: the wildcard name BuildCSR requests and NeedsIssue asserts on the issued cert. Single source so the two sides (request vs verify) can never drift — a silent drift would make NeedsIssue re-issue on every renewal tick forever.
Types ¶
This section is empty.