OS image and first boot#
Why#
The image choice and first-boot configuration set constraints that will be hard to fix later, especially SSH access (if misconfigured, access to a headless machine is lost) and DNS resolution of the server’s public name.
How#
Flashing the image#
With rpi-imager, choose Raspberry Pi OS Lite (64-bit), not the
desktop variant, which is useless for a server and consumes resources for
no benefit. In the imager’s advanced options:
- Hostname: the name that will be published to DNS (e.g.
time.example.org) - SSH: enabled, public key only, never password auth for a server exposed on the Internet
- Wi-Fi: disabled (Ethernet only, more stable, less radio attack surface)
- Locale and timezone:
UTCfor the timezone, regardless of the locale chosen, a time server should never reason in local time
First boot#
ssh user@time.example.org
sudo -i
cat /etc/os-release
uname -aHostname and FQDN#
hostnamectl set-hostname time.example.org
# SHORT hostname only, not the full FQDN
# 127.0.1.1 (not 127.0.0.1): a Debian convention that reserves a distinct
# loopback address for the machine's own name, so it never conflicts with
# the real "localhost" entry
grep -qE '^127\.0\.1\.1\s+time\b' /etc/hosts || echo "127.0.1.1 time" >> /etc/hosts
# The full FQDN must resolve via PUBLIC DNS, not /etc/hosts
host time.example.orgPitfalls to avoid#
Never put the public FQDN in
/etc/hostspointed at loopback. This is a common shortcut (“to make it work right away”) that silently breaks several things downstream: Let’s Encrypt’s ACME validation (which checks public DNS resolution), any external connectivity test, and worst of all, it hides a real DNS configuration problem behind a fake “works locally”. Only the short hostname (without the domain) belongs in/etc/hosts.
- Enabling password SSH “to move fast”. A public NTP server receives continuous scan traffic as soon as it goes live (observed: several thousand banned IPs within weeks on this project). Key-based auth isn’t optional, it’s a prerequisite.
- Keeping Wi-Fi enabled “just in case”. Every active network interface is an attack surface and a source of variable latency. A reference time service needs the simplest, most predictable network path possible.
Verify#
uname -a
# Confirms architecture (aarch64) and base kernel
cat /etc/os-release
# Confirms the underlying Debian version
host time.example.org
# Should return the server's public IP, not 127.0.1.1If host doesn’t resolve to the right IP yet, that’s not blocking at this
stage (DNS can be set up in parallel), but it must be resolved before the
NGINX/Let’s Encrypt chapter, which depends on this public resolution for
certificate validation.