Files
keycloak-pattern/docs/diagrams/d4-renewal-gap.svg
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

95 lines
5.6 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 860 520" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,sans-serif">
<style>
.box{fill:#fff;stroke:#8c959f;stroke-width:1.4;rx:6}
.dead{fill:#fff5f5;stroke:#cf222e;stroke-width:1.6;stroke-dasharray:5 3;rx:6}
.ok{fill:#f6fdf6;stroke:#1a7f37;stroke-width:1.6;rx:6}
.t{font-size:12px;fill:#1f2328}
.tb{font-size:12.5px;fill:#1f2328;font-weight:600}
.s{font-size:10.5px;fill:#656d76}
.ttl{font-size:14px;fill:#1f2328;font-weight:600}
.r{stroke:#cf222e;stroke-width:1.6;fill:none}
.g{stroke:#1a7f37;stroke-width:1.6;fill:none}
.k{stroke:#8c959f;stroke-width:1.3;fill:none}
</style>
<defs>
<marker id="a" markerWidth="8" markerHeight="8" refX="7" refY="3" orient="auto"><path d="M0,0 L7,3 L0,6 z" fill="#8c959f"/></marker>
<marker id="ar" markerWidth="8" markerHeight="8" refX="7" refY="3" orient="auto"><path d="M0,0 L7,3 L0,6 z" fill="#cf222e"/></marker>
<marker id="ag" markerWidth="8" markerHeight="8" refX="7" refY="3" orient="auto"><path d="M0,0 L7,3 L0,6 z" fill="#1a7f37"/></marker>
</defs>
<text x="20" y="26" class="ttl">D-4 — 「갱신 성공」과 「새 인증서 서빙」 사이의 38분 25초</text>
<text x="20" y="44" class="s">측정: 2026-09-04 · 일련번호 5초 간격 564표본 · 새 연결 0.2초 간격 8856건</text>
<!-- 좌: 디스크 -->
<rect x="20" y="70" width="250" height="196" class="box"/>
<text x="34" y="92" class="tb">디스크 — certbot</text>
<rect x="36" y="104" width="218" height="46" class="box"/>
<text x="48" y="122" class="t">cert1.pem</text>
<text x="48" y="138" class="s">09-03 10:47:40 · notAfter Dec 2</text>
<rect x="36" y="158" width="218" height="46" class="ok"/>
<text x="48" y="176" class="t">cert2.pem</text>
<text x="48" y="192" class="s">09-04 17:22:13 · notAfter Dec 3</text>
<text x="36" y="224" class="s">certbot renew --force-renewal</text>
<text x="36" y="240" class="s">→ 성공. live/ 링크가 2번을 가리킨다</text>
<text x="36" y="256" class="s">경로는 그대로, 내용만 바뀐다</text>
<!-- 중: 끊긴 고리 -->
<rect x="300" y="96" width="260" height="144" class="dead"/>
<text x="316" y="118" class="tb">★ 잇는 것이 없다</text>
<text x="316" y="140" class="t">1. ExecStartPost</text>
<text x="470" y="140" class="t" fill="#cf222e">없음</text>
<text x="316" y="160" class="t">2. renewal-hooks/deploy/</text>
<text x="470" y="160" class="t" fill="#cf222e">비었음</text>
<text x="316" y="180" class="t">3. certbot nginx 플러그인</text>
<text x="470" y="180" class="t" fill="#cf222e">없음</text>
<text x="316" y="206" class="s">post/ · pre/ 도 비어 있다 (total 8)</text>
<text x="316" y="222" class="s">셋 다 비면 아무도 reload 를 부르지 않는다</text>
<path d="M270 168 L296 168" class="r" marker-end="url(#ar)"/>
<path d="M300 230 L560 108" stroke="#cf222e" stroke-width="1.2" stroke-dasharray="4 3"/>
<path d="M300 108 L560 230" stroke="#cf222e" stroke-width="1.2" stroke-dasharray="4 3"/>
<!-- 우: nginx -->
<rect x="590" y="70" width="250" height="196" class="box"/>
<text x="604" y="92" class="tb">nginx — 메모리</text>
<rect x="606" y="104" width="218" height="60" class="dead"/>
<text x="618" y="124" class="t">기동 시 읽은 cert1</text>
<text x="618" y="140" class="s">master 585 / worker 586</text>
<text x="618" y="156" class="s">둘 다 09-03 19:00:39, 22.4시간째</text>
<text x="606" y="184" class="s">reload 없이는 디스크를 다시 안 본다.</text>
<text x="606" y="200" class="s">reload 하면 마스터는 남고</text>
<text x="606" y="216" class="s">워커만 새로 뜬다 → 워커 PID 로 확인</text>
<text x="606" y="240" class="s">ssl_certificate .../fullchain.pem</text>
<path d="M564 168 L586 168" class="k" marker-end="url(#a)"/>
<!-- 타임라인 -->
<text x="20" y="306" class="tb">밖에서 본 것 — 일련번호 (5초 간격)</text>
<line x1="60" y1="356" x2="800" y2="356" class="k"/>
<line x1="60" y1="350" x2="60" y2="362" class="k"/>
<line x1="300" y1="350" x2="300" y2="362" class="k"/>
<line x1="660" y1="344" x2="660" y2="368" stroke="#1a7f37" stroke-width="2"/>
<line x1="800" y1="350" x2="800" y2="362" class="k"/>
<text x="46" y="382" class="s">08:10:51</text>
<text x="278" y="382" class="s">08:22:13</text>
<text x="620" y="382" class="s">08:58:52</text>
<text x="770" y="382" class="s">09:02</text>
<text x="278" y="398" class="s">디스크 기록</text>
<text x="618" y="398" class="s">nginx -s reload</text>
<rect x="60" y="330" width="600" height="16" class="dead"/>
<text x="300" y="342" class="s" text-anchor="middle" fill="#cf222e">0520BB…B853 (옛 인증서) — 이 구간에서 428회 관측</text>
<rect x="660" y="330" width="140" height="16" class="ok"/>
<text x="730" y="342" class="s" text-anchor="middle" fill="#1a7f37">06C7CB…EA1D</text>
<path d="M300 416 L660 416" class="r" marker-end="url(#ar)"/>
<path d="M660 416 L300 416" class="r" marker-end="url(#ar)"/>
<text x="480" y="410" class="tb" text-anchor="middle" fill="#cf222e">38분 25초</text>
<text x="480" y="434" class="s" text-anchor="middle">사람이 reload 했기에 36분이다. 아무도 안 했다면 다음 재시작까지 — 무기한</text>
<!-- reload 판정 -->
<rect x="20" y="452" width="400" height="52" class="ok"/>
<text x="34" y="472" class="tb">reload 는 무중단이었다</text>
<text x="34" y="490" class="s">새 연결 8856건 전부 200 · p95 205.7 → 204.3ms (변화 없음)</text>
<rect x="440" y="452" width="400" height="52" class="ok"/>
<text x="454" y="472" class="tb">진행 중이던 요청도 살아남았다</text>
<text x="454" y="490" class="s">전송 12초째에 reload · 845361바이트 전량 · 연결수 1</text>
</svg>