Adding secure NTP
This commit is contained in:
+34
-5
@@ -164,6 +164,18 @@ variable "audit_host" {
|
||||
default = "audit.fleet.lab"
|
||||
}
|
||||
|
||||
variable "secure_ntp" {
|
||||
type = bool
|
||||
description = "true (default): SECURE, CA-AUTHENTICATED time via NTS (RFC 8915). The NM dispatcher derives the NTP server name at runtime as <ntp_prefix>.<DHCP-provided-domain> (NO FQDN baked — the domain can change without a rebuild) and chrony verifies the server's NTS-KE TLS cert against the fleet CA (/etc/dot1x/radius-ca.pem — same anchor as RADIUS/agent). A DHCP/NTP/DNS spoofer can then only DoS (cause no-sync), never shift the clock to resurrect expired/revoked certs (closes F-03/P-18; docs/secure-ntp-design.md). The serving NTP server needs a fleet-signed NTS cert with SAN <ntp_prefix>.<domain> (serving/chrony/nts-cert.sh). false: legacy UNAUTHENTICATED DHCP option-42 NTP (the dispatcher writes the handed IPs) — lab/interop only."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "ntp_prefix" {
|
||||
type = string
|
||||
description = "secure_ntp=true only: the label prepended to the DHCP-provided domain to form the NTS NTP server name (<ntp_prefix>.<domain>, e.g. ntp.fleet.lab). Deliberately NOT a full FQDN — only this label + the fleet CA are baked, so the environment's domain can change (new DHCP domain + reissued NTS cert) without rebuilding the image. Must match the serving NTS cert SAN and resolve via dnsmasq."
|
||||
default = "ntp"
|
||||
}
|
||||
|
||||
variable "sb_key" {
|
||||
type = string
|
||||
description = "Secure Boot signing key (PEM) for the UKI. Empty = unsigned lab build. Production: CI/HSM-held; never enters the build VM."
|
||||
@@ -413,15 +425,32 @@ build {
|
||||
# secure mode, reserving the physical NIC for wpa_supplicant.
|
||||
"chmod 0755 /usr/lib/dracut/modules.d/95dot1x-macsec/*.sh",
|
||||
|
||||
# ---- NTP from DHCP (option 42) -> chrony, no public-pool egress --------
|
||||
# NM dispatcher writes DHCP-provided NTP servers into chrony's sourcedir
|
||||
# (replaces the removed dhclient.d/chrony.sh bridge). Strip the baked public
|
||||
# pool so the host syncs ONLY from the lab NTP server handed via DHCP — the
|
||||
# workstation never reaches *.pool.ntp.org.
|
||||
# ---- NTP: CA-authenticated NTS (default) or legacy DHCP option 42 ------
|
||||
# BOTH modes run through the SAME machinery: the NM dispatcher writes a
|
||||
# source file into chrony's `sourcedir /run/chrony-dhcp`; the baked public
|
||||
# pool is stripped so the host never egresses to *.pool.ntp.org.
|
||||
# secure_ntp=true (NTS): the dispatcher derives the server NAME at runtime
|
||||
# as <ntp_prefix>.<DHCP-provided-domain> and writes `server NAME iburst
|
||||
# nts`. chrony verifies the NTS-KE TLS cert against the FLEET CA
|
||||
# (ntstrustedcerts below). NOTHING host- or domain-specific is baked
|
||||
# (only the `ntp` label + the CA) — the domain can change without a
|
||||
# rebuild. A DHCP/NTP/DNS spoofer can only DoS; it can't present a
|
||||
# fleet-CA-signed cert for the name it redirects to, so it can't shift
|
||||
# the clock (F-03/P-18). No fallback to unauthenticated time.
|
||||
# nocerttimecheck 1: a diskless host may boot with a bad/epoch clock (no
|
||||
# reliable RTC), failing the cert validity window (chicken-and-egg);
|
||||
# allow the FIRST measurement without the cert-time check to bootstrap,
|
||||
# then enforce. Isolated LAN + one-measurement window bound the trade-off.
|
||||
# secure_ntp=false (legacy): the dispatcher writes the DHCP option-42 IPs
|
||||
# as plain `server <ip> iburst` — UNAUTHENTICATED, lab/interop only.
|
||||
# The dispatcher is mode-aware via baked @NTP_MODE@/@NTP_PREFIX@ tokens.
|
||||
"install -D -m0755 /tmp/etc-stage/NetworkManager/dispatcher.d/10-chrony-dhcp-ntp /etc/NetworkManager/dispatcher.d/10-chrony-dhcp-ntp",
|
||||
"if [ \"${var.secure_ntp}\" = \"true\" ]; then NTP_MODE=nts; else NTP_MODE=dhcp; fi",
|
||||
"sed -i \"s/@NTP_MODE@/$NTP_MODE/; s/@NTP_PREFIX@/${var.ntp_prefix}/\" /etc/NetworkManager/dispatcher.d/10-chrony-dhcp-ntp",
|
||||
"restorecon /etc/NetworkManager/dispatcher.d/10-chrony-dhcp-ntp",
|
||||
"sed -i -E 's/^[[:space:]]*(pool|server)[[:space:]]/#&/' /etc/chrony.conf",
|
||||
"grep -q '^sourcedir /run/chrony-dhcp' /etc/chrony.conf || echo 'sourcedir /run/chrony-dhcp' >> /etc/chrony.conf",
|
||||
"if [ \"${var.secure_ntp}\" = \"true\" ]; then echo '==> secure NTP: NTS via <${var.ntp_prefix}>.<dhcp-domain> (fleet-CA-authenticated)'; { printf '\\n# Secure NTP (NTS, RFC 8915) — verify the server against the fleet CA. docs/secure-ntp-design.md\\n'; printf 'ntstrustedcerts /etc/dot1x/radius-ca.pem\\n'; printf 'nocerttimecheck 1\\n'; } >> /etc/chrony.conf; else echo '==> legacy NTP: unauthenticated DHCP option-42'; fi",
|
||||
# Enable chrony's tracking log so the fleet-agent can report clock health
|
||||
# (source/stratum/offset) WITHOUT touching chronyd's command interface. That
|
||||
# interface is unusable by the hardened agent: the unix socket is
|
||||
|
||||
Reference in New Issue
Block a user