Files
llm-wiki/raw/branch-notes/feature-keycloak-https-termination-caddy-nginx.md
T

31 KiB

title, source_type, status, id, kind, project, work_item, inherits, refines, overrides, depends_on, contract_packet, branch, parent_branch, related_projects, tags, created, target_merge, status_label, contract_packet_sha256
title source_type status id kind project work_item inherits refines overrides depends_on contract_packet branch parent_branch related_projects tags created target_merge status_label contract_packet_sha256
branch / feature-keycloak-https-termination-caddy-nginx (P3B HTTPS termination — Caddy vs nginx + Let's Encrypt) branch-note raw BR-KEYCLOAK-CHILD-A34AB4E8 branch-child keycloak-patterns-overview WI-KEYCLOAK-PATTERNS-OVERVIEW-020
DEC-KEYCLOAK-PATTERNS-OVERVIEW-AUTH-TAXONOMY-001@1
1 feature-keycloak-https-termination-caddy-nginx feature-keycloak-patterns
keycloak-patterns
branch
keycloak-patterns
p3b
https
tls
caddy
nginx
letsencrypt
acme
2026-05-25 in-progress 3cb0c15cd9eed9060bbf609a1eceb775ab560d7bdafc292900454af3c43aac1c

branch: feature-keycloak-https-termination-caddy-nginx (P3B HTTPS termination — Caddy vs nginx + Let's Encrypt)

Layer: raw/branch-notes/raw/branch-notes/feature-keycloak-patterns의 WI020 child branch. HTTPS termination 위치와 cert 자동화 옵션 비교. Cloudflare Tunnel은 edge TLS 자동, EC2 public IP는 Caddy 또는 nginx + certbot 필요. 본 sub-sub-branch는 문서까지만 — 실 Caddy / nginx 설치 / cert 발급 / cron 등록은 진행하지 않음. 등급 documented-only. status_label: in-progress

부모 (필수)

raw/branch-notes/feature-keycloak-patterns

브랜치 계약 패킷

  • 생성 시 프로젝트 개정: 1
  • 패킷 스키마: contract_packet: 1
  • 완료 조건: project governance hub가 AP1~AP4 taxonomy와 child progress index를 유지한다

상속한 프로젝트 결정

Decision Ref Project Summary Branch Application Source
DEC-KEYCLOAK-PATTERNS-OVERVIEW-AUTH-TAXONOMY-001@1 canonical 분류축은 AP1~AP4 인증 통합 아키텍처와 cross-cutting 변형이다 HTTPS termination을 인증 패턴 공통의 deployment cross-cutting 변형으로 분류한다 raw/project-notes/keycloak-patterns-overview

브랜치 지역 결정

기존 branch-local 결정은 아래 ## Decision Evidence Map의 D-row가 소유하며 이 packet에서 복제하지 않는다.

Decision ID Decision Relation Supporting Claims Status

선언한 예외

Override ID Overrides Reason Approval Status

없음.

목표

Google OAuth가 redirect_uri로 HTTPS를 강제(-6-3 참조)하므로 P3B는 어떤 식으로든 HTTPS가 필수. 단일 EC2 학습 환경에서 다음 4개 옵션의 trade-off를 정리:

  1. Caddy — 1줄 config로 Let's Encrypt 자동 (ACME-TLS-ALPN-01 / HTTP-01)
  2. nginx + certbot — 직접 cert 발급 + cron으로 renew
  3. Cloudflare Tunnel — origin은 HTTP, edge가 TLS 종단 (edge-managed certificate)
  4. EC2 + ALB + ACM — production-like, AWS managed cert

이 결정이 운영 비용(cert renew burden, 만료 사고) + 학습 friction(설치 복잡도)를 좌우.

면접에서 답해야 할 질문:

  1. Caddy를 학습용으로 왜 우선 골랐나? → 짧은 config와 자동 ACME로 수동 발급·갱신 부담을 줄이기 때문이다.
  2. nginx + certbot vs Caddy의 차이는? → nginx는 명시적 (server block + ssl_certificate path), certbot이 별도 binary로 cert 발급/갱신. Caddy는 통합.
  3. HSTS / TLS 1.2+ enforce 어디서? → reverse proxy 레이어. Caddy는 Automatic HTTPS로 HTTP→HTTPS redirect를 제공하지만 HSTS는 header directive로 명시해야 한다. nginx도 명시 설정한다.
  • 이슈:
  • PR:

범위

포함 범위

  • Caddy auto_https on (디폴트) + 1줄 config로 Let's Encrypt 발급
  • nginx + certbot (또는 acme.sh) CLI 흐름, cron / systemd timer 등록
  • Cloudflare Tunnel edge TLS (origin HTTP, edge HTTPS) 흐름
  • EC2 + ALB + ACM (production-like 대안) — 비교만
  • cert 갱신 자동화 (certbot.timer / cron / Caddy 내장 / Cloudflare 자동)
  • TLS 1.2+ enforce 설정 위치
  • HSTS 헤더 (Strict-Transport-Security) 설정 위치

제외 범위

  • 실 cert 발급 (도메인 소유 검증 필요 → P3A 완료 후 선택적 확장)
  • mTLS / client cert auth
  • TLS 1.3 0-RTT
  • HPKP (deprecated)
  • HAProxy / Traefik 옵션

근거 (필수, 최소 1개+)

관련 sub-branch

TODO

각 항목 옆에 증거 등급 표기.

  • Caddy 설치 + 1줄 config 정리apt install caddy 또는 docker image, Caddyfilekc.example.com { reverse_proxy localhost:8080 } 1줄 → auto_https on 디폴트로 Let's Encrypt 자동 발급 — 등급: planned
  • nginx + certbot 흐름 정리apt install nginx certbot python3-certbot-nginxcertbot --nginx -d kc.example.com → server block에 ssl_certificate 자동 삽입 → certbot renew --dry-run 검증 → systemctl enable certbot.timer — 등급: planned
  • acme.sh 대안 비교 — certbot 대비 shell-only / 더 가벼움 / 다양한 DNS provider 지원 — 등급: documented-only
  • Cloudflare Tunnel edge TLS 흐름 — origin은 http://localhost:8080, edge certificate는 공급자가 관리 → 학습용 1순위 — 등급: planned
  • EC2 + ALB + ACM (production-like) — Route53 hosted zone + ALB + ACM cert + Target Group → EC2:80. ACM 자동 갱신. 학습 비용 ↑ — 등급: documented-only
  • cert 갱신 자동화 비교표 — certbot.timer / cron 0 3 * * * certbot renew --quiet / Caddy background 갱신(정확 시점은 issuer 정책 의존) / Cloudflare edge 관리 / ACM managed renewal — 등급: planned
  • TLS 1.2+ enforce 정책 — Caddy 디폴트로 TLS 1.2 minimum, nginx는 ssl_protocols TLSv1.2 TLSv1.3; 명시 — 등급: planned
  • HSTS 헤더 정책Strict-Transport-Security: max-age=31536000; includeSubDomains. Caddy는 header directive, nginx는 add_header, Cloudflare는 dashboard에서 각각 명시 — 등급: planned

진행 중 메모

  • Caddy Automatic HTTPS 동작: HTTP(80) 요청을 HTTPS로 redirect하고 ACME 인증서 발급·background 갱신을 수행한다. HSTS는 이 기능의 default가 아니며 별도 header 설정이 필요하다. 정확한 갱신 시점 수치는 issuer 정책에 의존한다.
  • certbot --nginx plugin은 nginx config 자동 수정. 수동 관리하려면 --webroot 또는 --standalone.
  • Let's Encrypt rate limit: 도메인당 주 50회 cert 발급. 학습 중 반복 실수 주의.
  • Cloudflare Tunnel origin이 HTTP라도 edge ↔ Cloudflare ↔ origin 구간은 Cloudflare 사설 네트워크. 클라이언트 ↔ edge는 HTTPS. origin port 0 open 가능 (egress only).
  • ALB + ACM은 cert 자동 갱신 + AWS-native, 비용은 ALB $20~/월 + 트래픽. 학습 환경에 과함.

옵션 비교표 초안

항목 Caddy nginx + certbot Cloudflare Tunnel EC2 + ALB + ACM
설정 복잡도 1줄 server block + certbot CLI tunnel config (yml) Terraform / 콘솔
cert 발급 자동 (Let's Encrypt) 수동 1회 (certbot) 자동 (Cloudflare) 자동 (ACM)
cert 갱신 자동 (내장) certbot.timer (자동) 자동 (Cloudflare) 자동 (ACM)
만료 사고 위험 낮음 중 (cron 실패 시) 낮음(공급자 관리) 낮음(조건 충족 시 managed renewal)
TLS 1.2+ enforce 디폴트 명시 (ssl_protocols) dashboard ALB Security Policy
HSTS header 명시 (default 아님 — CADDY-AHTTPS-C11) add_header 명시 dashboard ALB / WAF
비용 무료 무료 무료 (Cloudflare account) ALB ~$20/월 + 트래픽
학습 환경 적합도 높음 매우 높음 (edge-managed certificate) 낮음 (과함)
운영 환경 적합도 중~높음 높음 (전통) 중 (vendor 의존) 매우 높음 (AWS-native)

결정 사항 (decisions)

  • 2026-05-25: 학습 환경 1순위 Cloudflare Tunnel (edge TLS). 이유: certificate lifecycle을 edge 공급자가 관리해 학습자의 수동 발급·갱신 부담이 작다. 갱신 실패가 없다는 보장은 하지 않는다. sub-sub-branch -6-1 Cloudflare Tunnel 결정과 자연스럽게 연결.
  • 2026-05-25: 학습 환경 2순위 Caddy (EC2 public IP를 직접 노출하는 시나리오). 이유: 1줄 config + auto_https + Let's Encrypt 내장. (주의: HSTS 는 Caddy default 아님header directive 명시 필요. CADDY-AHTTPS-C11 이 공식 페이지에 HSTS 언급 부재를 근거로 기록. 초기 메모의 "HSTS 디폴트"는 반증됨.)
  • 2026-05-25: nginx + certbot은 비교 대상으로만. 이유: 전통적 운영 환경에서는 표준이나 학습 friction이 Caddy 대비 높음 (cron renew 실패 사고).
  • 2026-05-25: EC2 + ALB + ACM은 운영 환경 대안으로만 기재. 본 P3B 범위는 단일 EC2 학습 → ALB / multi-AZ는 과함.
  • 2026-05-25: TLS 1.2+ enforce + HSTS는 어떤 옵션을 선택하든 강제. 학습이라도 보안 디폴트 leak 안 함.
  • 2026-05-25: 본 sub-sub-branch 전체 등급 documented-only. 실 cert 발급 / Caddy 또는 nginx 구동은 P3A 완료 후 선택적 확장 시점에 재검토.

결정-근거 매핑

각 결정이 어떤 raw source claim 으로 뒷받침되는지 명시. Decision ID 는 본 branch-note 안에서 안정적으로 유지.

Decision ID Decision 선택 조건 (언제 이 결정 / 언제 대안) Supporting Claims Evidence Strength Open Risk
D1 학습 환경 1순위 Cloudflare Tunnel (edge TLS) — certificate lifecycle을 공급자가 관리 수동 cert 발급·갱신 부담을 줄이고 public 도메인을 Cloudflare 로 확보할 때 이 결정. 갱신 실패가 없다는 보장은 하지 않는다. EC2 public IP 를 직접 노출해야 하면 → D2(Caddy) raw/official-docs/cloudflare-tunnel-routing-official.md#CLOUDFLARE-TUNNEL-C1 (cloudflared outbound-only), raw/official-docs/cloudflare-tunnel-routing-official.md#CLOUDFLARE-TUNNEL-C2 (firewall inbound 차단 권장), raw/official-docs/cloudflare-tunnel-routing-official.md#CLOUDFLARE-TUNNEL-C5 (locally-managed tunnel DNS routing 명령) official-vendor-doc TLS 가 Cloudflare edge ↔ origin 구간에서 어떻게 종단되는지 (origin HTTP) 의 정확한 header 동작과 certificate 갱신 조건은 본 raw 인용으로 직접 보증 안 됨 — 로컬 검증 및 별도 SSL/TLS 공식 문서 필요 (feature-keycloak-reverse-proxy-headers 의 X-Forwarded-* 와 결합)
D2 학습 환경 2순위 Caddy (1줄 config + auto_https + Let's Encrypt 내장; HSTS 는 header directive 명시 필요 — default 아님, CADDY-AHTTPS-C11) EC2 public IP 를 직접 노출(Cloudflare 미사용)하고 1줄 config 로 cert 자동화를 원할 때. 전통 nginx 스택 표준화가 목표면 → D3 raw/official-docs/caddy-automatic-https-docs.md#CADDY-AHTTPS-C1 (TLS cert 자동 발급 + 자동 갱신 — "Automatic HTTPS provisions TLS certificates for all your sites and keeps them renewed"), #CADDY-AHTTPS-C2 (default 로 모든 site 를 HTTPS 로 serve), #CADDY-AHTTPS-C3 (public ACME CA — Let's Encrypt 또는 ZeroSSL), #CADDY-AHTTPS-C4 (HTTP → HTTPS redirect + managed cert 자동 갱신 default), #CADDY-AHTTPS-C5 (renewal background 수행, subdomain 은 명시 설정 필요), #CADDY-AHTTPS-C6 (hostname 인식 시 implicit 활성화) official-vendor-doc "HSTS 디폴트" 주장은 본 raw 로 입증 불가CADDY-AHTTPS-C11 은 본 페이지에 HSTS 직접 언급 없음을 명시적 부재 사실로 기록. D2 의 HSTS 부분은 별도 출처 (Caddy tls / header directive 페이지) 보강 필요. 또한 CADDY-AHTTPS-C5 는 renewal background 만 보증, "만료 30일 전" 같은 정확 timing 은 별도 ACME issuer 정책 의존
D3 nginx + certbot 은 비교 대상으로만 (학습 friction, cron renew 실패 사고 위험) 기존 nginx 운영 표준에 편입해야 할 때만. 학습·저마찰이 목표면 → D2(Caddy). 본 branch 에서는 비교 baseline 으로만 raw/official-docs/certbot-user-guide.md#CERTBOT-UG-C1 (subcommand 체계 — obtain/renew/revoke), #CERTBOT-UG-C2 (대부분 installation 은 automated renewal preconfigured — certbot renew scheduled task), #CERTBOT-UG-C3 (scheduled task 구체 구현은 OS/installer 의존), #CERTBOT-UG-C4 (Nginx plugin — "should work for most configurations", --nginx rollback 지원), #CERTBOT-UG-C5 (Certbot 4.0.0 부터 renewal 임계 = lifetime 의 1/3 미만), #CERTBOT-UG-C6 (--pre-hook / --post-hook / --deploy-hook 지원) official-vendor-doc "cron renew 실패 사고 위험" 의 정량적 비교는 본 raw 로 직접 보증되지 않음 — CERTBOT-UG-C3 가 "OS / installer 의존" 만 진술. 실제 systemd timer vs cron 의 신뢰성 비교는 운영 사례 / wiki 합성 단계에서 별도 분석 필요
D4 EC2 + ALB + ACM 은 운영 환경 대안으로만 기재 (단일 EC2 학습 범위 초과) multi-AZ / production-grade managed cert 가 요구될 때. 단일 EC2 학습 범위면 → D1/D2. 본 branch 에서는 운영 대안 기재만 raw/official-docs/aws-acm-managed-renewal.md#AWS-ACM-RENEW-C1 (Amazon-issued cert 의 managed renewal — DNS validation 시 자동), #AWS-ACM-RENEW-C2 (public + private cert 모두 적용), #AWS-ACM-RENEW-C3 (ELB / CloudFront 등 AWS service attach 시 자동 갱신 ELIGIBLE), #AWS-ACM-RENEW-C8 (갱신 시 ARN 유지 → listener config 무수정), #AWS-ACM-RENEW-C9 (regional resource — multi-region 독립 갱신), #AWS-ACM-RENEW-C11 (DNS validation cert 의 fully automated renewal), #AWS-ACM-RENEW-C12 (만료 45일 전 갱신 시도, legacy 395-day cert 의 경우 60일 전), #AWS-ACM-RENEW-C13 (갱신 사전 조건: AWS service 사용 중 + CNAME public DNS 존재), #AWS-ACM-RENEW-C14 (실패 시 EventBridge alert 30/15/7/3/1일 전) official-vendor-doc ALB Security Policy (TLS 1.2 enforce) 는 본 raw 로 입증 불가 — ACM 은 cert 발급/갱신만 진술, listener TLS policy 는 ELB 측 별도 문서. "ACM cert renew 실패 사고 0" 도 본 raw 가 직접 보증하지 않음 (C14 는 alert schedule 만 진술) — Route53 CNAME 영구 유지 + AWS service attach 가 동시 충족되어야 함 (C13)
D5 TLS 1.2+ enforce + HSTS 는 어떤 옵션을 선택하든 강제 (학습이라도 보안 디폴트 leak 안 함) N/A — D1~D4 어느 옵션을 선택하든 무조건 강제 (분기 없음) TLS 1.0/1.1 deprecation: raw/official-docs/rfc8996-tls10-tls11-deprecation.md#RFC8996-C1 (TLS 1.0/1.1 formally deprecated → Historic), #RFC8996-C4 ("TLS 1.0 MUST NOT be used"), #RFC8996-C5 ("TLS 1.1 MUST NOT be used"), #RFC8996-C6 (BCP 195 의 SHOULD NOT → MUST NOT 강화). HSTS: raw/official-docs/owasp-hsts-cheat-sheet.md#OWASP-HSTS-C1 (HSTS 는 opt-in response header), #OWASP-HSTS-C2 (활성 시 HTTP → HTTPS 자동 redirect), #OWASP-HSTS-C3 (invalid cert 경고 override 불가), #OWASP-HSTS-C4 (권장 헤더 예시 max-age=63072000; includeSubDomains; preload), #OWASP-HSTS-C6 (includeSubDomains 생략 시 cookie 공격 위험) TLS 1.0/1.1 deprecation: official-standard (RFC 8996 = IETF Standards Track). HSTS: official-reference (OWASP cheatsheet — 표준 아님; RFC 6797 별도) RFC 8996 은 TLS 1.0/1.1 의 MUST NOT 만 보증 — "TLS 1.2 가 충분히 안전" 또는 "TLS 1.3 권장" 은 별도 RFC 8446 / 8447 영역. OWASP HSTS 는 cheatsheet (reference) 이므로 official standard 로 격상 금지. OWASP-HSTS-C5 의 preload PERMANENT CONSEQUENCES 는 학습 도메인에 preload 금지 권고로 반영 필요 (Claims To Verify §HSTS preload 항목 참조)
D6 본 sub-sub-branch 전체 등급 documented-only (실 cert 발급 / Caddy or nginx 구동 보류) N/A — 부모 P3B 의 documented-only 정책에 종속, 실 구동은 P3A 완료 후 재검토 UNSUPPORTED_DECISION (project scope 결정 — 외부 raw 가 아닌 부모 branch P3B 의 documented-only 정책에 종속) UNSUPPORTED_DECISION scope 결정 자체는 외부 raw 인용 불필요 — 부모 branch decision 만 root

구현 가이드

본 branch 는 전체 등급 documented-only (D6) — 실 cert 발급/구동은 P3A 완료 후 선택적 확장. 따라서 본 §는 확장 시 되묻지 않도록 각 옵션의 config-level 명세를 결정별로 catalog 한다. 주의 (R2 라벨 원칙): config 문법 detail (Caddyfile 정확한 syntax / nginx directive line / cloudflared config key / ALB Security Policy) 은 수집한 raw 가 동작 원리만 보증하고 정확한 문법은 보증하지 않으므로 UNSUPPORTED_IMPL_DECISION 라벨 — 실 확장 시 vendor 문법 페이지로 재확인 대상 (Claims To Verify 와 연결).

1. Cloudflare Tunnel edge TLS (학습 1순위)

Trace: D1 → CLOUDFLARE-TUNNEL-C1 (cloudflared outbound-only), -C2 (inbound firewall 차단), -C5 (locally-managed tunnel DNS routing).

  • UNSUPPORTED_IMPL_DECISION: cloudflared config 의 정확한 ingress: 문법 + service: http://localhost:8080 매핑은 수집 raw 에 없음 (routing 원리만 보증) — trade-off: 학습 1순위라 우선 문서화하나 실 확장 시 Cloudflare Tunnel config 페이지 인용 보강 필요.
항목 명세 근거 / 라벨
Origin http://localhost:8080 (평문, egress-only) D1 / CLOUDFLARE-TUNNEL-C1
Edge TLS Cloudflare edge 가 TLS 종단하고 edge certificate lifecycle을 관리 D1 (정확한 갱신 보장은 Claims To Verify §Cloudflare 확인 대상)
Inbound port EC2 inbound 전부 차단 (tunnel egress-only) D1 / CLOUDFLARE-TUNNEL-C2
DNS routing locally-managed tunnel → cloudflared DNS route 명령 D1 / CLOUDFLARE-TUNNEL-C5
X-Forwarded-Proto edge 가 https 주입 → Keycloak 이 소비 의존: raw/branch-notes/feature-keycloak-reverse-proxy-headers D1 (§엣지·실패·의존)

2. Caddy 1줄 config (학습 2순위 — EC2 직접 노출)

Trace: D2 → CADDY-AHTTPS-C1 (cert 자동 발급+갱신), -C2 (default HTTPS serve), -C3 (Let's Encrypt/ZeroSSL ACME), -C4 (HTTP→HTTPS redirect), -C5 (background renewal).

  • UNSUPPORTED_IMPL_DECISION: (a) Caddyfile 정확한 문법 kc.example.com { reverse_proxy localhost:8080 } 은 수집 raw 미보증(auto-HTTPS 원리만) — trade-off: 관행적으로 널리 쓰이나 문법은 Caddyfile 페이지로 재확인. (b) "HSTS 디폴트" 는 CADDY-AHTTPS-C11 이 부재를 명시 → HSTS 는 Caddy header directive 로 명시 필요로 가정, default 로 단정 금지 (D2 Open Risk 와 동일).
항목 명세 근거 / 라벨
Config Caddyfile 1줄: kc.example.com { reverse_proxy localhost:8080 } D2 / UNSUPPORTED_IMPL_DECISION (문법)
Cert 발급 auto_https default → public ACME CA (Let's Encrypt/ZeroSSL) D2 / CADDY-AHTTPS-C3
Cert 갱신 background 자동 (정확한 "만료 N일 전" timing 은 ACME issuer 정책 의존) D2 / CADDY-AHTTPS-C5
HTTP→HTTPS default redirect D2 / CADDY-AHTTPS-C4
HSTS header Strict-Transport-Security ... 명시 필요 (default 로 단정 금지) D2 / CADDY-AHTTPS-C11 (부재 근거) → UNSUPPORTED_IMPL_DECISION
TLS min TLS 1.2 minimum (Caddy 관행 default) D5 / UNSUPPORTED_IMPL_DECISION (정확 min version 은 Caddy tls 페이지 재확인)

3. nginx + certbot (운영 비교 baseline)

Trace: D3 → CERTBOT-UG-C1 (subcommand), -C2 (automated renewal preconfigured), -C4 (--nginx plugin), -C5 (4.0.0+ renewal 임계 = lifetime 1/3), -C6 (deploy-hook).

  • UNSUPPORTED_IMPL_DECISION: nginx server block 의 정확한 directive (ssl_protocols TLSv1.2 TLSv1.3;, add_header Strict-Transport-Security ...) 는 certbot raw 가 보증 안 함 (certbot 은 cert 발급/갱신만) — trade-off: nginx TLS/HSTS directive 는 nginx 문서 영역이고 본 branch 는 비교 baseline 이라 원리 수준만.
항목 명세 근거 / 라벨
발급 certbot --nginx -d kc.example.com → server block 자동 삽입 D3 / CERTBOT-UG-C4
갱신 certbot.timer (automated renewal preconfigured), 임계 = lifetime 1/3 D3 / CERTBOT-UG-C2, -C5
deploy-hook --deploy-hook 으로 갱신 후 nginx reload D3 / CERTBOT-UG-C6
TLS min ssl_protocols TLSv1.2 TLSv1.3; 명시 D5 / UNSUPPORTED_IMPL_DECISION (nginx directive)
HSTS add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; 명시 D5 / OWASP-HSTS-C4 (헤더 값) + UNSUPPORTED_IMPL_DECISION (nginx add_header 문법)

4. EC2 + ALB + ACM (운영 대안 — 기재만)

Trace: D4 → AWS-ACM-RENEW-C1/-C11 (DNS-validated 자동 갱신), -C3 (ELB attach 자격), -C8 (ARN 유지 → 무수정 갱신), -C12 (만료 45/60일 전 갱신), -C13 (갱신 사전조건), -C14 (EventBridge alert).

  • UNSUPPORTED_IMPL_DECISION: ALB Security Policy (TLS 1.2 enforce) 는 ACM raw 밖 (ELB listener 문서 영역) — D4 Open Risk 와 동일. trade-off: 운영 대안 기재만이므로 Terraform/console 실배치는 본 branch scope 밖.
항목 명세 근거 / 라벨
Cert ACM DNS-validated → fully automated renewal D4 / AWS-ACM-RENEW-C11
Attach ALB listener 에 attach (ARN 유지 → 무수정 갱신) D4 / AWS-ACM-RENEW-C3, -C8
갱신 사전조건 AWS service 사용 중 + CNAME public DNS 유지 D4 / AWS-ACM-RENEW-C13
실패 alert EventBridge 30/15/7/3/1일 전 D4 / AWS-ACM-RENEW-C14
TLS policy ALB Security Policy = TLS 1.2 min D5 / UNSUPPORTED_IMPL_DECISION (ELB 문서 영역)

5. cert 갱신 자동화 + TLS/HSTS enforce 위치 (cross-cutting)

Trace: D5 → RFC8996-C4/-C5 (TLS 1.0/1.1 MUST NOT), OWASP-HSTS-C4 (권장 헤더값), -C6 (includeSubDomains 생략 위험). 갱신 메커니즘은 옵션별 §1~§4 참조.

  • UNSUPPORTED_IMPL_DECISION: 각 proxy 의 TLS min / HSTS 를 어느 config 라인에 넣는지의 정확한 문법은 §2~§4 라벨 참조 — 값(max-age, includeSubDomains)은 OWASP-HSTS-C4 로 보증, 위치·문법은 vendor 별.
옵션 cert 갱신 TLS 1.2+ enforce 위치 HSTS 위치
Cloudflare Tunnel edge 자동 (D1) Cloudflare dashboard dashboard (edge)
Caddy 내장 background (D2) tls directive (관행 default) header directive 명시 (§2)
nginx+certbot certbot.timer (D3) ssl_protocols (§3) add_header (§3)
ALB+ACM ACM 자동 (D4) ALB Security Policy (§4) ALB / WAF

HSTS 공통 정책 (D5): 권장값 max-age=63072000; includeSubDomains (OWASP-HSTS-C4), includeSubDomains 생략 시 cookie 공격 노출(OWASP-HSTS-C6). preload 는 학습 도메인에 금지 — 되돌리기 PERMANENT (Claims To Verify §HSTS preload).

엣지·실패·의존

R4(깊이 게이트) 캡처. 본 branch 는 documented-only 이므로 아래 실패 경로는 실 확장 시 부딪힐 함정(진행 중 메모·마주친 문제에서 승격)이고, 의존은 TLS 종단 위치가 다른 계약에 미치는 영향이다.

  • 실패·엣지 경로:

    • Let's Encrypt rate limit — 도메인당 주 50회 발급. 디버깅 반복 시 --staging endpoint 사용 (D2/D3 확장 시). → Claims To Verify §rate limit (공식 raw 미수집).
    • ACME-HTTP-01 challenge 는 80 port 점유 필요 — Keycloak 이 80 을 안 쓰는지 확인(충돌 시 발급 실패). Caddy/certbot 공통(D2/D3).
    • certbot.timer 비활성 — Ubuntu default enable 이나 minimal 이미지에서 누락 → cert 만료 사고(D3). → Claims To Verify §certbot.timer.
    • Caddy HSTS 오인 — "default HSTS" 가정 시 실제 미적용 가능(CADDY-AHTTPS-C11 부재 근거) → header directive 명시로 방어(구현 가이드 §2).
    • HSTS preload 되돌리기 불가 — 한 번 등록 시 subdomain 전체 HTTPS 강제 PERMANENT → 학습 도메인 preload 금지(D5, OWASP-HSTS-C6 계열).
    • Cloudflare Tunnel origin verification — edge 는 self-signed origin 도 허용하나 학습은 HTTP origin 이 단순(D1).
  • 다른 계약 의존:

    • raw/branch-notes/feature-keycloak-reverse-proxy-headersD1 (KC_PROXY_HEADERS=xforwarded) 에 의존 — TLS 종단 위치가 X-Forwarded-Proto: https출처를 결정한다. Cloudflare Tunnel(D1)은 origin 이 HTTP 이므로 edge 가 헤더를 주입해야 Keycloak 이 HTTPS 인식; Caddy(D2)/nginx(D3)는 proxy 가 종단하며 헤더를 세팅. 그 계약이 바뀌면(예: forwarded 모드 전환) 본 branch 의 종단-위치별 헤더 주입 가정이 깨진다.
    • raw/branch-notes/feature-keycloak-public-domain-tunneling 에 의존 — D1(Cloudflare Tunnel edge TLS)은 이 branch 의 public 도메인/tunnel 확보를 전제한다. tunnel 미확보면 D1 → D2(Caddy) fallback.
    • raw/branch-notes/feature-keycloak-google-redirect-uri-policy 에 의존(역방향 — 본 branch 의 WHY) — Google OAuth 의 HTTPS redirect_uri 강제가 본 branch 의 존재 이유. TLS 종단이 없으면 그 정책을 충족 불가.

검증해야 할 주장

공식 문서나 사례는 근거지만, 내 프로젝트에서의 동작을 자동으로 보장하지 않는다.

Claim Why uncertain How to verify Status
Caddy Caddyfile 1줄 (kc.example.com { reverse_proxy localhost:8080 }) + auto_https on 디폴트로 Let's Encrypt cert 자동 발급 동작 Caddy 공식 raw 미수집 — 본 branch 의 진행 중 메모는 관행적 사실 실제 EC2 또는 로컬 도커에서 Caddy 구동 → DNS A 레코드 매핑 → 첫 요청 시 ACME-HTTP-01 challenge 로그 + 발급된 cert 확인 planned
Cloudflare Tunnel edge certificate의 발급·갱신 조건과 실패 시 운영 책임 CLOUDFLARE-TUNNEL-C1/C2 는 outbound tunnel 동작만 보증하고 certificate lifecycle 조건은 직접 입증하지 않음 (별도 Cloudflare SSL/TLS 페이지 필요) Cloudflare dashboard → SSL/TLS → Edge Certificates → auto-renew 정책 확인 + cert expiry 모니터링 needs-confirmation
certbot.timer 가 Ubuntu 디폴트로 enable + 정상 동작 certbot 공식 raw 미수집 — 관행적 사실 systemctl list-timers | grep certbot + certbot renew --dry-run 실행하여 종료 코드 0 확인 planned
Let's Encrypt rate limit 도메인당 주 50회 Let's Encrypt 공식 raw 미수집 — 본 branch 의 진행 중 메모는 관행적 사실 Let's Encrypt rate limits 페이지 직접 발췌 후 raw/official-docs/ 등록 planned
HSTS preload 등록 후 subdomain 전체 HTTPS 강제 + 학습 도메인 preload 금지 권고 HSTS preload 공식 raw 미수집 — 관행적 사실 hstspreload.org 정책 페이지 발췌 후 인용 보강 planned

마주친 문제

  • 아직 없음 (문서 단계). 실 적용 시 예상되는 함정:
    • Let's Encrypt rate limit: 도메인당 주 50회 cert 발급. 디버깅 반복 시 staging endpoint (--staging) 활용.
    • ACME-HTTP-01 challenge 시 80 port 점유 필요 → Keycloak이 80을 안 쓰는지 확인.
    • certbot.timer 비활성: Ubuntu 디폴트로 enable되어 있으나 일부 minimal 이미지에서 누락 → cert 만료 사고.
    • Cloudflare Tunnel origin verification: edge에서 self-signed cert origin도 허용하나 학습 환경에서는 HTTP origin이 단순.
    • HSTS preload 등록 후 실수: 한 번 preload에 등록되면 subdomain 전체가 HTTPS 강제 → 학습 도메인에는 preload 금지.

묶음

본 branch 는 leaf — 자식 자료 없음. errors / interview prep / lectures 가 누적되면 본 섹션에서 그룹화.

오류 기록

  • (없음)

면접 준비

  • (없음)

관련 일일 노트

완료 후 정리

본 sub-sub-branch는 문서까지만. 실 Caddy / nginx 설치 / cert 발급은 P3A 완료 후 선택적 확장.

  • PR 링크:
  • 리뷰 메모:
  • 머지 결과 / 배포 환경: 해당 없음 (문서 단계, P3B 전체 documented-only)
  • wiki 추출 대상 (verified만, wiki/projects/로만 추출):
    • actually-implemented 항목: 없음
    • locally-verified 항목: 없음
    • prod-verified 항목: 없음
  • 추출하지 않을 항목 (planned / documented-only / abandoned):
    • 본 sub-sub-branch 전체가 documented-only. 추후 wiki/concepts/keycloak-deployment-patterns.md 합성 시 "HTTPS termination 옵션 비교표"로 인용 후보.