Keycloak 26.7.4[1] 를 RHEL 9 계열 서버 한 대에 PostgreSQL 과 함께 올리고 HTTPS 로 여는 절차다. 리버스 프록시 없이 Keycloak 이 직접 8443 을 받는 구성이다. 프록시 뒤에 두려면 proxy-headers 옵션을 추가로 준다[2].
java-21-openjdk-headless 를 쓴다[3].auth.example.com 이다.dnf install -y java-21-openjdk-headless
java -version
sudo -u postgres psql <<'SQL'
CREATE USER keycloak WITH PASSWORD '${KEYCLOAK_DB_PASSWORD}';
CREATE DATABASE keycloak OWNER keycloak ENCODING 'UTF8';
SQL
pg_hba.conf 에서 keycloak 사용자가 접속할 수 있게 하고 PostgreSQL 을 다시 읽는다.
useradd --system --home-dir /opt/keycloak --shell /sbin/nologin keycloak
mkdir -p /opt/keycloak /var/log/keycloak
cd /tmp
curl -LO https://github.com/keycloak/keycloak/releases/download/26.7.4/keycloak-26.7.4.tar.gz
tar xzf keycloak-26.7.4.tar.gz -C /opt/keycloak --strip-components=1
mkdir -p /opt/keycloak/conf/certs
cp /etc/pki/tls/certs/auth.example.com.crt /opt/keycloak/conf/certs/server.crt
cp /etc/pki/tls/private/auth.example.com.key /opt/keycloak/conf/certs/server.key
chown -R keycloak:keycloak /opt/keycloak /var/log/keycloak
chmod 600 /opt/keycloak/conf/certs/server.key
/opt/keycloak/conf/keycloak.conf 를 다음처럼 쓴다. 옵션 이름은 공식 설정 참조와 같다[4].
# Database
db=postgres
db-url=jdbc:postgresql://localhost:5432/keycloak
db-username=keycloak
db-password=${KEYCLOAK_DB_PASSWORD}
# Hostname
hostname=https://auth.example.com
hostname-strict=true
# HTTPS
https-certificate-file=${kc.home.dir}/conf/certs/server.crt
https-certificate-key-file=${kc.home.dir}/conf/certs/server.key
https-port=8443
http-enabled=false
# Observability (관리 인터페이스 9000 포트)
health-enabled=true
metrics-enabled=true
# Logging
log=console,file
log-file=/var/log/keycloak/keycloak.log
log-level=info
db-password 는 파일에 평문으로 두지 말고 환경변수 KC_DB_PASSWORD 로 넘기는 편이 낫다. systemd 의 EnvironmentFile 을 쓴다.hostname 에 URL 을 통째로 적으면 스킴 · 포트까지 고정된다[5]. 관리 콘솔을 다른 주소로 내려면 hostname-admin 을 추가한다.proxy-headers=xforwarded 를 추가하고 프록시가 X-Forwarded-* 를 붙이게 한다[2:1].DB 종류처럼 빌드 시점에 굳는 옵션을 반영한다. 설정을 바꿀 때마다 다시 돌린다.
sudo -u keycloak /opt/keycloak/bin/kc.sh build
sudo -u keycloak /opt/keycloak/bin/kc.sh show-config
Keycloak 은 기본 관리자가 없다. 최초 기동 때 환경변수로 임시 관리자를 만든다[6]. 이 계정은 정식 관리자를 만든 뒤 지운다.
cat > /etc/keycloak.env <<'ENV'
KC_BOOTSTRAP_ADMIN_USERNAME=tmpadmin
KC_BOOTSTRAP_ADMIN_PASSWORD=${BOOTSTRAP_ADMIN_PASSWORD}
KC_DB_PASSWORD=${KEYCLOAK_DB_PASSWORD}
ENV
chmod 600 /etc/keycloak.env
이미 기동한 뒤에 관리자를 잃어버렸으면 서버를 띄운 채로 다음을 쓴다.
sudo -u keycloak KC_BOOTSTRAP_ADMIN_PASSWORD=... /opt/keycloak/bin/kc.sh bootstrap-admin user --username tmpadm --password:env KC_BOOTSTRAP_ADMIN_PASSWORD
cat > /etc/systemd/system/keycloak.service <<'UNIT'
[Unit]
Description=Keycloak Authentication Server
After=network-online.target postgresql.service
Wants=network-online.target
[Service]
Type=simple
User=keycloak
Group=keycloak
EnvironmentFile=/etc/keycloak.env
Environment="JAVA_OPTS_APPEND=-Xms1g -Xmx2g"
ExecStart=/opt/keycloak/bin/kc.sh start --optimized
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
UNIT
systemctl daemon-reload
systemctl enable --now keycloak
journalctl -u keycloak -f
기동 로그 끝에 다음 줄이 나오면 정상이다.
Keycloak 26.7.4 on JVM (powered by Quarkus ...) started in ...s. Listening on: https://0.0.0.0:8443. Management interface listening on https://0.0.0.0:9000.
임시 관리자가 만들어졌으면 /etc/keycloak.env 에서 KC_BOOTSTRAP_ADMIN_* 두 줄을 지운다.
firewall-cmd --permanent --add-port=8443/tcp
# 9000 은 모니터링 서버에서만 접근하게 제한한다
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=192.168.0.0/24 port port=9000 protocol=tcp accept'
firewall-cmd --reload
curl -sk https://auth.example.com:9000/health/ready
# {"status": "UP", ...}
curl -s https://auth.example.com:8443/realms/master/.well-known/openid-configuration | jq -r .issuer
# https://auth.example.com:8443/realms/master
브라우저에서 https://auth.example.com:8443/admin/ 에 임시 관리자로 로그인한 뒤 다음을 한다.
master realm 에 정식 관리자 계정을 만들고 admin 역할을 준다.tmpadmin 을 삭제한다.master 에 애플리케이션 클라이언트를 만들지 않는다.realm 의 User Federation 에서 LDAP 제공자를 추가한다. OpenLDAP 을 쓸 때 값은 다음과 같다.
| 항목 | 값 |
|---|---|
| Vendor | Other |
| Connection URL | ldaps://ldap.example.com:636 |
| Bind DN | cn=root,dc=example,dc=com |
| Users DN | ou=users,dc=example,dc=com |
| Username LDAP attribute | uid |
| UUID LDAP attribute | entryUUID |
| User object classes | inetOrgPerson, organizationalPerson |
Test connection · Test authentication 이 모두 성공한 뒤 저장하고 Synchronize all users 를 누른다.
최신 버전 26.7.4 — 2026-09-20 확인. https://www.keycloak.org/downloads · https://github.com/keycloak/keycloak/releases/download/26.7.4/keycloak-26.7.4.tar.gz ↩︎
Using a reverse proxy. 2026-09-20 확인. https://www.keycloak.org/server/reverseproxy ↩︎ ↩︎
Keycloak Getting Started — OpenJDK 요구사항. 2026-09-20 확인. https://www.keycloak.org/getting-started/getting-started-zip ↩︎
All configuration. 2026-09-20 확인. https://www.keycloak.org/server/all-config · Configuring the database https://www.keycloak.org/server/db · Configuring TLS https://www.keycloak.org/server/enabletls ↩︎
Configuring the hostname. 2026-09-20 확인. https://www.keycloak.org/server/hostname ↩︎
Bootstrapping and recovering an admin account. 2026-09-20 확인. https://www.keycloak.org/server/bootstrap-admin-recovery ↩︎