Rack state re-pins rollcall.ca in stored boot entries
Commission, deploy and stateless entries are stored with the root's fingerprint of the moment; after a rotation switch a machine booting from one refused its rack. The state now writes the root the rack serves. Found in the lab rotation (node002's entry on pxe-rack2). Refs #12 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2f708e8f69
commit
a9235c85d8
3 files changed
+25
No files matched your search
@@ -33,6 +33,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -671,3 +672,8 @@ func (r *rackd) stageBundle(t *rackTrustState, trust []*x509.Certificate) error
|
||||
}
|
||||
return writeAtomic(filepath.Join(dir, "ca-ready"), []byte("1\n"), 0o644)
|
||||
}
|
||||
|
||||
var caWordRe = regexp.MustCompile(`\brollcall\.ca=[0-9a-fA-F]{64}\b`)
|
||||
|
||||
// pinCA points the rollcall.ca= words of a boot entry at the root fp.
|
||||
func pinCA(entry, fp string) string { return caWordRe.ReplaceAllString(entry, "rollcall.ca="+fp) }
|
||||
@@ -176,3 +176,15 @@ func TestCARefreshScript(t *testing.T) {
|
||||
t.Fatal("shQuote")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPinCA(t *testing.T) {
|
||||
old, nw := strings.Repeat("7e", 32), strings.Repeat("a1", 32)
|
||||
in := "LABEL deploy\n APPEND initrd=x rollcall.tls=https://10.213.78.1 rollcall.ca=" + old + " quiet\n APPEND rollcall.ca=" + old + "\n"
|
||||
got := pinCA(in, nw)
|
||||
if strings.Contains(got, old) || strings.Count(got, "rollcall.ca="+nw) != 2 || !strings.Contains(got, "rollcall.tls=https://10.213.78.1 rollcall.ca="+nw+" quiet") {
|
||||
t.Fatalf("%q", got)
|
||||
}
|
||||
if pinCA("APPEND rollcall.server=x", nw) != "APPEND rollcall.server=x" {
|
||||
t.Fatal("changed an entry without rollcall.ca")
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"crypto/subtle"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -488,6 +489,12 @@ func (a *App) rackState(ctx context.Context, name string) (*rackState, error) {
|
||||
if st.PXE, err = a.store.PXEFiles(ctx, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if a.ca != nil { // entries keep the root they were written with; a rotation moves it
|
||||
fp := certFingerprint(a.serverCAFor(base))
|
||||
for k, v := range st.PXE {
|
||||
st.PXE[k] = pinCA(v, hex.EncodeToString(fp[:]))
|
||||
}
|
||||
}
|
||||
subnets, err := a.store.Subnets(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in new issue
Block a user