Meta discusses the implementation of Network Time Security (NTS) to provide authenticated time, addressing the long-standing vulnerability of unauthenticated NTP. The article details the stateless architecture for cookie management and key derivation, ensuring high availability and scalability while protecting against critical security risks like certificate invalidation and token expiry due to manipulated clocks. This system design is crucial for modern internet security where precise and verifiable time is a fundamental building block.
Read original on Meta EngineeringNTP, a foundational internet protocol, has historically lacked authentication, making it susceptible to man-in-the-middle (MITM) attacks. This vulnerability is no longer merely an 'operational annoyance' but a critical security risk. Modern systems heavily rely on accurate and verifiable time for a multitude of security functions, making a secure time service a load-bearing component of any secure distributed system.
NTS (Network Time Security, RFC 8915) addresses NTP's lack of authentication by introducing a two-phase process: Key Establishment (NTS-KE) over TLS 1.3 and Authenticated NTP over UDP. A key architectural decision by Meta is to maintain a completely stateless server design for the NTP responses, even though NTS uses cookies.
To avoid a distributed state problem, Meta's NTS implementation derives the cookie sealing key dynamically. Each server generates its sealing key from a shared master secret and the current 'epoch day' (Unix epoch divided by 24-hour periods). This allows any server to open any valid cookie without needing to replicate or share key rings, enabling horizontal scalability and high availability. This mechanism means NTS-KE servers and NTP responders can be different, disconnected machines, greatly simplifying deployment and scaling.
Design Lesson: Statelessness for Scalability
The NTS cookie design demonstrates a powerful pattern for scaling distributed systems: offloading state to the client in an encrypted, verifiable manner. By making servers stateless regarding client sessions, system complexity is reduced, and horizontal scaling becomes trivial. This approach is highly resilient to failures and allows independent scaling of different service components.