性能排查时别漏掉安全入口
安全检查要以资产暴露面和权限路径为准,扫描结果需人工确认,不能只依赖规则命中。
排查 GC、线程或内存问题时,工程师可能临时开启 JMX、远程调试或 Arthas。它们能读取运行状态,有些还允许调用管理操作或修改运行时,因此应按高权限运维入口管理,而不是因为“只用于诊断”就直接暴露。
开始排障前先确定入口由谁使用、从哪里访问、持续多久;结束后验证端口、账号和转储文件都已收回。性能工具留下的证据也可能包含业务数据,存储和分享范围需要单独审批。
防线一:加固 JMX 与 JVM 远程诊断端口
为了使用 JConsole 或 VisualVM 监控生产环境 JVM 指标,很多运维配置在启动参数里直接写上了Dcom.sun.management.jmxremote.authenticate=false和Dcom.sun.management.jmxremote.ssl=false。
关闭认证与 TLS 会让网络上可达该端口的主体访问管理接口。具体可执行操作取决于注册的 MBean 和权限配置,但不能把“只读监控”当作默认保证。
使用认证、加密与网络限制
确需远程 JMX 时,开启认证与 TLS,并在防火墙或网络策略中限制来源。优先通过受控运维通道访问,不把端口暴露给不相关网络。下面参数只展示所需配置类别,端口、证书路径和 TLS 选项应按当前 JDK 与部署平台文档验证。
密码和 keystore 口令不要直接写入镜像、仓库或进程命令行。示例以占位符表示受控注入;实际方案可使用平台 Secret、受限文件或自定义 SSL 配置,并检查进程列表、诊断输出和启动日志不会显示秘密。
# JVM 启动参数加固配置 java -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port=9010 \ -Dcom.sun.management.jmxremote.rmi.port=9010 \ -Dcom.sun.management.jmxremote.authenticate=true \ -Dcom.sun.management.jmxremote.ssl=true \ -Djavax.net.ssl.keyStore=/etc/jvm/jmx.keystore \ -Djavax.net.ssl.keyStorePassword=<securely-injected-value> \ -Dcom.sun.management.jmxremote.password.file=/etc/jvm/jmxremote.password \ -Dcom.sun.management.jmxremote.access.file=/etc/jvm/jmxremote.access \ -jar app.jarJMX 密码文件包含敏感内容,应由 JVM 运行账号独占读取,并按当前 JDK 要求设置权限。示例不提供可使用的口令:
# /etc/jvm/jmxremote.password monitorUser <generated-monitor-password> adminUser <generated-admin-password>防线二:Heap Dump(堆转储文件)的凭证脱敏与落盘安全
定位 OOM 或内存泄露时,jmap -dump:format=b,file=heap.hprof是最常用的手段。然而,JVM 的 Heap Dump 文件是整个堆内存的物理快照。
如果应用把密码、令牌、个人信息或密钥保存在堆对象中,它们可能出现在.hprof文件里。是否完整可见取决于应用表示和采集时刻,但转储应按最高相关数据级别保护。
转储不应下载到个人设备或上传到公共分析站点。需要跨环境分析时,使用受控、加密且有访问审计的位置,并为文件设置明确保留期限。
安全规范:内存脱敏与即用即销
- 受限落盘:Dump 写入加密卷上的专用目录,只向获批账号开放,文件名和路径不进入普通应用日志。
- 受控分析:在隔离环境使用审核过的工具,记录访问并按期限删除;第三方服务需经过数据与安全评审。
- 减少秘密驻留:能控制生命周期的秘密可使用
char[]或byte[]并及时覆盖,但库调用、编码转换和复制可能留下其他副本,不能据此保证转储中一定没有秘密。
public class SensitiveKeyHandler { public void processSecretKey(char[] secret) { try { // 使用密钥执行解密操作 doCryptoOperation(secret); } finally { // 尽量缩短当前数组中秘密的驻留时间。 // 这不能清除库或中间转换产生的其他副本。 Arrays.fill(secret, '\0'); } } }防线三:Arthas 与 Java Agent 动态字节码注入管控
Arthas 是定位线上问题的利器。然而,通过java -jar arthas-boot.jar挂载 Agent 会修改 JVM 运行时的 Bytecode。
Arthas Web Console 若对不受信网络开放且缺少认证,会暴露高权限诊断能力。ognl等命令可访问应用对象,应限制用户、命令和会话,并保留审计。
管控策略:禁用外网绑定与动态 Agent 安全审计
- 限制绑定与网络:优先绑定回环或运维网卡,网络策略只放行受控来源。
- 开启认证:用户名、密码或平台访问代理按当前 Arthas 版本配置,秘密不出现在共享脚本和工单正文。
- 评估 Attach 能力:
-XX:+DisableAttachMechanism可以收紧运行时 Attach,也会影响正常诊断工具。高敏感服务可采用,但要先准备替代观测与重启流程。
JVM 线上诊断安全排查 Checklist
发布前与排障结束后,必须对照以下安全卡点进行清理:
核对 JVM 启动参数与容器端口,确认没有未经批准的 JDWP、JMX 或 Arthas 入口。不要只扫描常见端口号,实际端口与绑定地址应从进程、服务和网络策略三处对应起来。
排障结束后关闭临时会话、撤销短期账号,并按存储介质和平台能力删除.hprof。shred在 SSD、快照或写时复制存储上未必可靠,更可控的做法是使用加密临时卷、限制备份,并在到期时删除文件和相关密钥。
应用秘密通过 KMS、Secret Manager 或受限挂载提供,不在 JVM 参数和普通环境日志中出现。最后用低权限身份验证诊断入口确实被拒绝,并保存审批、开放时间、使用者和清理结果。性能排查完成的标准应包含安全入口恢复到原状态。