mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-19 10:52:04 +00:00
fix(ovn): pin OVS system-id to hostname for IPsec cert identity match
ovs-monitor-ipsec uses chassis-id as the IKEv2 `@<name>` peer identity in the strongSwan config it generates. Our per-node IPsec peer cert (admin.GenerateIPSecPeerCert) carries the node name as CN + dnsName SAN. With chassis-id left at the package-generated UUID, charon validates `@<UUID>` against a cert with dnsName=<hostname> — mismatch returns AUTHENTICATION_FAILED and no xfrm SAs are negotiated. Pin system-id to hostname (which equals the node name on Mulga clusters) by writing both the on-disk source of truth (/etc/openvswitch/system-id.conf, read by ovs-ctl on boot) and the running OVS DB value. Writing only one would drift on the next reboot — the original "do not override" comment was right about that hazard, just wrong about the resolution. Cross-link the invariant in admin/ipsec.go: changing the cert identity without updating setup-ovn.sh (or vice versa) breaks IKE silently. Refs: mulga-siv-136
This commit is contained in:
+20
-5
@@ -597,11 +597,26 @@ else
|
||||
external_ids:ovn-encap-type="geneve"
|
||||
fi
|
||||
|
||||
# system-id is owned by the openvswitch-switch package (persisted in
|
||||
# /etc/openvswitch/system-id.conf and re-applied on every boot). Read it back
|
||||
# rather than overriding — overriding here would drift from the on-disk value
|
||||
# and the next reboot would silently flip the chassis identity (mulga-999).
|
||||
echo " system-id: $(sudo ovs-vsctl get open . external_ids:system-id)"
|
||||
# Pin OVS system-id (= OVN chassis-id) to the node's hostname. Two reasons:
|
||||
# 1. IPsec identity: ovs-monitor-ipsec uses chassis-id as the IKEv2
|
||||
# `@<name>` peer identity. Our per-node IPsec peer cert
|
||||
# (admin.GenerateIPSecPeerCert) carries the node name as CN + dnsName
|
||||
# SAN — see spx admin init/join, which pass --node as the cert
|
||||
# identity. Leaving chassis-id as the package-generated UUID would
|
||||
# cause `received AUTHENTICATION_FAILED` because charon validates
|
||||
# `@<UUID>` against a cert dnsName=<hostname>.
|
||||
# 2. Ops legibility: `ovn-sbctl show` lists chassis by name, not UUID.
|
||||
# Both the on-disk file (read by ovs-ctl on boot) and the running OVS DB
|
||||
# value must be updated atomically — writing only one drifts on the next
|
||||
# reboot.
|
||||
NODE_SYSTEM_ID="$(hostname -s)"
|
||||
if [ -z "$NODE_SYSTEM_ID" ]; then
|
||||
echo " ERROR: hostname -s returned empty; cannot pin OVS system-id." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "$NODE_SYSTEM_ID" | sudo tee /etc/openvswitch/system-id.conf >/dev/null
|
||||
sudo ovs-vsctl set Open_vSwitch . external_ids:system-id="$NODE_SYSTEM_ID"
|
||||
echo " system-id: $NODE_SYSTEM_ID (pinned to hostname for IPsec cert identity)"
|
||||
echo " ovn-remote: $OVN_REMOTE"
|
||||
echo " ovn-encap-ip: $ENCAP_IP"
|
||||
echo " ovn-encap-type: geneve"
|
||||
|
||||
@@ -48,6 +48,15 @@ func IPSecCertPaths(configDir string) (certPath, keyPath string) {
|
||||
// SANs discovered from the local machine's interfaces are not added here —
|
||||
// IPSec peer identity should be the explicit cluster identity only, not
|
||||
// every interface address, to keep peer-identity matching strict.
|
||||
//
|
||||
// Cross-cutting invariant: this dnsName SAN must equal the OVS chassis-id
|
||||
// (Open_vSwitch.external_ids:system-id) on every node, because
|
||||
// ovs-monitor-ipsec generates strongSwan configs with leftid=@<chassis-id>
|
||||
// / rightid=@<chassis-id> and charon validates those names against the
|
||||
// peer cert's dnsName SAN. setup-ovn.sh pins system-id to `hostname -s`
|
||||
// for exactly this reason — see the comment in setup-ovn.sh near
|
||||
// `system-id.conf`. Changing the cert identity here without updating
|
||||
// setup-ovn.sh (or vice versa) breaks IKE with AUTHENTICATION_FAILED.
|
||||
// GenerateIPSecPeerCertIfEnabled is a no-op when enabled is false. Used by
|
||||
// admin init and admin join so the call site reads as a single guarded line
|
||||
// keyed off the cluster's network.ipsec_enabled flag.
|
||||
|
||||
Reference in New Issue
Block a user