Keycloak TLS
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
本文缩写(英文全称与中文含义)
| 缩写 | 英文全称/名称 | 中文含义 |
|---|---|---|
| ACME | Automatic Certificate Management Environment | 自动化证书管理协议 |
| AD | Active Directory | 微软活动目录 |
| CA | Certificate Authority | 证书颁发机构 |
| DB | Database | 数据库 |
| HTTP | Hypertext Transfer Protocol | 超文本传输协议 |
| HTTPS | Hypertext Transfer Protocol Secure | 使用 TLS 加密的 HTTP |
| IdP | Identity Provider | 身份提供方 |
| JDBC | Java Database Connectivity | Java 数据库连接接口 |
| LDAP | Lightweight Directory Access Protocol | 轻量级目录访问协议 |
| LDAPS | LDAP over TLS | 通过 TLS 保护的 LDAP |
| OIDC | OpenID Connect | 基于 OAuth 2.0 的身份认证协议 |
| SAN | Subject Alternative Name | 证书主题备用名称,用于声明域名或 IP |
| SMTP | Simple Mail Transfer Protocol | 简单邮件传输协议 |
| TLS | Transport Layer Security | 传输层安全协议 |
| URL | Uniform Resource Locator | 统一资源定位符,通常指访问地址 |
Links#
https://www.keycloak.org/server/enabletls
https://www.keycloak.org/server/hostname
https://www.keycloak.org/server/reverseproxy
https://www.keycloak.org/server/db
https://www.keycloak.org/server/all-config1. Important Points#
Keycloak 企业部署里 TLS 不只是浏览器访问 HTTPS。至少有 4 条链路要明确:
browser / app -> Keycloak:
public HTTPS endpoint
reverse proxy / ingress -> Keycloak:
edge termination or re-encrypt
Keycloak -> PostgreSQL:
JDBC TLS and CA verification
Keycloak -> LDAP / AD / upstream IdP / SMTP:
LDAPS / HTTPS / SMTP TLSproduction principles:
use trusted CA certificates
keep hostname stable
verify certificates and hostnames
monitor certificate expiry
rotate certs before expiry
do not use insecure TLS flags in production2. Server Configuration#
TLS terminated at Keycloak#
hostname=sso.example.com
http-enabled=false
https-certificate-file=/etc/keycloak/tls/tls.crt
https-certificate-key-file=/etc/keycloak/tls/tls.key
health-enabled=true
metrics-enabled=trueFile layout:
/etc/keycloak/tls/
tls.crt
tls.key
ca.crt
permissions:
tls.key readable only by keycloak user
certificate files managed by cert-manager / ACME / secret managerTLS terminated at reverse proxy#
hostname=sso.example.com
http-enabled=true
proxy-headers=xforwardedreverse proxy checklist:
edge:
TLS certificate belongs to sso.example.com
redirect HTTP to HTTPS
set X-Forwarded-For
set X-Forwarded-Proto=https
set X-Forwarded-Host=sso.example.com
Keycloak:
trusts forwarded headers only from controlled proxy
hostname matches external URL
admin console tested behind proxyDo not expose the internal HTTP port directly to users when TLS is terminated at the proxy.
3. Client Configuration / Verify#
OIDC discovery:
curl -fsS https://sso.example.com/realms/prod/.well-known/openid-configurationCertificate verify:
openssl s_client -connect sso.example.com:443 -servername sso.example.com </dev/nullExpected:
Verify return code: 0 (ok)
issuer is expected company/public CA
subject/SAN contains sso.example.com
certificate expires later than rotation windowDatabase TLS:
db=postgres
db-url=jdbc:postgresql://postgres.example.com:5432/keycloak?sslmode=verify-full&sslrootcert=/etc/keycloak/db-ca/ca.crt
db-username=keycloak
db-password=${KC_DB_PASSWORD}LDAP TLS:
LDAP URL:
ldaps://ad.example.com:636
trust:
AD server certificate chains to trusted CA
hostname matches certificate SAN
bind account has least privilege4. Java#
Spring Security OIDC resource server example:
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://sso.example.com/realms/prodCustom CA:
keytool -importcert -alias company-root-ca -file company-root-ca.crt -keystore truststore.p12 -storetype PKCS12
java -Djavax.net.ssl.trustStore=truststore.p12 -Djavax.net.ssl.trustStorePassword=changeit -jar order-api.jarDo not disable hostname verification in production.
5. Python#
Python requests with CA bundle:
import requests
issuer = "https://sso.example.com/realms/prod"
resp = requests.get(
f"{issuer}/.well-known/openid-configuration",
timeout=5,
verify="/etc/ssl/company-ca.pem",
)
resp.raise_for_status()
print(resp.json()["issuer"])Runtime:
export SSL_CERT_FILE=/etc/ssl/company-ca.pem
export REQUESTS_CA_BUNDLE=/etc/ssl/company-ca.pemNever use verify=False in production.
6. Go#
Go custom CA:
package main
import (
"crypto/tls"
"crypto/x509"
"net/http"
"os"
)
func clientWithCA(caPath string) (*http.Client, error) {
pem, err := os.ReadFile(caPath)
if err != nil {
return nil, err
}
roots := x509.NewCertPool()
roots.AppendCertsFromPEM(pem)
return &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
MinVersion: tls.VersionTLS12,
RootCAs: roots,
},
},
}, nil
}Do not set InsecureSkipVerify: true in production.
7. Node.js#
Node.js with custom CA:
export NODE_EXTRA_CA_CERTS=/etc/ssl/company-ca.pem
node server.jsFetch OIDC discovery:
const issuer = "https://sso.example.com/realms/prod";
const resp = await fetch(`${issuer}/.well-known/openid-configuration`);
if (!resp.ok) {
throw new Error(`OIDC discovery failed: ${resp.status}`);
}
const discovery = await resp.json();
console.log(discovery.issuer);Never use NODE_TLS_REJECT_UNAUTHORIZED=0 or rejectUnauthorized: false in production.
8. Rotation Checklist#
before rotation:
check all clients trust the new CA/intermediate
update Keycloak TLS secret or certificate files
update DB / LDAP CA bundles if needed
confirm certificate SAN includes hostname
during rotation:
apply secret/certificate
restart or reload component if needed
verify OIDC discovery
verify browser login
verify app token validation
after rotation:
monitor login failures and TLS errors
remove old cert after overlap window
update expiry dashboard