133 lines
10 KiB
Markdown
133 lines
10 KiB
Markdown
---
|
|
title: Keycloak — Configuring the hostname (v2 hostname guide, iss claim validation)
|
|
source_type: official-doc
|
|
url: https://www.keycloak.org/server/hostname
|
|
archive_url:
|
|
status: raw
|
|
confidence: high
|
|
tags: [hostname, hostname-strict, iss-claim, jwt-validation, kc-hostname, keycloak, keycloak-patterns, oidc-discovery, p3a-single-ec2, p3b-single-ec2-google, public-uri, security]
|
|
related_projects: [keycloak-patterns]
|
|
related_branches: [feature-keycloak-patterns, feature-keycloak-single-ec2-google-federation, feature-keycloak-single-ec2-no-google, feature-keycloak-iss-claim-hostname-mismatch, feature-keycloak-https-termination-caddy-nginx, feature-keycloak-reverse-proxy-headers]
|
|
created: 2026-05-25
|
|
last_reviewed: 2026-05-27
|
|
---
|
|
|
|
# Keycloak — Configuring the hostname
|
|
|
|
> Layer: `raw/official-docs/` — Keycloak Server Guides "Hostname v2" 페이지 발췌.
|
|
> `iss` claim 생성 / fraudulent issuer 방어 / frontchannel-backchannel URL 분리의 1차 근거.
|
|
|
|
## Parent / 활용 branch (필수)
|
|
|
|
| Branch | 이 자료가 정당화하는 결정 |
|
|
|---|---|
|
|
| [[raw/branch-notes/feature-keycloak-patterns]] | keycloak-patterns root — hostname-strict 활성 + 명시적 hostname 설정의 모든 P 변형 baseline |
|
|
| [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]] | P3B 단일 EC2 + Google federation 에서 public DNS → `KC_HOSTNAME` 명시 결정 |
|
|
| [[raw/branch-notes/feature-keycloak-single-ec2-no-google]] | P3A 단일 EC2 (Google 없음) 에서 `KC_HOSTNAME=localhost` 단순화 결정 |
|
|
| [[raw/branch-notes/feature-keycloak-iss-claim-hostname-mismatch]] | `iss` mismatch 디버깅 시 hostname 옵션과의 인과 관계 정리 (frontchannel vs backchannel URL) |
|
|
| [[raw/branch-notes/feature-keycloak-https-termination-caddy-nginx]] | reverse proxy 가 Host header 를 overwrite 하는 경우 `hostname-strict` 유지 결정 근거 |
|
|
| [[raw/branch-notes/feature-keycloak-reverse-proxy-headers]] | hostname + proxy-headers 조합으로 발급 URL 결정 메커니즘 |
|
|
|
|
## 컨텍스트
|
|
|
|
P3A/P3B 의 핵심 함정: container service name (`keycloak`) 과 external hostname (`localhost` 또는 public DNS) 의 mismatch 가 token `iss` claim 검증 실패로 직결. `KC_HOSTNAME` 명시가 의무이며, 이는 fraudulent issuer 방어를 위한 공식 보안 조치.
|
|
|
|
## 출처 / Source
|
|
|
|
- 원본 URL: https://www.keycloak.org/server/hostname
|
|
- 아카이브 URL: (미수집)
|
|
- 저자 / 조직: Keycloak (Red Hat) — Server Guides
|
|
- 발행일: rolling docs (현재 26.x, v2 hostname guide 적용 중)
|
|
- 마지막 확인일: 2026-05-27
|
|
|
|
## 핵심 인용 / Key quotes (verbatim)
|
|
|
|
> [§Backchannel] "Keycloak has the capability to offer a separate URL for backchannel requests, enabling internal communication while maintaining the use of a public URL for frontchannel requests."
|
|
|
|
> [§Default behavior] "By default, Keycloak mandates the configuration of the `hostname` option and does not dynamically resolve URLs. This is a security measure."
|
|
|
|
> [§Security rationale] "By explicitly setting the `hostname` option, we avoid a situation where tokens could be issued by a fraudulent issuer."
|
|
|
|
> [§hostname-backchannel-dynamic] "If set to true, `hostname` option needs to be specified as a full URL."
|
|
|
|
> [§hostname-strict] "Should always be set to true in production, unless your reverse proxy overwrites the Host header."
|
|
|
|
> [§Relevant options table] `hostname-strict` default: `true`
|
|
|
|
## Claims Extracted / 추출된 주장
|
|
|
|
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
|
|---|---|---|---|---|---|
|
|
| KC-HOST-C1 | Keycloak 은 backchannel 요청에 별도 URL 을 제공할 수 있으며, frontchannel public URL 과 internal communication URL 을 분리 가능 | [§Backchannel] "Keycloak has the capability to offer a separate URL for backchannel requests, enabling internal communication while maintaining the use of a public URL for frontchannel requests." | `official-vendor-doc` | container 내부 vs 외부 access 가 다른 토폴로지 (예: docker-compose, k8s) | backchannel URL 의 정확한 설정 옵션 이름 (`KC_HOSTNAME_BACKCHANNEL_DYNAMIC` 등) 의 자세한 동작은 다른 section |
|
|
| KC-HOST-C2 | Keycloak 의 기본 동작은 `hostname` 옵션 설정을 **의무화** 하며 dynamic URL resolution 을 차단 (보안 조치) | [§Default behavior] "By default, Keycloak mandates the configuration of the `hostname` option and does not dynamically resolve URLs. This is a security measure." | `official-vendor-doc` | Keycloak 모든 deployment | hostname 미설정 시의 정확한 startup 동작 (실패 vs 기본값 추론) 은 본 인용에 없음 |
|
|
| KC-HOST-C3 | `hostname` 옵션 명시는 **fraudulent issuer 가 token 을 발급하는 상황을 방지** 하는 보안 목적 | [§Security rationale] "By explicitly setting the `hostname` option, we avoid a situation where tokens could be issued by a fraudulent issuer." | `official-vendor-doc` | hostname-strict 정책의 rationale | spoofed `Host` header 로 인한 token issuer 위조 시나리오의 구체적 공격 모델은 본 인용 범위 밖 |
|
|
| KC-HOST-C4 | `hostname-backchannel-dynamic=true` 설정 시 `hostname` 옵션은 hostname-only 가 아닌 **full URL** 로 지정해야 함 | [§hostname-backchannel-dynamic] "If set to true, `hostname` option needs to be specified as a full URL." | `official-vendor-doc` | frontchannel-backchannel 분리 시나리오 (Keycloak 24+) | full URL 의 정확한 schema/port 처리 (`https://` 의무 여부 등) 는 본 인용 범위 밖 |
|
|
| KC-HOST-C5 | `hostname-strict` 의 기본값은 `true`. production 에서는 항상 `true` 권장, 단 reverse proxy 가 Host header 를 overwrite 하는 경우만 예외 | [§hostname-strict] "Should always be set to true in production, unless your reverse proxy overwrites the Host header." + [§Relevant options table] `hostname-strict` default: `true` | `official-vendor-doc` | production hardening + reverse proxy 시나리오 | Host header overwrite 의 정확한 동작 (proxy 가 무엇으로 overwrite 하는지) 은 reverse proxy 페이지에서 보강 — `keycloak-reverseproxy-official.md` |
|
|
|
|
## Usage Boundaries / 적용 경계
|
|
|
|
- **이 자료가 직접 증명하는 것**:
|
|
- `KC-HOST-C1` ~ `C5`: hostname 옵션의 보안 rationale, frontchannel/backchannel 분리, hostname-strict 기본값, full URL 요구 조건
|
|
- **이 자료가 증명하지 않는 것**:
|
|
- `iss` claim 생성 시 `KC_HOSTNAME` + realm path 결합 규칙의 정확한 string concatenation (본 페이지에선 명시 없음 — Resource Server 측 검증 동작과 결합)
|
|
- admin console URL 분리 옵션 (`KC_HOSTNAME_ADMIN`) 의 정확한 동작
|
|
- hostname-strict 가 `false` 일 때의 정확한 fallback 동작 (어떤 header / source 를 신뢰)
|
|
- `KC_HOSTNAME=localhost` 와 backend `issuer-uri=http://keycloak:8080/...` mismatch 의 P3A 시나리오 — 본 페이지의 일반 원칙으로 추론 가능하나 직접 case study 는 없음
|
|
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
|
|
- P3A docker-compose 에서 `network_mode: host` vs `extra_hosts` 어느 쪽이 더 학습 환경에 적합한지
|
|
- hostname-backchannel-dynamic 활성 시 OIDC discovery (`.well-known/openid-configuration`) 의 `issuer` 값이 frontchannel vs backchannel 중 어느 쪽으로 표시되는지
|
|
- reverse proxy + hostname-strict=true + proxy-headers=xforwarded 조합에서 token `iss` 의 최종 결정 우선순위
|
|
|
|
## 핵심 옵션 (페이지 기준 요약)
|
|
|
|
| 옵션 | 의미 |
|
|
|------|------|
|
|
| `KC_HOSTNAME` (`--hostname`) | 서버가 노출되는 frontchannel 주소. hostname only 또는 full URL. |
|
|
| `KC_HOSTNAME_STRICT` (`--hostname-strict`) | 동적 hostname 해석 차단. 기본 `true`. production 의무 (단, reverse proxy 가 Host header 를 overwrite 하는 경우 예외) |
|
|
| `KC_HOSTNAME_BACKCHANNEL_DYNAMIC` | frontchannel/backchannel URL 분리. true 설정 시 `KC_HOSTNAME` 은 full URL 필수 |
|
|
| `KC_HOSTNAME_ADMIN` | 관리 콘솔용 별도 hostname (옵션) |
|
|
|
|
## `iss` claim 과의 관계 (내 프로젝트 해석)
|
|
|
|
> 본 섹션은 자료 직접 인용 아님 — 페이지의 일반 원칙 + Resource Server 측 검증 동작의 결합. wiki 추출 시 별도 처리.
|
|
|
|
- Keycloak 이 발급한 access/ID token 의 `iss` claim 은 `KC_HOSTNAME` (+ realm path) 기반으로 생성.
|
|
- 예: `KC_HOSTNAME=localhost`, realm `keycloak-patterns` → `iss = http://localhost:8080/realms/keycloak-patterns`.
|
|
- Resource Server (backend) 는 token 의 `iss` 를 본인이 설정한 `issuer-uri` 와 정확 비교 → 다르면 **검증 실패**.
|
|
|
|
## P3A 함정 시나리오 (내 프로젝트 해석)
|
|
|
|
> 본 섹션은 자료 직접 인용 아님 — 일반 원칙의 시나리오 적용. wiki 추출 시 별도 처리.
|
|
|
|
1. docker-compose 에서 keycloak service name `keycloak` 로 두고 backend 가 `issuer-uri=http://keycloak:8080/realms/...` 등록.
|
|
2. browser 는 `http://localhost:8080` 에서 로그인 → token `iss = http://localhost:8080/realms/...` (KC_HOSTNAME=localhost 인 경우).
|
|
3. backend 는 `http://keycloak:8080/realms/...` 를 기대 → **issuer mismatch → 401**.
|
|
|
|
### 해결책 (3종)
|
|
|
|
- **A.** `KC_HOSTNAME=localhost` 로 통일 + backend 도 `localhost:8080` 사용 + 컨테이너에서 `network_mode: host` 또는 `extra_hosts: [host.docker.internal:host-gateway]`.
|
|
- **B.** `KC_HOSTNAME_BACKCHANNEL_DYNAMIC=true` 로 frontchannel/backchannel 분리 (Keycloak 24+ — `KC-HOST-C4`).
|
|
- **C.** Compose service name 과 외부 hostname 을 동일하게 (Docker DNS alias + `/etc/hosts` 추가).
|
|
|
|
## P3A/P3B 적용 메모
|
|
|
|
- 학습 환경에서는 `KC_HOSTNAME=localhost` + `KC_HTTP_ENABLED=true` 로 단순화.
|
|
- prod 시 hostname-strict 유지 (`KC-HOST-C5`) + HTTPS termination + 정확한 public DNS.
|
|
|
|
## 한계 / 후속
|
|
|
|
- 본 문서는 hostname 단일 주제만. realm/client 설정은 별도.
|
|
- 본 wiki 변환 시 `wiki/concepts/keycloak-iss-claim-and-hostname` 후보.
|
|
|
|
## Related / 관련
|
|
|
|
- 같은 주제 다른 official-doc:
|
|
- [[raw/official-docs/keycloak-reverseproxy-official]]
|
|
- [[raw/official-docs/keycloak-server-containers-docker]]
|
|
- [[raw/official-docs/spring-security-resource-server-jwt]]
|
|
- 인용하는 branch:
|
|
- [[raw/branch-notes/feature-keycloak-single-ec2-no-google]]
|
|
- [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]]
|
|
- [[raw/branch-notes/feature-keycloak-iss-claim-hostname-mismatch]]
|
|
- 인용하는 wiki: (미작성)
|