1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
As an `Operator`, I want to `use the ACME protocol`, so that `I have a standards based way to manage PKI`.
# SYNOPSIS
Use the ACME protocol to generate TLS PKI.
# DESCRIPTION
Below is an example startup configuration for using the ACME protocol in golang
and distributing the key material using file storage. The file storage should be
replaced with a distributed blob storage that is locked down. This also uses
the `STEPPATH` environment variable to access an internal root certificate
authority.
```golang
func WithAcmeTLS(ctx context.Context, directoryURL string, cacheDir string) cfg.Option {
storageFor := func(config *cfg.Config) certmagic.Storage {
return &certmagic.FileStorage{Path: cacheDir}
}
return func(config *cfg.Config) {
host := os.Getenv("HOST")
tls := srv.NewTLS(ctx, host, storageFor(config), []certmagic.ACMEIssuer{
{
Agreed: true,
CA: directoryURL,
DisableHTTPChallenge: true,
Email: "everyone@example.com",
TestCA: directoryURL,
TrustedRoots: newCertPool(),
AltTLSALPNPort: bindingPort(),
},
})
config.TLS = x.Must(tls.Config())
}
}
func newCertPool() *x509.CertPool {
certPool := x.Must(x509.SystemCertPool())
certPool.AddCert(func() *x509.Certificate {
block, _ := pem.Decode(x.Must(ioutil.ReadFile(
filepath.Join(os.ExpandEnv("$STEPPATH"), "/certs/root_ca.crt"),
)))
return x.Must(x509.ParseCertificate(block.Bytes))
}())
return certPool
}
func bindingPort() int {
parts := strings.SplitN(os.Getenv("BIND_ADDR"), ":", 2)
bindPort, err := strconv.Atoi(parts[1])
if err != nil {
bindPort = 0
}
return bindPort
}
```
# SEE ALSO
* [RFC-8555](https://datatracker.ietf.org/doc/html/rfc8555)
* [$STEPPATH](https://smallstep.com/docs/step-cli/reference/path/#examples)
# Tasks
* [ ] TBD
# Acceptance Criteria
* [ ] TBD
|