Adding secure NTP
This commit is contained in:
@@ -1,16 +1,30 @@
|
||||
#!/bin/bash
|
||||
# NetworkManager dispatcher: feed DHCP option 42 (NTP servers) into chrony.
|
||||
# NetworkManager dispatcher: point chrony at the fleet NTP server, learned from
|
||||
# DHCP at runtime (no FQDN baked into the image). Two modes, baked at build time:
|
||||
#
|
||||
# Replaces the old dhclient.d/chrony.sh bridge — we use NetworkManager's internal
|
||||
# DHCP now (the network-manager dracut port), and NM exports the lease's NTP
|
||||
# servers to dispatcher scripts as $DHCP4_NTP_SERVERS. chrony.conf carries
|
||||
# `sourcedir /run/chrony-dhcp`, so writing <iface>.sources there and reloading
|
||||
# makes chronyd use the DHCP-provided server. The image's baked public pool is
|
||||
# stripped (see the provisioner), so the host syncs ONLY from the lab NTP server
|
||||
# — no time egress from the workstation.
|
||||
# nts (secure_ntp=true, default): AUTHENTICATED time. Derive the server NAME
|
||||
# from the DHCP-provided domain as <PREFIX>.<domain> and write
|
||||
# `server NAME iburst nts`. chrony verifies the NTS-KE TLS cert against the
|
||||
# fleet CA (chrony.conf: ntstrustedcerts). Because the domain comes from
|
||||
# DHCP, a domain change needs only a new DHCP domain + reissued NTS cert —
|
||||
# no image rebuild. A DHCP/NTP/DNS spoofer can only DoS (no fleet-CA-signed
|
||||
# cert for the name it redirects to => NTS fails => no sync); it cannot
|
||||
# shift the clock. See docs/secure-ntp-design.md (F-03/P-18).
|
||||
#
|
||||
# Installed 0755 root:root at /etc/NetworkManager/dispatcher.d/. Lenient on
|
||||
# purpose: a hiccup here must never break networking.
|
||||
# dhcp (secure_ntp=false): LEGACY, UNAUTHENTICATED. Write the DHCP option-42
|
||||
# server IPs as plain `server <ip> iburst`. Lab/interop only.
|
||||
#
|
||||
# We use NetworkManager's internal DHCP (the network-manager dracut port); NM
|
||||
# exports the lease's domain as $DHCP4_DOMAIN_NAME (option 15) / $DHCP4_DOMAIN_SEARCH
|
||||
# (option 119) and NTP servers as $DHCP4_NTP_SERVERS (option 42). chrony.conf
|
||||
# carries `sourcedir /run/chrony-dhcp`, so writing <iface>.sources there and
|
||||
# reloading makes chronyd use them. The baked public pool is stripped (provisioner).
|
||||
#
|
||||
# Installed 0755 root:root. Lenient on purpose: a hiccup here must never break
|
||||
# networking. @NTP_MODE@/@NTP_PREFIX@ are substituted at build time.
|
||||
|
||||
MODE="@NTP_MODE@" # nts | dhcp
|
||||
PREFIX="@NTP_PREFIX@" # nts: server name = <PREFIX>.<dhcp-domain>
|
||||
|
||||
interface="$1"
|
||||
action="$2"
|
||||
@@ -24,13 +38,23 @@ dir=/run/chrony-dhcp
|
||||
file="$dir/${interface}.sources"
|
||||
mkdir -p "$dir"
|
||||
|
||||
if [ -n "${DHCP4_NTP_SERVERS:-}" ]; then
|
||||
: > "$file"
|
||||
for s in $DHCP4_NTP_SERVERS; do
|
||||
printf 'server %s iburst\n' "$s" >> "$file"
|
||||
done
|
||||
# Pick up the new sources without restarting chronyd.
|
||||
chronyc reload sources >/dev/null 2>&1 || true
|
||||
if [ "$MODE" = nts ]; then
|
||||
# Prefer option 15 (domain-name); fall back to the first option-119 search domain.
|
||||
domain="${DHCP4_DOMAIN_NAME:-}"
|
||||
[ -z "$domain" ] && domain="${DHCP4_DOMAIN_SEARCH%% *}"
|
||||
if [ -n "$domain" ]; then
|
||||
printf 'server %s.%s iburst nts\n' "$PREFIX" "$domain" > "$file"
|
||||
# Pick up the new source without restarting chronyd.
|
||||
chronyc reload sources >/dev/null 2>&1 || true
|
||||
fi
|
||||
else
|
||||
if [ -n "${DHCP4_NTP_SERVERS:-}" ]; then
|
||||
: > "$file"
|
||||
for s in $DHCP4_NTP_SERVERS; do
|
||||
printf 'server %s iburst\n' "$s" >> "$file"
|
||||
done
|
||||
chronyc reload sources >/dev/null 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user