enrol-broker: run in serving stack + fix step signer path end-to-end
Verifying the step signer against a real step-ca surfaced two real bugs the mock signer had hidden, plus made the bench CA actually initialise: - signer.go: move --not-after from `step ca token` (validity caps ~1h -> "token validity too long") to `step ca sign` (it is the CERT lifetime). Without this the step signer never issues a cert. - dot1x-bench compose: DOCKER_STEPCA_INIT_PASSWORD_FILE pointed at a file that does not exist at first init (it is an INPUT path), so `step ca init` failed and never wrote secrets/password. Use DOCKER_STEPCA_INIT_PASSWORD (the value) which the entrypoint writes to secrets/password, where bootstrap + broker read. - bootstrap.sh: self-heal the root-owned ./pki Docker auto-creates; detect the CA password at $STEPPATH/password or secrets/password (varies by image version); raise authority.claims.maxTLSCertDuration so 720h fleet certs are allowed (stock cap 24h, which also blocked bootstrap's own RADIUS cert); fix RADIUS cert paths to write via the /export mount (were host paths run inside the container, so they never resolved). - serving stack: add the enrol-broker service (temporary home; nginx already proxies /enrol/) defaulting to the zero-dependency lab path (mock signer + insecure loopback admin), with ENROL_* knobs to switch to step + mTLS. - verify-serving.sh: exercise request -> approve -> cert through the deployed nginx /enrol/ proxy. - TODO #11: record the step-signer verification + the two fixes. Step signer VERIFIED end-to-end against a real step-ca: issued cert chains to the fleet root, EKU clientAuth, hostnqn derived from serial.
This commit is contained in:
@@ -66,30 +66,35 @@ func (s *stepSigner) Sign(ctx context.Context, csrPEM, cn string) (string, strin
|
||||
}
|
||||
|
||||
// 1. one-time token (subject MUST equal the CSR CN for the JWK provisioner).
|
||||
tokArgs := []string{
|
||||
// NOTE: token validity is the short-lived authorization window (a JWK
|
||||
// provisioner caps it at ~1h), NOT the issued cert's lifetime — do not put
|
||||
// s.notAfter here or a multi-day value fails "token validity too long".
|
||||
token, err := s.run(ctx,
|
||||
"ca", "token", cn,
|
||||
"--provisioner", s.provisioner,
|
||||
"--ca-url", s.caURL,
|
||||
"--root", s.root,
|
||||
"--provisioner-password-file", s.passwordFile,
|
||||
}
|
||||
if s.notAfter != "" {
|
||||
tokArgs = append(tokArgs, "--not-after", s.notAfter)
|
||||
}
|
||||
token, err := s.run(ctx, tokArgs...)
|
||||
)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("step ca token: %w", err)
|
||||
}
|
||||
token = strings.TrimSpace(token)
|
||||
|
||||
// 2. sign the CSR with that token.
|
||||
if _, err := s.run(ctx,
|
||||
// 2. sign the CSR with that token. The issued CERT's lifetime is set HERE
|
||||
// (must be <= the provisioner's maxTLSCertDuration claim, else step-ca
|
||||
// rejects it — raise that claim on the CA for multi-day fleet certs).
|
||||
signArgs := []string{
|
||||
"ca", "sign", csrPath, outPath,
|
||||
"--token", token,
|
||||
"--ca-url", s.caURL,
|
||||
"--root", s.root,
|
||||
"--force",
|
||||
); err != nil {
|
||||
}
|
||||
if s.notAfter != "" {
|
||||
signArgs = append(signArgs, "--not-after", s.notAfter)
|
||||
}
|
||||
if _, err := s.run(ctx, signArgs...); err != nil {
|
||||
return "", "", fmt.Errorf("step ca sign: %w", err)
|
||||
}
|
||||
certPEM, err := os.ReadFile(outPath)
|
||||
|
||||
Reference in New Issue
Block a user