폐쇄망 현장 — 방산·국방 도메인 · 시간 동기화와 기록의 증거력 · 이론
시계가 틀리면 기록은 증거가 되지 못한다
한 줄 요약
폐쇄망에는 바깥 시각원이 없다. 망 안에 세운 시각원은 호스트들 사이의 상대 순서를 맞춰 줄 뿐 절대 시각을 보증하지 않으며, 그 차이를 모른 채 "기록이 정확합니다" 라고 쓴 진술서는 감리에서 무너진다.
왜 이게 필요했나
장애 조사도 감사 대응도 결국 "무엇이 먼저 일어났는가" 를 묻는다. 그런데 기록의 시각은 그 기록을 남긴 기계의 시계가 보여 준 값이고, 기계마다 시계가 다르다. 초 단위로 다르면 사람이 눈치채지만, 2초쯤 차이는 아무도 알아채지 못한 채 원인과 결과를 뒤집어 놓는다. 실제로 조사에서 가장 흔하게 어긋나는 것이 이 지점이다. 배포가 장애보다 나중에 일어난 것처럼 보이면 조사는 엉뚱한 곳으로 간다.
인터넷이 닿는 곳에서는 이 문제가 대체로 조용히 해결된다. 공개 NTP 서버 여러 대를 보고 있으면 시계는 알아서 수렴한다. 폐쇄망에서는 그 전제가 사라진다. 망 안에 시각원을 하나 세우고 모두가 거기에 맞추는데, 그 시각원 자신은 바깥에 맞출 대상이 없다. [RFC 5905](https://www.rfc-editor.org/rfc/rfc5905)가 정의한 계통(stratum)에서 이런 시각원은 자기 자신을 기준으로 삼는 자리에 선다. 그 결과 망 안의 모든 기록은 서로 일관되지만, 그 전체가 바깥 세계보다 얼마나 앞서거나 뒤처져 있는지는 아무도 말할 수 없다. 이 사실을 진술서에 쓰지 않으면 나중에 문제가 된다.
어떻게 동작하나
판정은 네 층으로 쌓인다.
첫째, 표기를 하나로 모은다. 같은 시스템 안에서도 로그의 시각 표기는 제각각이다. 오프셋이 붙은 ISO 8601, 오프셋이 없는 지역시, epoch 초, 끝에 Z 가 붙은 UTC. 여기서 가장 위험한 것은 오프셋이 없는 시각이다. 그것을 UTC 로 읽으면 한국 시간대에서는 아홉 시간이 통째로 밀린다. 로그 파일만 보고는 어느 쪽인지 알 수 없으므로, 그 사실은 시스템 문서에서 가져와야 하고 진술서에도 그 근거를 적어야 한다. [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339)가 오프셋을 필수로 정한 이유가 이것이다.
둘째, 계통을 따라간다. 각 호스트가 어디에서 시각을 받는지 한 걸음씩 따라가면, 대부분은 선언된 시각원에 닿는다. 닿지 않는 호스트가 문제다. 설정이 지워져 자기 시계를 그대로 쓰고 있는 호스트는 겉보기에 멀쩡한 시각을 계속 찍어 내므로, 로그만 봐서는 구분되지 않는다. 계통을 끝까지 따라가는 것이 유일한 방법이다.
셋째, 기록끼리 부딪히는 자리를 찾는다. 두 호스트가 주고받은 요청과 응답에서 응답이 요청보다 앞선 건이 있으면, 두 시계가 최소한 그 차이만큼 벌어져 있다는 뜻이다. 이것은 추측이 아니라 하한이다. 보낸 쪽과 받은 쪽이 같은 사건을 서로 다른 시계로 찍었기 때문에 생기는 값이고, 동기화 보고의 오프셋과 견주면 보고가 사실인지도 확인된다.
넷째, 보정하고 남는 것을 본다. 오프셋으로 보정하면 대부분의 모순이 사라진다. 사라지지 않는 것이 남으면 그것은 시계 문제가 아니라 기록 자체의 결함이다. 이 둘을 가르는 것이 이 작업의 핵심이다. 보정으로 설명되는 구간은 조건부로 쓸 수 있고, 설명되지 않는 구간은 증거로 쓸 수 없다.
한 가지 더. 시계 동기화는 그 시각에 그 기록이 존재했다는 것을 증명하지 않는다. 그것은 다른 층의 일이고, [RFC 3161](https://www.rfc-editor.org/rfc/rfc3161)의 타임스탬프처럼 제삼자가 서명해 주는 구조가 필요하다. 동기화와 타임스탬프를 같은 것으로 말하는 진술서는 신뢰를 잃는다. 로그 관리 일반에 관해서는 [NIST SP 800-92](https://csrc.nist.gov/pubs/sp/800/92/final)가 시각 동기화를 로그 신뢰성의 전제로 다룬다.
현장에서 만나는 모습
한 폐쇄망 인도에서 조사가 이틀 동안 헛돌았다. 배치 작업이 큐에 넣은 시각보다 먼저 처리된 것처럼 보였기 때문이다. 원인은 처리 노드의 시계가 2.4초 빨랐던 것이었고, 동기화 보고에는 그 값이 그대로 적혀 있었다. 아무도 그 보고를 로그와 같이 놓고 보지 않았을 뿐이다. 보정한 뒤 남은 모순은 단 한 건이었고, 그 한 건이 진짜 버그였다.
또 하나 자주 보는 것은 자기 자신을 시각원으로 적어 놓은 호스트다. 설치 중에 설정을 한 번 지웠다가 되돌리지 않은 것인데, 그 호스트의 로그는 계속 그럴듯한 시각을 찍는다. 계통을 그림으로 그려 보기 전에는 드러나지 않는다.
세 번째는 진술서의 표현이다. 조사 결과를 넘길 때 "시각이 정확합니다" 라고 쓰고 싶은 유혹이 크지만, 그 문장은 자료가 뒷받침하지 않는다. 자료가 뒷받침하는 것은 "이 구간의 기록은 서로 모순되지 않으며, 보고된 오프셋으로 설명된다" 까지다. 이 차이는 말장난이 아니다. 나중에 한 건이라도 어긋나면, 앞 문장을 쓴 진술서는 통째로 신뢰를 잃고 뒤 문장을 쓴 진술서는 그 한 건만 다시 보면 된다. 감리가 좋아하는 문서는 단정하는 문서가 아니라 무엇을 확인했고 무엇을 확인하지 못했는지가 나뉘어 있는 문서다.
다음 실습에서 할 것
표기가 넷으로 갈린 다섯 호스트의 로그를 한 축으로 모으고, 오프셋 없는 로그를 UTC 로 잘못 읽으면 몇 건이 얼마나 밀리는지 세어 봅니다. 그 다음 시각 계통을 따라가 선언된 시각원에 닿지 않는 호스트를 찾고, 요청과 응답의 모순으로 시계 오차의 하한을 구한 뒤 보정합니다. 마지막에 호스트마다 기록을 얼마나 믿을 수 있는지 등급을 매기고, 무엇을 믿을 수 있고 무엇을 믿을 수 없는지 함께 적은 진술서를 씁니다.