265 lines
24 KiB
Markdown
265 lines
24 KiB
Markdown
---
|
|
title: branch / feature-keycloak-public-domain-tunneling (P3B 학습 환경 public 도메인 확보 — ngrok / Cloudflare Tunnel)
|
|
source_type: branch-note
|
|
status: raw
|
|
id: BR-KEYCLOAK-CHILD-89A2896F
|
|
kind: branch-child
|
|
project: keycloak-patterns-overview
|
|
work_item: WI-KEYCLOAK-PATTERNS-OVERVIEW-020
|
|
inherits: [DEC-KEYCLOAK-PATTERNS-OVERVIEW-AUTH-TAXONOMY-001@1]
|
|
refines: []
|
|
overrides: []
|
|
depends_on: []
|
|
contract_packet: 1
|
|
branch: feature-keycloak-public-domain-tunneling
|
|
parent_branch: feature-keycloak-patterns
|
|
related_projects: [keycloak-patterns]
|
|
tags: [branch, keycloak-patterns, p3b, public-domain, ngrok, cloudflare-tunnel, https]
|
|
created: 2026-05-25
|
|
target_merge:
|
|
status_label: in-progress
|
|
contract_packet_sha256: 5605aa356ecefd27cabba9dff6699e3058ee39235cbb0dd012b97176fb46a417
|
|
---
|
|
|
|
# branch: feature-keycloak-public-domain-tunneling (P3B 학습 환경 public 도메인 확보 — ngrok
|
|
|
|
> Layer: `raw/branch-notes/` — [[raw/branch-notes/feature-keycloak-patterns]] governance Work Item의 child. P3B 의미 계약은 [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]]를 참조한다. **Google OAuth redirect_uri 정책(HTTPS + localhost 외 IP 불가)** 때문에 학습 환경에서 어떻게 public URL을 확보할지 비교.
|
|
> 본 sub-sub-branch는 **문서까지만** — 실 ngrok 구동 / Cloudflare Tunnel 설치 / EC2 도메인 매핑은 진행하지 않음. 등급 `documented-only` (P3B 전체 등급에 종속).
|
|
> `status_label`: `in-progress`
|
|
|
|
<!-- section-id: branch-parent -->
|
|
## 부모 (필수)
|
|
|
|
[[raw/branch-notes/feature-keycloak-patterns]]
|
|
|
|
<!-- GENERATED: branch-contract:start -->
|
|
<!-- section-id: branch-contract-packet -->
|
|
## 브랜치 계약 패킷
|
|
|
|
- **생성 시 프로젝트 개정**: `1`
|
|
- **패킷 스키마**: `contract_packet: 1`
|
|
- **완료 조건**: project governance hub가 AP1~AP4 taxonomy와 child progress index를 유지한다
|
|
|
|
<!-- section-id: inherited-project-decisions -->
|
|
### 상속한 프로젝트 결정
|
|
|
|
| Decision Ref | Project Summary | Branch Application | Source |
|
|
|---|---|---|---|
|
|
| `DEC-KEYCLOAK-PATTERNS-OVERVIEW-AUTH-TAXONOMY-001@1` | canonical 분류축은 AP1~AP4 인증 통합 아키텍처와 cross-cutting 변형이다 | single-EC2 Google federation 변형의 public-domain tunnel 경계에 적용한다 | [[raw/project-notes/keycloak-patterns-overview]] |
|
|
|
|
<!-- section-id: branch-local-decisions -->
|
|
### 브랜치 지역 결정
|
|
|
|
> 기존 branch-local 결정은 아래 `## Decision Evidence Map`의 D-row가 소유하며 이 packet에서 복제하지 않는다.
|
|
|
|
| Decision ID | Decision | Relation | Supporting Claims | Status |
|
|
|---|---|---|---|---|
|
|
|
|
<!-- section-id: declared-overrides -->
|
|
### 선언한 예외
|
|
|
|
| Override ID | Overrides | Reason | Approval | Status |
|
|
|---|---|---|---|---|
|
|
|
|
없음.
|
|
<!-- GENERATED: branch-contract:end -->
|
|
|
|
<!-- section-id: branch-goal -->
|
|
## 목표
|
|
|
|
P3A에서는 `localhost:8080`으로 모든 통신이 끝났지만 P3B는 **Google이 Keycloak callback URI로 redirect** 해야 한다. Google OAuth 2.0 client는 **redirect_uri를 HTTPS 도메인으로 제한** (localhost는 dev 한정 예외, raw IP 금지). 따라서 학습 환경에서도 public 접근 가능한 HTTPS URL을 어떻게 확보할지 결정해야 한다.
|
|
|
|
면접에서 답해야 할 질문:
|
|
1. 학습 환경에서 왜 EC2 public IP만으론 부족한가? → Google이 IP 주소 redirect_uri 거부, HTTPS + 도메인 강제.
|
|
2. 부모가 선택한 public URL 전략을 어떻게 실행하나? → [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]] D3가 provider 우선순위를 소유하고, 본 문서는 named tunnel·managed custom domain과 임시 random URL의 운영 차이만 구체화한다.
|
|
3. 학습 → 운영 전환 시 무엇이 바뀌나? → tunnel 제거하고 EC2 public IP + Route53 A 레코드 + ACM cert로 대체.
|
|
|
|
- 이슈:
|
|
- PR:
|
|
|
|
<!-- section-id: branch-scope -->
|
|
## 범위
|
|
|
|
### 포함 범위
|
|
|
|
- ngrok / Cloudflare Tunnel / EC2 + Route53 도메인 3개 옵션의 trade-off
|
|
- 비교표: cost / static URL / TLS 자동 / 운영 비용 / inbound port 노출
|
|
- Google redirect_uri 정책과 각 옵션의 적합도
|
|
- 부모 [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]] D3의 채택 결정을 소비해 Cloudflare named tunnel·managed custom domain, ngrok 임시 URL, EC2 도메인 옵션의 실행 메커니즘을 정리
|
|
|
|
### 제외 범위
|
|
|
|
- 실 ngrok account 생성, Cloudflare account 연동, cloudflared 데몬 설치
|
|
- 자체 도메인 구매 / Route53 hosted zone 생성
|
|
- 운영용 ACM cert / ALB 구성 (P3B 운영 시나리오는 부모 sub-branch의 "대안 3"로만 언급)
|
|
- ngrok / Cloudflare Tunnel의 enterprise 기능 (custom domain on free plan 제외, IP allowlist 등)
|
|
|
|
## 근거 (필수, 최소 1개+)
|
|
|
|
- [[raw/official-docs/ngrok-http-tunnel-official]] — ngrok HTTP tunnel 공식
|
|
- [[raw/official-docs/cloudflare-tunnel-routing-official]] — Cloudflare Tunnel routing 공식
|
|
- [[raw/official-docs/google-oauth2-redirect-uri-validation-official]] — Google redirect_uri 정책 (HTTPS + localhost 외 IP 불가)
|
|
|
|
## TODO
|
|
|
|
각 항목 옆에 증거 등급 표기.
|
|
|
|
- [ ] **ngrok 무료 plan 동작 확인** — `ngrok http 80` → `https://<random>.ngrok-free.app` 임시 URL 발급, 세션 종료 시 URL 변경 — 등급: `planned`
|
|
- [ ] **Cloudflare Tunnel 동작 확인** — `cloudflared tunnel create <name>` + `cloudflared tunnel route dns <name> kc.example.com` → named tunnel과 Cloudflare가 관리하는 custom hostname 연결. `trycloudflare.com` quick tunnel의 random URL은 고정 callback으로 사용하지 않음 — 등급: `planned`
|
|
- [ ] **EC2 public IP + Route53 도메인 옵션 정리** — Route53 hosted zone + A 레코드 + ACM cert + ALB (또는 EC2 직결 + nginx + Let's Encrypt) — 등급: `planned`
|
|
- [ ] **비교표 작성** — cost / static URL / TLS 자동 / inbound port 노출 / 운영 비용 / Google Console redirect_uri exact match 적합도 — 등급: `planned`
|
|
- [ ] **부모 결정 수용 확인** — [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]] D3의 Cloudflare named tunnel + managed custom domain 기본 경로와 random URL dev-only fallback을 본 실행 절차에 반영 — 등급: `planned`
|
|
|
|
## 진행 중 메모
|
|
|
|
- ngrok free plan은 2026-05 기준 1 세션당 random subdomain. `https://<8자>.ngrok-free.app` 형식. 세션 끊기면 다음 세션은 다른 subdomain.
|
|
- Cloudflare Tunnel의 `trycloudflare.com` quick tunnel은 무료지만 URL이 random (ngrok와 유사). 정적 도메인 원하면 Cloudflare account + 자체 도메인 (Cloudflare DNS로 위임) + named tunnel 필요.
|
|
- EC2 public IP는 인스턴스 stop/start 시 변경 (Elastic IP 할당하면 고정). 도메인 매핑 안 하면 Google이 redirect_uri로 IP 거부.
|
|
- 학습 환경 핵심: **Google Console에 등록한 redirect_uri와 실제 Keycloak issuer URL이 글자 단위로 일치**해야 함 (Google exact match 정책). URL 변경 시마다 Console 업데이트 필요.
|
|
|
|
### 비교표 초안
|
|
|
|
| 항목 | ngrok free | Cloudflare Tunnel (named) | EC2 + Route53 + ACM |
|
|
|------|-----------|---------------------------|---------------------|
|
|
| cost | 무료 | 무료 (Cloudflare account 필요) | Route53 hosted zone $0.50/월 + ACM 무료 + EC2 비용 |
|
|
| static URL | ❌ (세션마다 변경) | ✅ (영구) | ✅ |
|
|
| TLS 자동 | ✅ (ngrok edge) | ✅ (Cloudflare edge) | ACM + ALB (자동) 또는 Let's Encrypt (cron) |
|
|
| inbound port 노출 | 불필요 (egress only) | 불필요 (egress only) | 필요 (443 open) |
|
|
| 운영 비용 | 매 세션 Console 갱신 | 도메인 1회 설정 후 무 | DNS / cert / SG 관리 |
|
|
| Google redirect_uri 적합도 | 낮음 (URL 변경 burden) | 높음 (정적) | 높음 (정적) |
|
|
|
|
## 결정 사항 (decisions)
|
|
|
|
- **2026-05-25 (Historical / superseded selection wording)**: 본 문서가 Cloudflare 1순위·ngrok 2순위를 직접 결정한다고 적었으나, provider 우선순위의 owner는 부모 [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]] D3이다. 본 문서는 선택 결과의 운영 메커니즘만 소유한다.
|
|
- **2026-07-18 (Reference-Only)**: 부모 D3가 Cloudflare 경로를 선택하면 **named tunnel + Cloudflare 관리 custom hostname**을 stable Google callback으로 사용한다. `trycloudflare.com` quick tunnel과 ngrok random hostname은 dev-only이며 URL이 바뀌면 Google Console 값을 함께 갱신한다.
|
|
- **2026-05-25**: 운영 환경 옵션 **EC2 + Route53 + ACM + ALB**. 본 sub-sub-branch에서는 비교 대상으로만 기재, 실 구성은 P3B 전체가 `documented-only`이므로 진행 안 함.
|
|
- **2026-05-25**: 본 sub-sub-branch 전체 등급 `documented-only`. P3B 부모 결정(문서까지만)에 종속. 실 tunnel 구동 / 도메인 매핑은 P3A 완료 후 선택적 확장 시점에 재검토.
|
|
|
|
## 결정-근거 매핑
|
|
|
|
> 각 결정이 어떤 raw source claim 으로 뒷받침되는지 명시. `Decision ID` 는 본 branch-note 안에서 안정적으로 유지.
|
|
> `선택 조건` 열(R2): "이 조건일 때 이 결정, 다른 조건이면 어떤 대안". 분기 없으면 `N/A`.
|
|
|
|
| Decision ID | Decision | 선택 조건 (언제 이 결정 / 언제 대안) | Supporting Claims | Evidence Strength | Open Risk |
|
|
|---|---|---|---|---|---|
|
|
| D1 | **Cloudflare 운영 profile(부모 D3 소비)** — stable Google callback이 필요하면 named tunnel을 Cloudflare가 관리하는 custom hostname(예: `kc.example.com`)에 연결한다. quick tunnel random URL은 이 profile에 포함하지 않는다. | 부모 [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]] D3가 Cloudflare를 선택하고, 관리 도메인을 확보할 수 있을 때. provider 선택 자체는 본 문서가 재정의하지 않는다. | `raw/official-docs/cloudflare-tunnel-routing-official.md#CLOUDFLARE-TUNNEL-C1` (cloudflared outbound), `raw/official-docs/cloudflare-tunnel-routing-official.md#CLOUDFLARE-TUNNEL-C2` (firewall inbound 차단 권장), `raw/official-docs/cloudflare-tunnel-routing-official.md#CLOUDFLARE-TUNNEL-C3` (tunnel `<UUID>.cfargotunnel.com` subdomain 자동 부여), `raw/official-docs/cloudflare-tunnel-routing-official.md#CLOUDFLARE-TUNNEL-C4` (사용자 hostname CNAME → cfargotunnel.com), `raw/official-docs/google-oauth2-redirect-uri-validation-official.md#GOOGLE-REDIR-C2` (Google redirect URI raw IP 금지 → 도메인 필요) | `official-vendor-doc + official-vendor-doc` | managed custom hostname의 Google 등록과 실제 callback 성공은 P3B 실측 필요. `<UUID>.cfargotunnel.com`이나 `trycloudflare.com` URL을 stable callback으로 간주하지 않는다. |
|
|
| D2 | **ngrok 임시 운영 profile(부모 D3 fallback 소비)** — random URL은 dev-only이며 Google Console redirect_uri 갱신을 동반한다. | 부모 D3가 1회성 데모 fallback을 선택한 경우. 반복 사용·stable callback이면 부모 D3의 Cloudflare named tunnel profile로 돌아간다. | `raw/official-docs/ngrok-http-tunnel-official.md#NGROK-C1` (`ngrok http <port>` 가 random HTTPS hostname 생성), `raw/official-docs/ngrok-http-tunnel-official.md#NGROK-C3` (random hostname 은 기존 Domain object 와 매칭 안 됨), `raw/official-docs/ngrok-http-tunnel-official.md#NGROK-C4` (고정 URL에는 별도 Domain record + DNS CNAME 필요), `raw/official-docs/google-oauth2-redirect-uri-validation-official.md#GOOGLE-REDIR-C3` (exact match) | `official-vendor-doc + official-vendor-doc` | free plan에서 재시작마다 hostname이 바뀌는지는 `NGROK-C1` 인용에 직접 명시되지 않아 별도 확인 필요 |
|
|
| D3 | 운영 환경 옵션 **EC2 + Route53 + ACM + ALB** — 비교 대상으로만 기재 | 운영(production) 환경이거나 tunnel 의존을 제거해야 할 때. 학습 환경이면 → **D1/D2**. **본 branch 범위 밖**(§범위 Out of scope: 운영 ACM/ALB 구성 제외 + 부모 note 의 "대안 3"과 동일 tree 관행: AWS 경로 = 명명된 비교 대안, 전용 raw 미첨부) — 비교 축으로만 존재 | UNSUPPORTED_DECISION / OUT_OF_BRANCH_SCOPE (AWS Route53 / ACM / ALB 공식 raw 미수집 — 본 branch 의 Sources 인용 범위 밖이자 운영 구성 결정은 별도 branch 영역) | `UNSUPPORTED_DECISION` | 실 채택 시점에 AWS 공식 raw 인용 보강 필요 (예: ACM cert 자동 갱신 정책) |
|
|
| D4 | 본 sub-sub-branch 전체 등급 `documented-only` (P3B 부모 결정 종속, 실 tunnel 구동 보류) | P3A 완료 전 학습·문서 단계인 동안 적용. P3A 완료 후 선택적 확장 시점이면 → 실 tunnel 구동 / 도메인 매핑 재검토 (N/A — project scope 결정) | UNSUPPORTED_DECISION (project scope 결정 — 부모 branch P3B 의 `documented-only` 정책에 종속, 외부 raw 인용 불필요) | `UNSUPPORTED_DECISION` | scope 결정 자체는 외부 raw 가 root 가 아님 |
|
|
|
|
## 구현 가이드
|
|
|
|
> 본 branch 는 `documented-only` — 실 코드/구동 없음. 따라서 본 §는 "다음 P3B 확장 작업자가 되묻지 않고 각 옵션을 셋업할 수 있는 수준"의 사전 명세 (등급은 전부 `planned`/`documented-only`). 각 sub-section 은 본 branch 의 `Decision ID` + `Supporting Claim ID` 에서 도출된 것만 기재한다.
|
|
>
|
|
> **범위 경계**: Keycloak `KC_HOSTNAME` / `KC_PROXY_HEADERS` / relative-path / TLS 종단 config 는 본 branch 결정 영역 밖(sibling `feature-keycloak-reverse-proxy-headers` / `feature-keycloak-https-termination-caddy-nginx` 소유) → 여기 재진술하지 않고 §엣지·실패·의존 에 의존 링크로만 둔다 (R3 OUT_OF_BRANCH_SCOPE).
|
|
|
|
### 1. Cloudflare Tunnel (D1) — 부모 D3 선택을 실행하는 named tunnel 셋업 절차
|
|
|
|
> **Trace**: D1 + `CLOUDFLARE-TUNNEL-C1`(outbound-only) / `C2`(inbound 차단 권장) / `C3`(`<UUID>.cfargotunnel.com` 자동 부여) / `C4`(사용자 hostname CNAME → cfargotunnel.com) / `C5`(`cloudflared tunnel route dns`, running 아니면 트래픽 없음).
|
|
>
|
|
> - **UNSUPPORTED_IMPL_DECISION**: (1) tunnel/도메인 명명(`kc.example.com`, `<name>`)은 예시값 — 사용자가 소유·위임한 Cloudflare 관리 도메인에 종속하며 raw 근거 없음(trade-off: 구체 도메인은 실 확장 시점 확정). (2) step 4 ingress `config.yml` 문법(`ingress:` 블록 / `service:` 매핑)은 `CLOUDFLARE-TUNNEL-C1`(outbound-only)이 증명하지 않는 미근거 detail(trade-off: ingress 규칙 공식 페이지 미수집 — 실 셋업 시 Cloudflare Tunnel `config.yml` 문서 참조). documented-only 이므로 둘 다 실 확장 시점 확정.
|
|
|
|
| 단계 | 명령 / 설정 | 근거 | 결과 |
|
|
|---|---|---|---|
|
|
| 1. 전제·인증 | Cloudflare account + Cloudflare DNS 로 위임한 도메인 1개 → `cloudflared tunnel login` (브라우저 인증 → `cert.pem`) | (계정 전제 — raw 밖) | named tunnel + 사용자 CNAME 가능 조건 |
|
|
| 2. tunnel 생성 | `cloudflared tunnel create <name>` | `CLOUDFLARE-TUNNEL-C3` | tunnel UUID + `<UUID>.cfargotunnel.com` 자동 부여 |
|
|
| 3. DNS 라우팅 | `cloudflared tunnel route dns <UUID-or-NAME> kc.example.com` | `CLOUDFLARE-TUNNEL-C4`, `C5` | 사용자 hostname → cfargotunnel.com CNAME 생성 (단 tunnel running 전엔 트래픽 없음) |
|
|
| 4. ingress | `config.yml` 의 `ingress:` 블록에 `kc.example.com` → `service: http://localhost:8080`(Keycloak) 매핑 | `CLOUDFLARE-TUNNEL-C1`(outbound-only) + **UNSUPPORTED_IMPL_DECISION**(ingress 문법 미근거) | origin→Cloudflare outbound, ingress 규칙으로 Keycloak 라우팅 |
|
|
| 5. 구동 | `cloudflared tunnel run <name>` | `CLOUDFLARE-TUNNEL-C1`, `C2` | EC2 SG inbound 0 개로 public HTTPS 노출, TLS 는 Cloudflare edge 종단 |
|
|
|
|
### 2. ngrok (D2) — quick tunnel 셋업 절차
|
|
|
|
> **Trace**: D2 + `NGROK-C1`(`ngrok http <port>` random HTTPS hostname) / `C3`(random hostname = Domain object 미매칭) / `C4`(bring-your-own-domain 절차) + `GOOGLE-REDIR-C3`(exact match → URL 변경 시 재등록).
|
|
>
|
|
> - **UNSUPPORTED_IMPL_DECISION**: "재시작마다 hostname 변경" 은 `NGROK-C1` 인용 범위 밖(관행) → §검증해야 할 주장으로 이관해 별도 확인(trade-off: free plan 정책 페이지 미수집 상태에서 단정 금지).
|
|
|
|
| 단계 | 명령 / 설정 | 근거 | 결과 |
|
|
|---|---|---|---|
|
|
| 0. 전제 | 계정 가입 후 `ngrok config add-authtoken <token>` (authtoken 등록) | (계정 전제 — raw 밖) | ngrok agent 인증 완료 |
|
|
| 1. 임시 URL | `ngrok http 8080` | `NGROK-C1`, `C2`(scheme https default) | `https://<random>.ngrok.app` 발급 |
|
|
| 2. URL 변동성 | (재시작) | `NGROK-C3` | random hostname → reserved Domain 미매칭 → 세션마다 URL 변경 가능 → Google Console redirect_uri 재등록(`GOOGLE-REDIR-C3`) |
|
|
| 3. 고정 URL(선택) | Domain record 생성 + DNS CNAME + matching hostname 으로 endpoint 생성 | `NGROK-C4` | 고정 URL 확보(단 free plan 가부는 미확인 — §검증) |
|
|
|
|
### 3. Google Cloud Console redirect URI 등록 제약 (D1·D2 공통)
|
|
|
|
> **Trace**: `GOOGLE-REDIR-C2`(host = raw IP 금지, localhost 예외) + `GOOGLE-REDIR-C3`(등록값과 byte-level exact match, 불일치 시 `redirect_uri_mismatch`).
|
|
>
|
|
> - **OUT_OF_BRANCH_SCOPE**: 등록할 broker endpoint URL 의 정확한 형식(`/realms/{realm}/broker/google/endpoint` + `KC_HTTP_RELATIVE_PATH` 결합)은 sibling `feature-keycloak-reverse-proxy-headers` / `feature-keycloak-google-redirect-uri-policy` 소유 → 링크만, 재진술 금지.
|
|
|
|
- 등록 host 는 **도메인 필수**(raw IP 금지, `GOOGLE-REDIR-C2`) → D1/D2 의 public URL 이 이 제약을 만족시키는 이유.
|
|
- 등록값은 실제 요청 redirect_uri 와 **정확히 일치**(`GOOGLE-REDIR-C3`) → D2(ngrok random URL) 의 갱신 burden 이 여기서 발생.
|
|
- stable callback은 `<UUID>.cfargotunnel.com` 또는 `trycloudflare.com` 주소가 아니라 Cloudflare가 관리하는 custom hostname을 사용한다. 그 hostname의 Google 등록 성공은 §검증해야 할 주장으로 남긴다.
|
|
|
|
## 엣지·실패·의존
|
|
|
|
> 정상 경로(public URL 확보 → Google redirect 통과) 외에 실 확장 시 부딪힐 실패/엣지와 다른 branch 계약 의존을 미리 열거.
|
|
|
|
- **실패·엣지 경로**:
|
|
- **ngrok URL drift** — free plan 재시작 시 hostname 변경 가능 → 등록 redirect_uri 와 불일치 → `redirect_uri_mismatch`(`GOOGLE-REDIR-C3`). 기대 동작: dev-only로 제한하고 URL 변경 시 Console 갱신, stable callback은 부모 D3가 고른 D1 profile 사용.
|
|
- **Cloudflare 라우팅 ≠ 가용** — `cloudflared` 미실행 시 CNAME 은 있어도 트래픽 안 흐름(`CLOUDFLARE-TUNNEL-C5`). 기대: `cloudflared tunnel run` 데몬 상시 실행(systemd 등).
|
|
- **CNAME 전파 지연** — `cloudflared tunnel route dns` 직후 DNS 전파 지연(수초~수분)으로 등록 URL 이 일시 미해석 → Google redirect 일시 실패 가능. 기대: `dig <host>` 로 전파 확인 후 Google 등록/로그인 시도.
|
|
- **cfargotunnel 도메인 정책 미검증** — Google 이 `<UUID>.cfargotunnel.com` generic subdomain 을 거부할 가능성(`GOOGLE-REDIR-C2` 는 raw IP 만 금지, generic subdomain 은 미보증). 기대: 거부 시 사용자 소유 도메인 CNAME 으로 우회(`CLOUDFLARE-TUNNEL-C4`). → §검증.
|
|
- **outbound 443 차단 환경** — 방화벽이 outbound 를 막으면 cloudflared 미동작(`CLOUDFLARE-TUNNEL-C1` "Does not prove" 단서). 기대: egress 443 허용 확인.
|
|
- **quick tunnel 혼동** — `trycloudflare.com` quick tunnel 은 random URL(ngrok 유사). 정적 도메인이 목표면 named tunnel + 계정 도메인 필요(진행 중 메모).
|
|
- **다른 계약 의존**:
|
|
- [[raw/branch-notes/feature-keycloak-reverse-proxy-headers]] `D7`(`KC_HOSTNAME=https://kc.example.com`) + `D1`(`KC_PROXY_HEADERS=xforwarded`) + `D6`(`KC_HTTP_ENABLED=true` + `KC_PROXY_TRUSTED_ADDRESSES`) — 본 branch 가 고른 public host 를 그 branch 가 Keycloak issuer 로 주입. 그 계약(hostname 형식 / `D3` relative path `/keycloak`)이 바뀌면 본 branch 의 redirect URI 등록값도 영향.
|
|
- [[raw/branch-notes/feature-keycloak-google-redirect-uri-policy]] `D1`(broker endpoint URL 을 Authorized redirect URIs 에 등록) + `D8`(ngrok 운영 burden → Cloudflare 정적 도메인 채택 정당화) — 본 branch D2(ngrok URL 변경 burden)가 그 branch 의 갱신 운영(`D8`)과 결합.
|
|
- [[raw/branch-notes/feature-keycloak-https-termination-caddy-nginx]] `D1`(Cloudflare edge TLS 종단) — 본 branch D1(Cloudflare Tunnel)과 짝: edge 종단이므로 EC2 내부는 HTTP forward. 본 branch D3(EC2 직결)로 가면 그 branch `D2`(Caddy) / `D3`(nginx) + Let's Encrypt 가 TLS 담당.
|
|
- 부모 [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]] D3가 provider 우선순위와 채택 조건의 owner다. 본 sub-sub-branch D1/D2는 선택된 provider의 운영 profile만 제공하는 Reference-Only 문서다.
|
|
|
|
## 검증해야 할 주장
|
|
|
|
> 공식 문서나 사례는 근거지만, 내 프로젝트에서의 동작을 자동으로 보장하지 않는다.
|
|
|
|
| Claim | Why uncertain | How to verify | Status |
|
|
|---|---|---|---|
|
|
| Cloudflare named tunnel에 연결한 managed custom hostname(예: `kc.example.com`)이 Google Cloud Console authorized redirect URI 등록과 실제 callback에 통과 | `GOOGLE-REDIR-C2`는 raw IP 금지만 보증하고, Cloudflare DNS·TLS·tunnel 조합의 종단 동작을 직접 보증하지 않음 | P3B에서 managed custom hostname을 등록하고 실제 broker login을 수행해 exact match와 callback 성공 확인 | `needs-confirmation` |
|
|
| ngrok free plan 에서 재시작 시마다 hostname 이 변경 | `NGROK-C1` 은 random hostname 만 보증, 재시작 시 변경 정책은 본 raw 인용에 직접 없음 | ngrok pricing/free plan 페이지를 `raw/official-docs/` 로 등록 → free plan 의 reserved domain 정책 verbatim 확보 | `planned` |
|
|
| Cloudflare Tunnel `trycloudflare.com` quick tunnel 이 무료 + URL random | 본 branch 의 진행 중 메모만 — `cloudflare-tunnel-routing-official` 인용에 직접 없음 | Cloudflare quick tunnel 공식 페이지 발췌 후 `raw/official-docs/` 등록 | `planned` |
|
|
| Keycloak `KC_HOSTNAME=<tunnel-url>` 설정 시 issuer `iss` 가 정확히 `https://<tunnel-url>/realms/{realm}` 형식으로 발급 | Keycloak hostname 동작은 별도 raw (`keycloak-hostname-configuration`) 필요 | P3B 시연 시 token 발급 후 jwt.io 로 `iss` 디코딩 → backend `issuer-uri` 와 byte-level 비교 | `needs-confirmation` |
|
|
|
|
## 마주친 문제
|
|
|
|
- 아직 없음 (문서 단계).
|
|
|
|
## 관련 sub-branch
|
|
|
|
- [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]] (부모, P3B Single EC2 + Google federation)
|
|
- [[raw/branch-notes/feature-keycloak-reverse-proxy-headers]] — Keycloak reverse proxy 설정 (KC_PROXY_HEADERS + KC_HOSTNAME)
|
|
- [[raw/branch-notes/feature-keycloak-google-redirect-uri-policy]] — Google OAuth client 등록 + ngrok URL 변경 시 갱신
|
|
- [[raw/branch-notes/feature-keycloak-https-termination-caddy-nginx]] — HTTPS termination (Caddy vs nginx + Let's Encrypt)
|
|
|
|
## 묶음
|
|
|
|
<!-- GENERATED: sources:start -->
|
|
- [[raw/official-docs/google-oauth2-redirect-uri-validation-official]]
|
|
- [[raw/official-docs/ngrok-http-tunnel-official]]
|
|
<!-- GENERATED: sources:end -->
|
|
|
|
> 본 branch 는 leaf — 자식 자료 없음. errors / interview prep / lectures 가 누적되면 본 섹션에서 그룹화.
|
|
|
|
### 오류 기록
|
|
|
|
- (없음)
|
|
|
|
### 면접 준비
|
|
|
|
- (없음)
|
|
|
|
## 관련 일일 노트
|
|
|
|
|
|
## 완료 후 정리
|
|
|
|
> 본 sub-sub-branch는 **문서까지만**. 실 tunnel 구동 / 도메인 매핑 / Google Console 등록 흐름은 P3A 완료 후 선택적 확장.
|
|
|
|
- PR 링크:
|
|
- 리뷰 메모:
|
|
- 머지 결과 / 배포 환경: 해당 없음 (문서 단계, P3B 전체 `documented-only`)
|
|
- **wiki 추출 대상** (verified만, `wiki/projects/`로만 추출):
|
|
- `actually-implemented` 항목: 없음
|
|
- `locally-verified` 항목: 없음
|
|
- `prod-verified` 항목: 없음
|
|
- **추출하지 않을 항목** (planned / documented-only / abandoned):
|
|
- 본 sub-sub-branch 전체가 `documented-only`. 추후 부모 P3B의 6 패턴 비교 매트릭스 내 "public 도메인 확보 비교표"로만 인용.
|