各位大佬,想看那种网络设备/操作系统/数据库/中间件的测评命令清单,可在留言区留言!
依据 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 → Sessions | SSO 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 Detection | Enabled=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 → Config | Save Events=ON |
| 事件类型覆盖 | Enabled Event Types | 包含LOGIN/LOGIN_ERROR/LOGOUT/REGISTER/UPDATE_PASSWORD等 |
| 事件保留时间 | Expiration | ≥90天 |
| 管理员事件 | Admin Events Settings | Enabled=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+且已应用最新补丁 |
| 不必要客户端 | 客户端列表审查 | 仅业务所需客户端启用 |
| 不必要Realm | Realm列表审查 | 删除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 |
| 未配置MFA | Admin Console → Users → 检查Credentials | 管理员无OTP/WebAuthn配置 | 强制启用双因子认证 |
| 备份未配置 | 检查/backup目录或定时任务 | 无备份文件或任务 | 配置数据库和Realm配置自动备份 |
Keycloak部署模式对比
| 对比项 | Standalone | Standalone-HA | Docker | Kubernetes |
|---|---|---|---|---|
| 配置方式 | keycloak.conf | keycloak.conf + JDBC_PING | 环境变量 | ConfigMap/Secret |
| 数据库存储 | 内置/外部 | 必须外部 | 必须外部 | 必须外部 |
| 缓存配置 | local/invalidation | distributed (ISPN) | distributed | distributed |
| 日志收集 | 本地文件 | 本地文件 | stdout/stderr | 集中收集 |
| 监控集成 | 基础 | JGroups监控 | Prometheus | Prometheus+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.x | Keycloak 20.x | Keycloak 22.x |
|---|---|---|---|
| 底层框架 | WildFly | Quarkus (默认) | Quarkus |
| 配置方式 | standalone.xml | keycloak.conf | keycloak.conf |
| 存储机制 | 传统 | 新存储(可选) | 新存储(默认) |
| 管理CLI | kcadm.sh | kcadm.sh | kcadm.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