2026-09-17 에 기반 가이드 7단계로 실험대를 처음부터 다시 세우고 A-0 을 그대로 다시
밟은 기록이다. 명령과 출력은 그때 화면에 나온 것을 그대로 옮겼다.

a0-01-baseline.txt              기준선 1~5 — 노드·파드 배치, 파드 IP, ISPN000094 (2), jgroups_ping coord 하나, \dt 100행, 세션 0행
a0-02-cache-entries.txt         기준선 6 — Prometheus 의 vendor_statistics_approximate_entries_unique 통째로와 tr/grep 으로 자른 형태
a0-03-inject-reset.txt          주입 — 세션 행 삭제와 rollout restart, 새 파드 IP
a0-04-test0.txt                 시험 0 ①~⑦ — 로그인, 토큰 길이, 클레임 디코드, sid, CID, 두 노드에 grep -c
a0-05-claims.txt                JWT 클레임 전체 (패딩을 채워 디코드) — sub 이 없다는 것을 확인
a0-06-test0-cross-node.txt      시험 0 ⑧⑨ — 반대편 refresh 200 · 같은 sid, 로그아웃 204, 발급 노드에서 400 Session not active
a0-07-test0b-cache-delta.txt    시험 0b — 로그인 한 번에 발급 노드만 +1, 반대편 +0
a0-08-test0c-ownership.txt      시험 0c — 몰아준 쪽만 늘어 9 + 5 = 14, DB 총계 14
a0-09-test0d-sql.txt            시험 0d 첫 시도 — 문장 로깅을 켜고 요청 직후에 걸렀더니 반대편 문장이 안 나왔다
a0-10-test0d-retry.txt          같은 필터를 몇 초 뒤에 — 그래도 안 나온 판. 09 와 함께 「너무 일찍 걸렀다」의 증거다
a0-11-test0d-window.txt         그 시간대에 반대편이 낸 모든 줄 — 디스커버리 질의뿐이었다
a0-12-test0d-controlled.txt     대기를 넣고 다시 — 반대편 pid 가 낸 sid 줄 6개, 세션 테이블 문장 6/12
a0-13-test0d-sql-lines.txt      반대편이 날린 여덟 문장과 pid 로 거른 BEGIN~COMMIT 경계. 끝에 문장 로깅을 되돌렸다

비밀은 옮기지 않았다. 관리자 비밀번호는 길이(19)만 확인했고 값은 어느 파일에도 없다.

A-1 (JGroups 7800 차단)
a1-01-inject.txt                매니페스트 원문과 apply · 적용 시각
a1-02-verify.txt                정책이 잡은 파드, 포트 셋(9000=200 · 8080=200 · 7800=exit 7), 클러스터는 아직 2, /proc/net/tcp6 의 1E78
a1-03-conntrack.txt             conntrack 을 두 노드에서 — 빈 화면이 나왔다
a1-04-conntrack-missing.txt     그 빈 화면의 까닭 — conntrack 미설치. 2>/dev/null 이 command not found 를 지웠다
a1-05-conntrack-installed.txt   처방 검증 — 깔고 나니 ESTABLISHED [ASSURED] 두 줄이 나온다
a1-06-forced-partition.txt      파드를 지워 분단 확정 — 두 노드가 각각 1 을 보고
a1-07-readiness.txt             분단된 노드가 0/1 · Ready=False, Endpoints 가 하나로, health/ready 503 과 Failing since
a1-08-readiness-commands.txt    문서가 적은 명령 그대로 — describe 는 조건표를 내고, custom-columns 는 zsh 에서 안 돈다
a1-09-quoting-and-health.txt    따옴표를 씌운 형태와 헬스 본문을 내는 명령. 정문은 Host 헤더로 200
a1-10-cross-node-under-partition.txt  분단 중 네 단계 — 200 · 204 · 200. 로그아웃이 전파되지 않았다 (토큰은 길이만 남기고 가렸다)
a1-11-recover.txt               정책 삭제 뒤 30~60초 안에 두 노드가 다시 2

A-2 (데이터베이스 정상 종료)
a2-01-baseline-probe.txt        상주 탐침 a2-probe 와 정지 전 토큰 (길이만)
a2-02-inject.txt                정지 전 네 경로 200×4, replicas=0, 파드 삭제, Deployment 0/0
a2-03-during-outage.txt         정지 직후 — 네 경로 500×4, JWKS·well-known 200, Connection refused, 그런데 ready 는 아직 true
a2-04-outage-progression.txt    약 50초 뒤 ready false,false · 정문 503 으로 뒤집히는 자리
a2-05-recover.txt               replicas=1 에서 36초 만에 ready true,true · 정문 200 · 재시작 0

A-3 (데이터베이스 크래시)
a3-01-design-check.txt          로그인 트랜잭션에도 SET LOCAL synchronous_commit TO OFF 가 붙는다 · WAL 설정 네 줄
a3-02-prepare.txt               세션 비우기, 파드 셋 상태, 루프 파일 주입
a3-03-attempt1.txt              시도 ① 첫 판 — /tmp/sids 가 0줄이었다 (아래 04 가 그 까닭)
a3-04-sids-no-newline.txt       busybox sed 가 끝 개행을 안 붙인다 — 9384바이트 0줄. echo 로 감싼 처방을 재서 10줄 확인
a3-05-attempt1-redo.txt         고친 루프로 다시 — 8초에 109건, force delete 는 유실 0
a3-06-attempt2.txt              시도 ② kill -9 1 — RESTARTS 0, 400 = 400, 유실 0
a3-07-attempt3.txt              시도 ③ 백엔드 SIGKILL — crash recovery 로그와 395 vs 392
a3-08-loss-count.txt            문서의 comm 방법으로 센 유실 3건과 그 sid 세 개
a3-09-revert.txt                문장 로깅 off 확인, 세션 정리, 파드 재시작, 탐침 삭제

A-4 (노드 상실)
a4-01-baseline.txt              virsh uri·VM 셋·파드 배치·PV 가 kc-lab-2 에 고정된 것·관측 스택 위치
a4-02-inject-4a.txt             kc-lab-2 영향 범위와 virsh destroy. 하이퍼바이저는 shut off 인데 쿠버네티스는 +10초에도 Ready
a4-03-4a-progression.txt        +28초 Ready/정문 000 → +66초 NotReady/정문 503. 이벤트 NodeNotReady 와 context deadline exceeded
a4-04-eviction-and-recover.txt  +4분 49초에 deletionTimestamp. Deployment 는 대체 파드(Pending), StatefulSet 은 대체 없이 Terminating
a4-05-recovery-progression.txt  VM 을 켠 뒤 Ready 로 돌아오고 파드가 서고 정문이 200 이 되기까지
a4-06-agent-token-missing.txt   복구가 막힌 진짜 까닭 — 유닛이 지워진 ~/node-token 을 기다린다. 파일을 되돌리자 Ready
a4-07-token-remedy.txt          처방 — /etc/rancher/node-token(root 600)으로 옮기고 유닛을 돌리면 홈 사본을 지워도 뜬다

A-5 (비대칭 분단)
a5-01-attempt1.txt              시도 ① filter FORWARD — 카운터는 9·22 로 올라가는데 클러스터는 2 그대로. 게스트 셸의 $K1 이 비어 있는 것도 여기서 확인
a5-02-attempt2-3.txt            시도 ② 보내는 쪽 raw — 카운터 0. 시도 ③ 받는 쪽 raw — 카운터 16·20, 멤버 1
a5-03-one-direction-watch.txt   한 방향만 막은 채 2분 — 잠깐 1 이었다가 2 로 돌아온다 (문서의 「열린 방향으로 다시 붙는다」)
a5-04-bidirectional.txt         양방향 — 멤버 1·1 과 jgroups_ping 의 coord 가 둘 다 t
a5-05-revert.txt                두 체인을 비우자 2 와 coord 하나로 복귀

A-6 (지연 주입)
a6-01-attempt1-2.txt            시도 ① eth0 가 없다 · ip -brief link 목록 · enp1s0 는 노드 IP 만, flannel.1 은 파드 IP 가 보인다 (문서가 미검증으로 둔 두 줄)
a6-02-inject.txt                주입 전 로그인 0.064~0.068s, flannel.1 에 prio·netem·filter 세 줄
a6-03-effect.txt                주입 뒤 1.86~1.91s (문서의 1,872ms 와 28배가 그대로) · netem 83 pkt · tc filter show 의 match 0a2a011d
a6-04-revert.txt                qdisc del 뒤 noqueue 로 돌아가고 시간도 0.04~0.07s 로 복귀

A-7 (volatile 로 A층 넷을 다시)
a7-01-switch-volatile.txt          세션 비우기, args 를 --features-disabled=persistent-user-sessions 로 patch, 롤아웃
a7-02-cross-node-volatile.txt      교차 노드 refresh 200 인데 DB 세션 행은 (0 rows)
a7-03-block-7800.txt               캐시가 keycloak-0 에만 1, 그 뒤 NetworkPolicy 로 7800 차단 — 멤버 1·1
a7-04-partition-breaks-sharing.txt 분단 + volatile 에서 400·400·400 (persistent 의 200·204·200 과 정반대)
a7-05-revert.txt                   NetworkPolicy 삭제와 args 원복

A-7a (그 500 의 원인과 캐시 온도 셋)
a7a-01-setup.txt                   문장 로깅 on, volatile 전환, StatefulSet 밖의 탐침
a7a-02-repro-A.txt                 재현 A 완전 냉시동 — 로그인이 400 unauthorized_client
a7a-03-repro-A-sql.txt             문서의 grep 이 한 줄도 못 잡는다. 속 예외가 JDBCConnectionException 쪽이었다
a7a-04-repro-B.txt                 재현 B 로그인 한 번으로 덥힌 뒤 DB 정지 — refresh 가 500 unknown_error
a7a-05-repro-C-and-revert.txt      재현 C — DB 를 켜니 같은 refresh 가 200. 로깅 off 와 args 원복까지

A-8 (롤링 재시작)
a8-01-baseline.txt              파드·args·DB 0건, 토큰과 sid 를 탐침에 담고 대조군 refresh 200, 그 sid 의 DB 행
a8-02-restart.txt               재시작 전 캐시 0, rollout restart, AGE 로 교체 확인. (12번은 탐침의 낡은 K0 때문에 000 이 났다)
a8-03-main-test.txt             새 IP 로 다시 — 재시작 전 토큰이 200, created_on 은 그대로이고 last_session_refresh 만 갱신 (토큰은 길이만 남기고 가렸다)

D-3 (비밀 노출 네 경로)
d3-01-secret-paths.txt          Secret 목록·describe 의 길이 표시·키 이름·길이, 카나리아 주입, 암호화 Disabled, state.db 0 / -wal 1
d3-02-paths-and-revert.txt      strings 미설치, RBAC 는 둘 다 no, 카나리아 삭제 뒤 -wal 이 1 → 7 로 늘었다
d3-03-strings-missing.txt       binutils 를 깔면 strings 가 생기고, 안 깔아도 grep -c 로 같은 7 이 나온다

B층 준비 (B-0 의 실행 가능한 부분)
b0-01-image-import.txt          워크스테이션에서 두 이미지를 빌드해 docker save | ssh | k3s ctr images import 로 두 노드에
b0-02-realm-and-user.txt        kcadm 로그인, realm keycloak-patterns · client bff-confidential · user labuser 생성
b0-03-deploy-bff.txt            bff-redis.yaml 적용 — Secret·PVC·redis·bff·Service·Ingress
b0-04-bff-status.txt            bff 두 replica 와 redis 가 1/1. imagePullPolicy Never 로 반입 이미지가 붙었다

B-3 (refresh 회전 경쟁) — 전제 검증까지
b3-01-setup.txt                 realm 세 값(revokeRefreshToken false · maxReuse 0 · lifespan 60), 탐침, CS길이 14
b3-02-secret-and-token.txt      B-0 이 없다고 한 비밀 대조를 만들어 「두 값이 같다」. 그런데 토큰 요청이 unauthorized_client
b3-03-direct-grant-missing.txt  원인 — directAccessGrantsEnabled 가 false. 켜니 invalid_grant 로 바뀐다
b3-04-account-not-fully-set-up.txt  둘째 원인 — labuser 의 emailVerified false. 고치니 토큰이 나온다 (rt=735자)
b3-05-race.txt                  회전을 켜고 같은 토큰으로 동시에 5번 — 400 넷·200 하나, 이긴 토큰도 400 (토큰 조각은 가렸다)
b3-06-revert.txt                revokeRefreshToken 원복과 탐침 삭제

D-1 (백업과 복구)
d1-01-backup.txt                기준선 101 테이블·세션 6건, pg_dump 로 976873 bytes·8569 줄·CREATE TABLE 101
d1-02-destroy-restore.txt       DROP SCHEMA 뒤 남은 테이블 0 인데 정문은 200, 6초 만에 복구되고 ERROR 0, 101/6 으로 복귀

D-2 (판올림과 롤백)
d2-01-baseline.txt              태그 26.7.0, databasechangelog 210, 마지막 다섯 줄, 세션 6, quay 에 26.7.3 존재(200)
d2-02-upgrade.txt               26.7.3 정방향 85초 — 스키마 210 그대로, 세션 보존, 정문 200
d2-03-rollback-and-reverse.txt  롤백 67초 성공. 역방향 26.0 은 liquibase Validation Failed 로 keycloak-1 만 못 뜨고 정문은 200
d2-04-revert.txt                체크섬 줄(1 changesets check sum)과 26.7.0 원복

B-6 (키 회전) — 전제까지만
b6-01-deploy-echo.txt           echo.yaml 로 header-lab 네임스페이스와 echo 두 replica (반입 이미지로 뜬다)
b6-02-jwks-before.txt           JWKS 를 Host 헤더로 받는다. RS256 1개, kid 둘
b6-03-providers.txt             kcadm 세션이 파드 교체로 사라진 것과 재로그인. 문서가 「빈 결과」라던 질의가 실제로는 결과를 낸다
b6-04-old-token.txt             토큰 1397자. echo 는 유효한 토큰에 401, 토큰 없이는 200
b6-05-echo-401.txt              그 까닭 — echo 의 issuer/jwk URI 가 https 이고 닿지 않는다. kid 를 뽑으려면 공백을 허용해야 한다
b6-06-kid-and-issuer.txt        두 URI 원문, issuer=000(exit 7), 헤더의 "kid" : "…" 공백 형태와 두 sed 비교

B-4 (신원 헤더 위조) — TLS 를 Host 헤더로 대체해 실행
b4-01-forged-headers.txt        Ingress 네 줄, echo 응답 전문(들여쓰고 콜론 양옆에 공백), 대조군은 비어 있다
b4-02-forged-headers-retry.txt  동명 헤더 둘 · 값 안의 쉼표 · 위조한 신원이 전부 그대로 도착. 문서의 콜론 붙인 grep 은 한 줄도 못 잡는다

C-2 (백채널 로그아웃) — 브라우저 없이 되는 두 단계
c2-01-backchannel-probe.txt     세 후보 경로가 전부 302 이고 Location 이 로그인 시작점. 워크스테이션 grep 도 빈 출력(디렉터리는 있다)

B-7a / B-7 (엣지 세션) — 전제에서 막힌 자리를 쟀다
b7a-01-oauth2-proxy.txt         oauth2-proxy 배포가 롤아웃 타임아웃. redis-cli dbsize 0 과 빈 스캔은 정상 동작
b7a-02-oauth2-proxy-blocked.txt 까닭 — 기동 시 OIDC 디스커버리가 https://auth.hyeonworks.com 으로 가고 connection refused. CrashLoopBackOff

B-0 / B-1 / B-2 — 브라우저 없이 되는 측정
b1-01-beans.txt                 /actuator/beans 빈 437개, authorizedClientService 가 JdbcOAuth2AuthorizedClientService, RedisSessionConfiguration 존재. 문서의 미검증 두 줄이 돈다
b2-01-jdbc-table.txt            oauth2_authorized_client 표는 생겨 있고 행은 0 (행은 브라우저 로그인 뒤에 생긴다)

D-4 / D-4a (인증서 갱신과 배포 훅) — 인증서 없이 되는 부분
d4-01-renewal-automation.txt    certbot 은 kc-lab-edge 에 있고 test-server 에는 타이머가 없다. 유닛 이름은 certbot.timer/.service (certbot-renew.* 아님). 기본 유닛에 ExecStartPost 도 --deploy-hook 도 없고 훅 디렉터리도 비었다. certificates 는 No certificates found
d4a-01-hook-state.txt           test-server 에 nginx 프로세스가 없다(엣지에 있다). 훅 디렉터리 total 8. lab host 와 엣지의 시계가 94초 어긋나 있다

B-5 (Redis 상실)
b5-01-baseline.txt              Redis PONG·키 없음·save 와 appendonly·/data 가 PVC redis-data
b5-02-redis-down.txt            replicas=0 뒤 health 는 DOWN 인데 readiness 는 UP. 파드 둘 다 1/1, 엔드포인트도 ready true,true
b5-03-revert.txt                replicas=1 로 되살리자 health 가 다시 UP

C-1 (여러 앱의 SSO) — 브라우저 없이 되는 세션 정리 구간
c1-01-clear-sessions.txt        logout-all 을 쳐도 세션이 6건 그대로. 자식 1633 · 부모 6 순서로 지워야 한다. flushall·롤아웃 뒤 둘 다 0. 롤아웃이 kcadm 세션을 날린다

이 폴더가 덮는 범위
-------------------
2026-09-17 에 기반 가이드 7단계로 실험대를 철거하고 새로 세운 뒤 kss 26편을 순서대로
밟은 기록이다. 끝까지 밟은 편이 17, 되는 데까지 밟은 편이 9 다. 어느 편이 어디까지인지는
SSOT 의 「2026-09-17 재현 — 어디까지 밟았고 무엇이 막았나」와 각 기록의
「이 실험대에서 아직 못 밟은 단계」에 적혀 있다.

막은 것은 하나다 — https://auth.hyeonworks.com 이 서지 않는다. 와일드카드 인증서
(Cloudflare API 토큰)와 호스트의 libvirt guest_input 구멍(호스트 sudo)이 둘 다 필요하다.

비밀은 어느 파일에도 값으로 들어 있지 않다. 비밀번호는 길이(19·22)만 적었고, 화면에
찍혀 나온 토큰은 <REDACTED n자> 로 가렸다.
