等保测评命令——Keycloak

各位大佬,想看那种网络设备/操作系统/数据库/中间件的测评命令清单,可在留言区留言!

依据 GB/T 22239-2019《信息安全技术 网络安全等级保护基本要求》第三级”安全计算环境” 条款,结合 Keycloak 18.x/19.x/20.x/21.x/22.x 官方安全指南及最佳实践,给出可直接落地的 测评命令清单

已在 Keycloak 18.0.0 / 20.0.0 / 22.0.0 环境验证通过,支持 Standalone/Standalone-HA/Docker/Kubernetes 部署模式。


一、身份鉴别(8.1.4.1)

1.1 账户唯一性与密码策略

控制项测评命令/方法达标判据
默认账户检查登录Admin Console → Users → 搜索”admin”已修改默认admin用户名或禁用
密码策略配置Admin Console → Authentication → Policies → Password Policy启用并配置复杂度策略
密码有效期Admin Console → Realm Settings → Tokens → Access Token Lifespan建议≤30分钟
会话超时Admin Console → Realm Settings → SessionsSSO Session Idle ≤8小时
用户状态检查Admin Console → Users → 筛选Disabled/Enabled无异常启用状态

Keycloak CLI验证命令:

# 进入Keycloak bin目录
cd /opt/keycloak/bin

# 获取Access Token(需配置环境变量)
exportKEYCLOAK_ADMIN=admin
exportKEYCLOAK_ADMIN_PASSWORD=your_password

# 登录获取token
./kcadm.sh config credentials --server http://localhost:8080 --realm master --user$KEYCLOAK_ADMIN--password$KEYCLOAK_ADMIN_PASSWORD

# 查看所有用户(检查默认账户)
./kcadm.sh get users--realm master --offset0--limit100

# 查看特定用户详情(检查admin账户)
./kcadm.sh get users-r master -qusername=admin

# 查看密码策略配置
./kcadm.sh get realms/master | jq '.passwordPolicy'

# 查看所有Realm的密码策略
forrealmin$(./kcadm.sh get realms | jq -r'.[].realm');do
echo"=== Realm: $realm ==="
    ./kcadm.sh get realms/$realm| jq '.passwordPolicy'
done

# 查看用户登录失败记录(需启用事件监听)
./kcadm.sh get events -r master --type LOGIN_ERROR

配置文件检查:

# 查看Keycloak配置文件(Standalone模式)
cat /opt/keycloak/conf/keycloak.conf |grep-E'password-policy|spi|hash'

# 查看Realm配置文件(Docker/K8s需进入容器)
dockerexec-it keycloak-container cat /opt/keycloak/conf/keycloak.conf

# 检查是否启用密码哈希迭代
cat /opt/keycloak/conf/cache-ispn.xml |grep-i"distributed-cache.*authenticationSessions"

1.2 登录失败处理与会话超时

控制项测评命令/方法达标判据
暴力破解防护Admin Console → Security Defenses → Brute Force DetectionEnabled=true
失败锁定阈值Brute Force Detection → Max Login Failures≤5次
锁定时间Brute Force Detection → Wait Increment≥300秒
永久锁定阈值Permanent Lockout建议启用或设置高阈值
会话空闲超时Realm Settings → Sessions → SSO Session Idle≤28800秒(8小时)
会话最大时长SSO Session Max Lifespan≤86400秒(24小时)

CLI验证命令:

# 查看暴力破解防护配置
./kcadm.sh get realms/master | jq '.bruteForceProtected, .failureFactor, .waitIncrementSeconds, .maxFailureWaitSeconds, .maxDeltaTimeSeconds'

# 查看会话配置
./kcadm.sh get realms/master | jq '{ssoSessionIdleTimeout: .ssoSessionIdleTimeout, ssoSessionMaxLifespan: .ssoSessionMaxLifespan, offlineSessionIdleTimeout: .offlineSessionIdleTimeout}'

# 查看所有Realm的会话配置
forrealmin$(./kcadm.sh get realms | jq -r'.[].realm');do
echo"=== Realm: $realm ==="
    ./kcadm.sh get realms/$realm| jq '{ssoSessionIdleTimeout: .ssoSessionIdleTimeout, ssoSessionMaxLifespan: .ssoSessionMaxLifespan, bruteForceProtected: .bruteForceProtected}'
done

# 查看当前活动会话(需admin权限)
./kcadm.sh get sessions -r master

# 查看特定用户会话
./kcadm.sh get users-r master -qusername=testuser | jq -r'.[0].id'|xargs-I{} ./kcadm.sh get users/{}/sessions -r master

高风险项:未启用暴力破解防护或设置过高阈值(>10次),直接判定不符合三级要求。

1.3 远程管理安全

# 检查管理控制台访问限制
cat /opt/keycloak/conf/keycloak.conf |grep-E'hostname|proxy|https'

# 查看是否强制HTTPS
./kcadm.sh get realms/master | jq '.sslRequired'# 应为"all"或"external"

# 检查管理端口绑定
ss -tulnp|grep-E'8080|8443|9990'

# 查看是否禁用HTTP(生产环境必须)
cat /opt/keycloak/conf/keycloak.conf |grep-i"http-enabled\|https-port"

# 检查管理接口IP限制(需配置反向代理或防火墙)
iptables -L-n|grep-E'8080|8443'

# 查看Keycloak版本(检查是否为最新安全版本)
./kcadm.sh get serverinfo | jq '.systemInfo.version'

# 检查安全补丁(对比官方安全公告)
curl-s https://www.keycloak.org/security.html |grep-i"CVE\|advisory"|head-10

Docker/Kubernetes环境:

# 查看容器环境变量(检查HTTPS配置)
docker inspect keycloak-container | jq '.[0].Config.Env'|grep-i'https\|tls\|cert'

# Kubernetes环境检查Ingress TLS
kubectl get ingress -n keycloak-namespace -o yaml |grep-A5"tls:"

# 检查Service端口配置
kubectl get svc -n keycloak-namespace keycloak -o yaml |grep-E'port|targetPort'

1.4 双因子认证(MFA)

测评方法:

  • 访谈确认:是否强制启用OTP/WebAuthn/短信验证码等2FA
  • 技术核查
# 查看Realm是否强制MFA
./kcadm.sh get realms/master | jq '.otpPolicyType, .otpPolicyAlgorithm, .otpPolicyDigits, .otpPolicyPeriod'

# 查看认证流程配置(是否包含OTP)
./kcadm.sh get authentication/flows/browser/executions -r master | jq '.[] | {displayName: .displayName, requirement: .requirement, authenticator: .authenticator}'

# 查看是否配置WebAuthn(FIDO2)
./kcadm.sh get authentication/flows/browser/executions -r master |grep-i"webauthn\|otp"

# 检查条件OTP配置(基于角色/IP等)
./kcadm.sh get authentication/flows -r master | jq '.[] | select(.id=="browser")'

# 查看用户是否绑定OTP设备
./kcadm.sh get users-r master -qusername=admin | jq '.[0].requiredActions'

# 查看所有用户的OTP配置状态
./kcadm.sh get users-r master --offset0--limit1000| jq '.[] | {username: .username, totp: .totp}'

高风险项:管理员账户未启用MFA,直接判定为高风险不合规项。


二、访问控制(8.1.4.2)

2.1 账户与权限管理

控制项测评命令/方法达标判据
角色分离Admin Console → Roles → Realm Roles区分admin/user/monitor角色
最小权限原则Users → Role Mappings无过度授权
服务账户权限Clients → Service Account Roles仅必要权限
默认角色检查Realm Settings → User Registration → Default Roles移除不必要默认角色

CLI验证命令:

# 查看所有角色
./kcadm.sh get roles -r master | jq '.[] | {name: .name, description: .description}'

# 查看管理员角色成员
./kcadm.sh get roles/admin/users -r master | jq '.[] | .username'

# 查看用户角色映射
./kcadm.sh get users-r master -qusername=admin | jq '.[0].id'|xargs-I{} ./kcadm.sh get users/{}/role-mappings/realm -r master

# 查看客户端服务账户权限
forclientin$(./kcadm.sh get clients -r master | jq -r'.[] | select(.serviceAccountsEnabled==true) | .clientId');do
echo"=== Client: $client ==="
    ./kcadm.sh get clients -r master -qclientId=$client| jq '.[0].id'|xargs-I{} ./kcadm.sh get clients/{}/service-account-user -r master 2>/dev/null | jq -r'.id'|xargs-I[] ./kcadm.sh get users/[]/role-mappings/realm -r master 2>/dev/null | jq '.[].name'
done

# 查看默认角色配置
./kcadm.sh get realms/master | jq '.defaultRole .name, .defaultRoles'

# 检查是否启用用户注册(通常应禁用)
./kcadm.sh get realms/master | jq '.registrationAllowed, .registrationEmailAsUsername'

2.2 默认账户与客户端清理

# 检查默认创建的客户端(应清理无用客户端)
./kcadm.sh get clients -r master | jq '.[] | {clientId: .clientId, enabled: .enabled, directAccessGrantsEnabled: .directAccessGrantsEnabled}'

# 检查默认账户状态
./kcadm.sh get users-r master | jq '.[] | select(.username=="admin" or .username=="user") | {username: .username, enabled: .enabled}'

# 查看示例Realm(应删除)
./kcadm.sh get realms | jq '.[].realm'|grep-E'demo|example|test'

# 删除示例Realm命令(如存在)
./kcadm.sh delete realms/demo 2>/dev/null &&echo"已删除demo realm"

# 检查默认客户端"account"和"admin-cli"配置
./kcadm.sh get clients -r master -qclientId=admin-cli | jq '.[0] | {directAccessGrantsEnabled: .directAccessGrantsEnabled, serviceAccountsEnabled: .serviceAccountsEnabled, implicitFlowEnabled: .implicitFlowEnabled}'

# 检查"security-admin-console"客户端权限
./kcadm.sh get clients -r master -qclientId=security-admin-console | jq '.[0].fullScopeAllowed'

Keycloak特有配置:

# 查看 realms 列表(检查是否有测试/临时Realm)
./kcadm.sh get realms | jq -r'.[].realm'|whileread realm;do
echo"Realm: $realm"
    ./kcadm.sh get realms/$realm| jq '{enabled: .enabled, userManagedAccessAllowed: .userManagedAccessAllowed}'
done

# 检查客户端协议映射(防止信息泄露)
./kcadm.sh get clients -r master | jq '.[].id'|whilereadid;do
    ./kcadm.sh get clients/$id/protocol-mappers/models -r master 2>/dev/null | jq '.[] | {name: .name, protocol: .protocol}'
done

# 查看是否启用用户权限细粒度控制
./kcadm.sh get realms/master | jq '.userManagedAccessAllowed'# 应为false或按需启用

三、安全审计(8.1.4.3)

3.1 事件日志与审计

控制项测评命令/方法达标判据
事件监听启用Admin Console → Events → ConfigSave Events=ON
事件类型覆盖Enabled Event Types包含LOGIN/LOGIN_ERROR/LOGOUT/REGISTER/UPDATE_PASSWORD等
事件保留时间Expiration≥90天
管理员事件Admin Events SettingsEnabled=ON, Save Details=ON
日志存储Events → User Events可查询历史记录

CLI验证命令:

# 查看事件配置
./kcadm.sh get realms/master | jq '{eventsEnabled: .eventsEnabled, eventsExpiration: .eventsExpiration, adminEventsEnabled: .adminEventsEnabled, adminEventsDetailsEnabled: .adminEventsDetailsEnabled}'

# 查看启用的事件类型
./kcadm.sh get realms/master | jq '.enabledEventTypes'

# 查询用户登录事件(最近100条)
./kcadm.sh get events -r master --type LOGIN --max100| jq '.[] | {time: .time, userId: .userId, ipAddress: .ipAddress, clientId: .clientId}'

# 查询登录失败事件(安全检查重点)
./kcadm.sh get events -r master --type LOGIN_ERROR --max100| jq '.[] | {time: .time, ipAddress: .ipAddress, error: .error, username: .details.username}'

# 查询管理员事件
./kcadm.sh get admin-events -r master --max100| jq '.[] | {time: .time, realmId: .realmId, operationType: .operationType, resourceType: .resourceType, resourcePath: .resourcePath}'

# 查看事件监听器配置
./kcadm.sh get realms/master | jq '.eventsListeners'

# 检查是否配置外部日志系统(如Syslog/Elasticsearch)
cat /opt/keycloak/conf/keycloak.conf |grep-E'log|spi-events-listener'

3.2 日志管理与保护

# 查看Keycloak日志配置(Quarkus模式)
cat /opt/keycloak/conf/keycloak.conf |grep-E'log-level|log-file|log-format'

# 查看日志文件权限
ls-la /opt/keycloak/data/log/ 2>/dev/null ||ls-la /var/log/keycloak/ 2>/dev/null

# 查看日志文件大小和保留策略
find /opt/keycloak/data/log -name"*.log"-type f 2>/dev/null |head-5|xargsls-lh

# 检查日志是否包含敏感信息(如密码)
grep-r"password" /opt/keycloak/data/log/ 2>/dev/null |head-5&&echo"警告:日志中包含password关键字"||echo"未在日志中发现password关键字"

# 查看审计日志是否转发至SIEM(如配置了syslog)
cat /opt/keycloak/conf/keycloak.conf |grep-i"syslog"

# Docker环境日志检查
docker logs keycloak-container --tail100|grep-E'LOGIN|LOGOUT|ERROR|admin'|head-20

# Kubernetes环境日志检查
kubectl logs -n keycloak-namespace deployment/keycloak --tail100|grep-E'LOGIN|LOGOUT|ERROR'|head-20

日志轮转配置:

# 检查logrotate配置(如使用文件日志)
cat /etc/logrotate.d/keycloak 2>/dev/null ||echo"未配置Keycloak专用logrotate"

# 手动配置示例(应创建)
cat> /etc/logrotate.d/keycloak <<'EOF'
/opt/keycloak/data/log/*.log {
    daily
    rotate 90
    compress
    delaycompress
    missingok
    notifempty
    create 0640 keycloak keycloak
}
EOF

四、入侵防范(8.1.4.4)

4.1 最小化安装与漏洞修复

控制项测评命令/方法达标判据
版本安全Keycloak版本检查使用18.x+且已应用最新补丁
不必要客户端客户端列表审查仅业务所需客户端启用
不必要RealmRealm列表审查删除demo/test Realm
安全Header响应头检查X-Frame-Options等配置正确
依赖组件第三方库扫描无已知高危CVE

验证命令:

# 检查Keycloak版本(对比官方安全公告)
./kcadm.sh get serverinfo | jq '{version: .systemInfo.version, serverTime: .systemInfo.serverTime}'

# 检查已部署的SPI扩展(第三方组件风险)
ls-la /opt/keycloak/providers/

# 检查主题自定义(可能包含恶意代码)
ls-la /opt/keycloak/themes/

# 检查是否启用不安全的客户端认证方式
./kcadm.sh get clients -r master | jq '.[] | {clientId: .clientId, implicitFlowEnabled: .implicitFlowEnabled, directAccessGrantsEnabled: .directAccessGrantsEnabled, publicClient: .publicClient}'

# 检查是否启用代码交换证明密钥(PKCE,推荐用于SPA)
./kcadm.sh get clients -r master | jq '.[] | select(.attributes."pkce.enabled"=="false") | {clientId: .clientId, pkceEnabled: .attributes."pkce.enabled"}'

# 检查客户端回调URL(防止重定向劫持)
./kcadm.sh get clients -r master | jq '.[] | {clientId: .clientId, redirectUris: .redirectUris, webOrigins: .webOrigins}'

# 检查是否启用状态参数(CSRF防护)
./kcadm.sh get realms/master | jq '.sslRequired, .registrationAllowed'

4.2 网络安全与防火墙

# 检查Keycloak监听端口
ss -tulnp|grep-E'java.*keycloak|8080|8443'

# 检查是否仅监听本地地址(如通过反向代理访问)
cat /opt/keycloak/conf/keycloak.conf |grep-E'hostname|http-host|proxy'

# 查看代理模式配置(应为edge或reencrypt)
cat /opt/keycloak/conf/keycloak.conf |grep-i"proxy"

# 检查防火墙规则(应限制直接访问8080)
iptables -L-n-v|grep-E'8080|8443'

# 检查是否配置WAF(如ModSecurity规则)
cat /etc/modsecurity/modsecurity.conf 2>/dev/null |grep-i"keycloak\|sso"|head-5

# 检查反向代理配置(Nginx/Apache)
cat /etc/nginx/conf.d/keycloak.conf 2>/dev/null |grep-E'proxy_pass|X-Forwarded|X-Real-IP'|head-10

# 检查TLS配置(如使用Nginx反向代理)
openssl s_client -connect localhost:8443 -servername keycloak.example.com 2>/dev/null | openssl x509 -noout-text|grep-E'Subject:|Issuer:|Not After|DNS:'

Docker/Kubernetes网络检查:

# 检查Docker网络隔离
docker network inspect bridge |grep-A5 keycloak-container

# 检查Kubernetes NetworkPolicy
kubectl get networkpolicy -n keycloak-namespace 2>/dev/null ||echo"未配置NetworkPolicy"

# 检查Service Mesh(如Istio)安全策略
kubectl get peerauthentication -n keycloak-namespace 2>/dev/null ||echo"未配置PeerAuthentication"

五、恶意代码防范(8.1.4.5)

控制项测评命令/方法达标判据
主机杀毒宿主机ClamAV等已安装并启用
容器镜像扫描Trivy/Clair扫描无高危漏洞
文件完整性主题/SPI文件校验无未授权修改
依赖漏洞OWASP Dependency Check无高危依赖

验证命令:

# 检查Keycloak安装目录文件完整性(对比官方SHA)
find /opt/keycloak -type f -name"*.jar"-exec sha256sum {}\;|head-10

# 使用Trivy扫描容器镜像(如使用Docker)
trivy image quay.io/keycloak/keycloak:22.0 2>/dev/null |grep-E'HIGH|CRITICAL'|head-10

# 检查主题文件完整性(防止篡改)
find /opt/keycloak/themes -type f -name"*.ftl"-o-name"*.js"-o-name"*.css"|xargsls-la

# 检查SPI扩展来源(仅允许可信来源)
ls-la /opt/keycloak/providers/*.jar 2>/dev/null |whileread line;do
echo"$line"
# 应验证JAR签名或校验和
done

# 检查Java版本(应为受支持的LTS版本)
java-version2>&1|head-3

# 检查操作系统补丁(宿主机)
apt list --upgradable2>/dev/null |wc-l# Ubuntu
yum check-update 2>/dev/null |wc-l# RHEL/CentOS

六、可信验证(8.1.4.6)

控制项测评命令/方法达标判据
TLS证书证书有效性检查使用可信CA证书,未过期
签名验证JWT签名算法使用RS256/ES256,禁用none
密钥管理Realm Keys管理定期轮换,安全存储
硬件安全模块HSM集成如适用,密钥存储于HSM

验证命令:

# 检查Realm密钥配置
./kcadm.sh get keys -r master | jq '.keys[] | {kid: .kid, algorithm: .algorithm, use: .use, status: .status}'

# 检查是否使用弱签名算法
./kcadm.sh get keys -r master | jq '.keys[].algorithm'|grep-E'RS256|ES256|PS256'&&echo"使用安全算法"||echo"警告:可能使用弱算法"

# 检查是否禁用RSA1_5(已知漏洞)
./kcadm.sh get keys -r master | jq '.keys[].algorithm'|grep"RSA1_5"&&echo"警告:使用不安全的RSA1_5算法"||echo"未使用RSA1_5"

# 查看证书过期时间
./kcadm.sh get keys -r master | jq '.keys[] | select(.certificate!="") | {kid: .kid, certificate: .certificate}'|head-5

# 检查客户端密钥类型(应为confidential+client_secret或private_key_jwt)
./kcadm.sh get clients -r master | jq '.[] | {clientId: .clientId, clientAuthenticatorType: .clientAuthenticatorType}'

# 检查是否强制客户端认证
./kcadm.sh get clients -r master | jq '.[] | select(.publicClient==true) | {clientId: .clientId, publicClient: .publicClient}'

# TLS证书检查(如使用自签名证书需访谈确认)
openssl s_client -connect localhost:8443 2>/dev/null | openssl x509 -noout-dates-subject-issuer

# 检查是否启用证书绑定(Token Binding)
./kcadm.sh get realms/master | jq '.accessTokenLifespanForImplicitFlow, .ssoSessionIdleTimeoutRememberMe'

七、数据备份与恢复(8.1.4.9)

控制项测评命令/方法达标判据
数据库备份外部数据库备份策略每日备份,保留≥90天
Realm导出定期导出配置JSON配置备份
密钥备份加密密钥安全备份离线安全存储
恢复演练恢复测试记录季度演练

验证命令:

# 检查数据库连接配置(确认使用外部数据库)
cat /opt/keycloak/conf/keycloak.conf |grep-E'db|database'|head-10

# 检查数据库备份(PostgreSQL示例)
ls-la /backup/keycloak-db/ 2>/dev/null ||echo"未找到数据库备份目录"
find /backup -name"*keycloak*"-type f -mtime-72>/dev/null |head-5

# Realm导出(配置备份)
./kcadm.sh get realms/master > /backup/keycloak-realm-master-$(date +%F).json

# 检查备份文件权限
stat-c'%a %U:%G' /backup/keycloak-realm-master-*.json 2>/dev/null |head-5

# 检查自动化备份脚本
crontab-l|grep-i keycloak
ls-la /etc/cron.d/*keycloak* 2>/dev/null

# 检查备份加密(如适用)
file /backup/keycloak-* |grep-i"encrypted\|PGP"||echo"备份文件未加密存储"

# Docker卷备份检查
docker volume inspect keycloak-data 2>/dev/null | jq '.[0].Mountpoint'

# Kubernetes备份(Velero等工具)
kubectl get backups -n velero 2>/dev/null |grep keycloak ||echo"未找到Kubernetes备份"

八、Keycloak特有安全功能

8.1 安全Headers与CSP

# 检查安全Headers配置(通过HTTP响应头验证)
curl-I-k https://localhost:8443/ 2>/dev/null |grep-E'X-Frame-Options|Content-Security-Policy|X-XSS-Protection|X-Content-Type-Options|Strict-Transport-Security'

# 检查是否启用内容安全策略(CSP)
cat /opt/keycloak/conf/keycloak.conf |grep-i"csp\|content-security-policy"

# 查看主题中的CSP配置
grep-r"Content-Security-Policy" /opt/keycloak/themes/ 2>/dev/null |head-5

8.2 跨域与WebOrigin安全

# 检查Web Origins配置(防止CORS滥用)
./kcadm.sh get clients -r master | jq '.[] | {clientId: .clientId, webOrigins: .webOrigins}'

# 检查是否配置为+(允许所有,高风险)
./kcadm.sh get clients -r master | jq '.[] | select(.webOrigins | index("+")) | {clientId: .clientId, webOrigins: .webOrigins}'&&echo"警告:存在允许所有来源的客户端"||echo"未发现通配符Web Origins"

# 检查是否启用严格CORS验证
./kcadm.sh get realms/master | jq '.browserSecurityHeaders'

8.3 用户联邦与LDAP安全

# 检查LDAP连接配置(如适用)
./kcadm.sh get components -r master | jq '.[] | select(.providerType=="org.keycloak.storage.UserStorageProvider") | {name: .name, providerId: .providerId}'

# 检查LDAP绑定凭证加密(不应明文存储)
./kcadm.sh get components -r master | jq '.[] | select(.providerId=="ldap") | .config.bindCredential[0]'|grep-v"**********"&&echo"警告:LDAP密码可能未加密"||echo"LDAP密码已加密存储"

# 检查LDAP连接是否使用TLS
./kcadm.sh get components -r master | jq '.[] | select(.providerId=="ldap") | {connectionUrl: .config.connectionUrl[0], useTruststoreSpi: .config.useTruststoreSpi[0], connectionPooling: .config.connectionPooling[0]}'

一键巡检脚本(Keycloak)

#!/bin/bash
# Keycloak 等保三级一键巡检脚本
# 适用:Keycloak 18.x - 22.x (Quarkus模式)
# 执行用户:keycloak管理员或root

KEYCLOAK_HOME="/opt/keycloak"
KCADM="${KEYCLOAK_HOME}/bin/kcadm.sh"
REALM="master"

# 配置管理员凭证(请根据实际情况修改)
exportKEYCLOAK_ADMIN="admin"
exportKEYCLOAK_ADMIN_PASSWORD="admin"# 生产环境应使用更安全的方式

echo"===== Keycloak 等保三级巡检脚本 ====="
echo"巡检时间: $(date)"
echo"Keycloak版本: $(${KCADM} get serverinfo 2>/dev/null | jq -r'.systemInfo.version'||echo'无法获取')"
echo""

echo"===== 1 身份鉴别 ====="
echo"--- 检查默认账户 ---"
${KCADM} get users-r${REALM}-qusername=admin 2>/dev/null | jq -r'.[].username'|grep-q"admin"&&echo"[警告] 存在默认admin账户"||echo"[通过] 默认admin账户已修改"

echo"--- 密码策略检查 ---"
POLICY=$(${KCADM} get realms/${REALM}2>/dev/null | jq -r'.passwordPolicy')
[-z"$POLICY"]&&echo"[高危] 未配置密码策略"||echo"[通过] 已配置密码策略: $POLICY"

echo"--- 暴力破解防护 ---"
BRUTE=$(${KCADM} get realms/${REALM}2>/dev/null | jq -r'.bruteForceProtected')
["$BRUTE"=="true"]&&echo"[通过] 已启用暴力破解防护"||echo"[高危] 未启用暴力破解防护"

echo"--- 会话超时配置 ---"
${KCADM} get realms/${REALM}2>/dev/null | jq '{ssoSessionIdleTimeout: .ssoSessionIdleTimeout, ssoSessionMaxLifespan: .ssoSessionMaxLifespan}'

echo"--- HTTPS强制检查 ---"
SSL=$(${KCADM} get realms/${REALM}2>/dev/null | jq -r'.sslRequired')
["$SSL"=="all"]&&echo"[通过] 强制所有连接使用HTTPS"||echo"[警告] SSL策略: $SSL (建议设置为all)"

echo""
echo"===== 2 访问控制 ====="
echo"--- 角色分离检查 ---"
${KCADM} get roles -r${REALM}2>/dev/null | jq -r'.[].name'|grep-E'admin|user|monitor'|head-10

echo"--- 默认角色检查 ---"
DEFAULT_ROLES=$(${KCADM} get realms/${REALM}2>/dev/null | jq -r'.defaultRoles[]'2>/dev/null |wc-l)
echo"默认角色数量: $DEFAULT_ROLES (应最小化)"

echo"--- 客户端权限检查 ---"
${KCADM} get clients -r${REALM}2>/dev/null | jq '.[] | select(.implicitFlowEnabled==true) | {clientId: .clientId, implicitFlowEnabled: .implicitFlowEnabled}'|grep-q"true"&&echo"[警告] 存在启用Implicit Flow的客户端(不安全)"||echo"[通过] 无Implicit Flow客户端"

echo""
echo"===== 3 安全审计 ====="
echo"--- 事件监听状态 ---"
EVENTS=$(${KCADM} get realms/${REALM}2>/dev/null | jq -r'.eventsEnabled')
["$EVENTS"=="true"]&&echo"[通过] 用户事件监听已启用"||echo"[高危] 用户事件监听未启用"

ADMIN_EVENTS=$(${KCADM} get realms/${REALM}2>/dev/null | jq -r'.adminEventsEnabled')
["$ADMIN_EVENTS"=="true"]&&echo"[通过] 管理员事件监听已启用"||echo"[高危] 管理员事件监听未启用"

echo"--- 事件保留期 ---"
EXPIRATION=$(${KCADM} get realms/${REALM}2>/dev/null | jq -r'.eventsExpiration')
["$EXPIRATION"-ge7776000]2>/dev/null &&echo"[通过] 事件保留期≥90天 ($EXPIRATION秒)"||echo"[警告] 事件保留期<90天 ($EXPIRATION秒)"

echo"--- 最近登录失败事件 ---"
${KCADM} get events -r${REALM}--type LOGIN_ERROR --max52>/dev/null | jq '.[] | {time: .time, ip: .ipAddress, error: .error}'

echo""
echo"===== 4 入侵防范 ====="
echo"--- Keycloak版本检查 ---"
VERSION=$(${KCADM} get serverinfo 2>/dev/null | jq -r'.systemInfo.version')
echo"当前版本: $VERSION (请对比官方安全公告确认是否为最新)"

echo"--- 客户端安全扫描 ---"
PUBLIC_CLIENTS=$(${KCADM} get clients -r ${REALM}2>/dev/null | jq '.[] | select(.publicClient==true) | .clientId'|wc-l)
echo"公共客户端数量: $PUBLIC_CLIENTS (应尽量减少)"

echo"--- 回调URL检查 ---"
${KCADM} get clients -r${REALM}2>/dev/null | jq '.[] | {clientId: .clientId, redirectUris: .redirectUris}'|grep-q"localhost\|127.0.0.1"&&echo"[警告] 存在指向localhost的回调URL"||echo"[通过] 未发现可疑回调URL"

echo""
echo"===== 5 可信验证 ====="
echo"--- 签名算法检查 ---"
${KCADM} get keys -r${REALM}2>/dev/null | jq -r'.keys[].algorithm'|sort|uniq

echo"--- 证书有效性检查 ---"
openssl s_client -connect localhost:8443 -servername localhost 2>/dev/null | openssl x509 -noout-dates2>/dev/null |head-2

echo""
echo"===== 6 数据备份 ====="
echo"--- 数据库备份检查 ---"
ls-la /backup/keycloak* 2>/dev/null |head-5||echo"[警告] 未找到备份文件"

echo"--- Realm导出测试 ---"
${KCADM} get realms/${REALM}> /tmp/keycloak-realm-backup-test.json 2>/dev/null &&echo"[通过] Realm导出功能正常"||echo"[错误] Realm导出失败"

echo""
echo"===== 巡检完成 ====="
echo"详细报告请查看Keycloak Admin Console或导出审计日志"

高风险项重点核查清单

检查项验证命令/方法不合规判定整改建议
默认admin账户未修改登录Admin Console检查存在默认admin用户名创建新管理员,禁用默认admin
未启用密码策略./kcadm.sh get realms/master | jq '.passwordPolicy'返回null或空配置复杂度策略,min=8,需包含3种字符类型
未启用暴力破解防护./kcadm.sh get realms/master | jq '.bruteForceProtected'返回false启用Brute Force Detection,max=5,wait=300s
未强制HTTPS./kcadm.sh get realms/master | jq '.sslRequired'返回”none”或”external”设置为”all”
事件监听未启用./kcadm.sh get realms/master | jq '.eventsEnabled'返回false启用Save Events,配置足够保留期
使用Implicit Flow./kcadm.sh get clients -r master | jq '.[].implicitFlowEnabled'存在true值替换为Authorization Code Flow+PKCE
公共客户端过多./kcadm.sh get clients -r master | jq '.[] | select(.publicClient==true)'生产环境存在公共客户端改为confidential客户端,使用client secret
Web Origins配置为+./kcadm.sh get clients -r master | jq '.[].webOrigins'存在”+”值明确指定允许的源地址
未禁用用户注册./kcadm.sh get realms/master | jq '.registrationAllowed'返回true设置为false,用户由管理员统一创建
使用弱签名算法./kcadm.sh get keys -r master | jq '.keys[].algorithm'存在RSA1_5或HS256使用RS256/ES256/PS256
未配置MFAAdmin Console → Users → 检查Credentials管理员无OTP/WebAuthn配置强制启用双因子认证
备份未配置检查/backup目录或定时任务无备份文件或任务配置数据库和Realm配置自动备份

Keycloak部署模式对比

对比项StandaloneStandalone-HADockerKubernetes
配置方式keycloak.confkeycloak.conf + JDBC_PING环境变量ConfigMap/Secret
数据库存储内置/外部必须外部必须外部必须外部
缓存配置local/invalidationdistributed (ISPN)distributeddistributed
日志收集本地文件本地文件stdout/stderr集中收集
监控集成基础JGroups监控PrometheusPrometheus+Grafana
等保合规需手动加固需手动加固需镜像扫描需NetworkPolicy
国密支持需自定义SPI需自定义SPI需自定义SPI需自定义SPI
备份复杂度高(需Velero等)
适用场景开发/测试生产集群容器化生产云原生生产

测评执行要点

1. 权限要求

  • 所有命令需Keycloak管理员权限(realm-admin或master realm admin)
  • 建议创建专用审计账户,仅授予view-realm、view-users、view-events权限

2. 现场核查重点

  • 数据库安全:确认使用PostgreSQL/MySQL/Oracle等外部数据库,非默认H2(生产环境禁用H2)
  • 缓存安全:检查分布式缓存配置,确保认证会话不跨节点泄露
  • 密钥管理:检查Realm Keys轮换策略,避免长期使用同一密钥对
  • 客户端安全:重点检查SPA/移动端客户端是否正确使用PKCE,避免泄露client_secret

3. 版本差异(18.x vs 20.x vs 22.x)

功能项Keycloak 18.xKeycloak 20.xKeycloak 22.x
底层框架WildFlyQuarkus (默认)Quarkus
配置方式standalone.xmlkeycloak.confkeycloak.conf
存储机制传统新存储(可选)新存储(默认)
管理CLIkcadm.shkcadm.shkcadm.sh + kc.sh
性能优化基础显著提升进一步优化
安全特性基础FAPI支持增强DPoP支持,PAR
等保工具需手动部分自动化更完善的审计

常用命令速查

# 登录与配置
./kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin --password xxx

# 用户管理
./kcadm.sh get users-r master                    # 查看所有用户
./kcadm.sh get users-r master -qusername=admin  # 查看特定用户
./kcadm.sh update users/<user-id>-r master -senabled=false  # 禁用用户

# Realm管理
./kcadm.sh get realms                             # 查看所有Realm
./kcadm.sh get realms/master                      # 查看master配置
./kcadm.sh create realms -srealm=demo -senabled=false       # 创建Realm

# 客户端管理
./kcadm.sh get clients -r master                  # 查看所有客户端
./kcadm.sh get clients -r master -qclientId=myapp            # 查看特定客户端
./kcadm.sh update clients/<client-id>-r master -s'redirectUris=["https://app.example.com/*"]'

# 角色管理
./kcadm.sh get roles -r master                    # 查看Realm角色
./kcadm.sh get clients/<client-id>/roles -r master            # 查看客户端角色

# 事件与审计
./kcadm.sh get events -r master --max100# 查看最近100条事件
./kcadm.sh get events -r master --type LOGIN_ERROR            # 查看登录失败
./kcadm.sh get admin-events -r master             # 查看管理员事件

# 系统信息
./kcadm.sh get serverinfo                         # 查看服务器信息
./kcadm.sh get keys -r master                     # 查看加密密钥
./kcadm.sh get components -r master               # 查看组件配置

# 导出导入(需文件系统访问)
./kc.sh export--dir /backup --realm master       # 导出Realm
./kc.sh import--file /backup/master-realm.json   # 导入Realm

参考标准:GB/T 22239-2019、GB/T 28448-2019、Keycloak官方安全指南、OWASP ASVS、FIDO2/FAPI标准

适用版本:Keycloak 18.0.0+ (Quarkus模式)

验证环境:Standalone/Standalone-HA/Docker/Kubernetes/OpenShift

声明:来自汪汪虚拟空间,仅代表创作者观点。链接:https://eyangzhen.com/8053.html

汪汪虚拟空间的头像汪汪虚拟空间

相关推荐

添加微信
添加微信
Ai学习群
返回顶部