Files
keycloak-pattern/docs/evidence/d4-certificate-renewal/README.md
T
DongHyeonkaandClaude Opus 5 3d7778bd3c docs(d4): correct the gap to 38m25s — the two timestamps came from different clocks
The 2199 seconds reported for D-4 subtracted a test-server timestamp
(archive/cert2.pem mtime) from a dev-machine timestamp (the serial change
observed by the poll), without noting they are different clocks.

Checked against external references: the dev machine matches Google and the
Let's Encrypt ACME endpoint to the second, while test-server is 105 seconds
fast and reports NTPSynchronized=no. Three round-trip measurements put the
offset at +106.1s every time.

Corrected:

  new certificate written to disk  08:20:27 UTC   (mtime 17:22:13 KST - 106s)
  actually served                  08:58:52 UTC   (dev observation, no correction)
  gap                              2305s = 38m25s

The correction validates itself in D-4a, where the new certificate's SCT —
signed by CT logs on their own accurate clock at 12:27:49.054 GMT — lands
one second before the skew-corrected hook time. Without the correction the
hook would appear to have run 104 seconds before the certificate existed.

Updated across the experiment doc, the index, the follow-up doc, the verdict
evidence file and the SVG.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 21:33:01 +09:00

3.5 KiB
Raw Blame History

D-4 — 인증서 갱신 증거

2026-09-04 17:25 18:02 KST 해설: docs/experiment-d4-certificate-renewal.md

파일 무엇을 보여주는가
01-certificate-state.txt SAN 3개(와일드카드 아님) · 체인 4단계, Verify return code: 0 · certbot-renew.timer enabled·active, 11시간 전 실행 · 88일 남음 · sudo: a password is required 로 강제 갱신 불가
05-control-no-injection.txt 대조군 1 — 잡음 바닥. 0.2초 × 900회 / 180초 동안 900전부 200, 오류 0. 중앙 98ms · p95 195ms. TLS 핸드셰이크 900/900 = 매 요청이 새 연결이다
06-inflight-control.txt 대조군 2 — '진행 중이던 요청' 측정 장치. 845KB 번들을 --limit-rate 20k 로 받아 요청을 42초간 살려 둔다. 무주입 시 코드 200 · 845361바이트 · 연결수 1

| 05-control-no-injection.txt | 대조군 1 — 잡음 바닥. 0.2초 × 900회 / 180초 동안 900 전부 200, 오류 0. 중앙 98ms · p95 195ms. TLS 핸드셰이크 900/900 = 매 요청이 새 연결 | | 06-inflight-control.txt | 대조군 2 — '진행 중이던 요청' 장치. 845KB 를 --limit-rate 20k 로 받아 요청을 42초간 살려 둔다. 무주입 시 200 · 845361바이트 · 연결수 1 | | 07-renewal-hook-missing.txt | nginx 는 reload 된 적이 없다 — 마스터 585·워커 586 이 같은 시각 기동, 22.4시간째. 유닛은 ExecStart=certbot -q renew 가 전부. crt.sh 는 SCT 가 박힌 인증서를 0건으로 답한다 | | 08-inflight-artifact.txt | 76건 실패는 서버 탓이 아니다 — 같은 순간 폴링 49건 전부 200, 연결수=0, 50µs, 재현 0/100. 대조군이 오보를 막았다 | | 09-serial-timeline.txt | 일련번호 564표본. 08:10:51 ~ 08:58:47 옛 것 → 08:58:52 새 것 | | 10-reload-poll-window.txt | reload 전후 60초 새 연결 원문 — 비200 0건, 최대 373ms | | 11-inflight-full.txt | in-flight 전체 50건. 08:58:40 시작 요청이 08:58:52 reload 를 관통해 845361바이트 전량 수신 | | 12-certbot-state.txt | cert2.pem 09-04 17:22:13 기록됨 · renewal-hooks/{deploy,post,pre}/ 셋 다 비었음 · 플러그인 목록에 nginx 없음 | | 13-verdict.txt | 판정 전문 — 38분 25초 공백(428회 관측) + reload 무중단(8856건 0실패) |

핵심 다섯 줄

  1. 「갱신 성공」과 「새 인증서 서빙」은 다른 사건이다. 새 인증서가 디스크에 있는 채로 38분 25초 동안 옛 인증서를 서빙했고, 그 구간에서 428번 관측했다.
  2. 그 36분은 우연히 짧았다. reload 를 시킨 것은 사람이다. 아무도 안 했다면 다음 nginx 재시작까지 무기한이었다.
  3. 원인이 셋 겹쳤다. 유닛에 ExecStartPost 없음 · 훅 디렉터리 3개 전부 비었음 · certbot 에 nginx 플러그인 없음. 하나라도 있었으면 자동 반영됐다.
  4. reload 자체는 무중단이었다. 새 연결 8856건 전부 200, p95 205.7 → 204.3ms, 그리고 전송 12초째에 reload 를 맞은 42초 요청이 845361바이트를 온전히 받았다(연결수 1).
  5. 이 결함은 88일 동안 안 보인다. 타이머는 오늘도 두 번 SUCCESS 로 끝났다. 만료 30일 전까지는 갱신 자체를 하지 않으므로 발현할 기회가 없고, 발현하는 날의 증상은 인증서 만료다 — 그날에도 로그는 SUCCESS 라고 적혀 있다.