Add ntp time source and browser policy

This commit is contained in:
Audiobuzz
2026-06-18 09:35:58 +00:00
parent 8f8e24ac28
commit a53357216d
10 changed files with 222 additions and 10 deletions
+3
View File
@@ -61,6 +61,9 @@ curl -sI http://${SERVER_IP}/fleet-${IMAGE_VERSION}.efi | head -1 # 200 OK
# HTTP: kiosk test page is served (what the diskless kiosk loads by default)
curl -sI http://${SERVER_IP}/kiosk/ | head -1 # 200 OK
# NTP: lab time server answers (diskless hosts get it via DHCP option 42)
chronyc -h ${SERVER_IP} tracking 2>/dev/null || ntpdate -q ${SERVER_IP}
# NVMe/TCP: target is listening + discoverable
ss -lntp | grep 4420
sudo nvme discover -t tcp -a ${SERVER_IP} -s 4420 # lists the subsystem
+9
View File
@@ -0,0 +1,9 @@
# Minimal chrony NTP server for the lab boot LAN. Diskless workstations get this
# host as their time source via DHCP option 42 (dnsmasq), so they never reach the
# public NTP pool (no workstation egress). Config is bind-mounted from
# chrony.conf in docker-compose.yml. Build our own so the version is pinned.
FROM alpine:3.20
RUN apk add --no-cache chrony
# -d: run in the foreground (don't daemonise) so the container stays up and logs
# to stdout for `docker compose logs`.
ENTRYPOINT ["chronyd", "-d", "-f", "/etc/chrony/chrony.conf"]
+20
View File
@@ -0,0 +1,20 @@
# Lab NTP server (serving stack). Syncs from upstream and serves the boot LAN so
# diskless workstations get time INTERNALLY (handed out as DHCP option 42 by
# dnsmasq) instead of egressing to the public pool. Only this host reaches the
# internet for time; the workstations never do.
# Upstream time source (this serving host has internet; the workstations don't).
pool pool.ntp.org iburst
# Serve the boot LAN. This is an isolated lab/boot network, so allow all; scope
# to your subnet (e.g. `allow 192.168.50.0/24`) for anything less trusted.
allow all
# Serve our own clock at a high stratum if upstream is unreachable, so a diskless
# boot never blocks waiting for time.
local stratum 10
# Step the clock on large initial offsets (containers can start far off), then
# slew. driftfile is best-effort (container fs is ephemeral).
makestep 1.0 3
driftfile /var/lib/chrony/drift
+27
View File
@@ -63,11 +63,24 @@ services:
# resolve the per-environment DNS name to this serving host.
- --address=/${NVME_HOST}/${SERVER_IP}
- --address=/${BOOT_HOST}/${SERVER_IP}
# Kiosk is LOCAL-ONLY (loads boot.fleet.lab), so sinkhole Chromium's
# call-home to 0.0.0.0 — telemetry can't leave the lab even if the browser
# tries. Defense-in-depth behind the in-image Chromium policy/flags; in
# production this belongs in the boot-LAN firewall's egress rules. NOTE: the
# client still *emits* the query (you'll see it in this log answered locally,
# not "forwarded"); stopping the query itself is the browser policy's job.
- --address=/google.com/0.0.0.0
- --address=/googleapis.com/0.0.0.0
- --address=/gstatic.com/0.0.0.0
# ---- DHCP ----
- --dhcp-authoritative
- --dhcp-range=${DHCP_RANGE_START},${DHCP_RANGE_END},${DHCP_LEASE}
- --dhcp-option=option:router,${GATEWAY_IP}
- --dhcp-option=option:dns-server,${SERVER_IP}
# NTP server (option 42): point diskless hosts at the lab 'ntp' service
# below so they sync time internally and never reach the public NTP pool.
# The image's NM dispatcher (10-chrony-dhcp-ntp) feeds this into chrony.
- --dhcp-option=option:ntp-server,${SERVER_IP}
# ---- UEFI HTTP Boot ----
# Firmware sends vendor-class "HTTPClient"; we must echo it back (opt 60)
# and hand over the UKI URL (opt 67). IP in the URL avoids a DNS round-trip
@@ -96,6 +109,20 @@ services:
# For HTTPS boot (production), terminate TLS here with the boot-infra CA's
# cert and switch the dhcp-boot URL above to https://. Left HTTP for the lab.
# --- NTP server (serves time to the boot LAN; handed out via DHCP opt 42) ---
ntp:
build: ./chrony
network_mode: host # serve NTP on udp/123 across the boot LAN
cap_add:
- SYS_TIME # discipline the (host-shared) clock it serves
restart: unless-stopped
volumes:
- ./chrony/chrony.conf:/etc/chrony/chrony.conf:ro
# NOTE: with host networking + SYS_TIME this chronyd disciplines the Docker
# HOST clock (the clock isn't namespaced) — intended: the serving host is the
# lab time source. Drop SYS_TIME (and add `chronyd -x`) if the host already
# runs its own NTP and you only want this to relay.
# --- NVMe/TCP target (serves rootfs.erofs, read-only) ----------------------
nvmeof:
# Prebuilt by CI (.gitea/workflows/spdk-image.yaml) and pulled here — no