适用版本:Spring Boot 2.7.x(含 3.x 部分适用) 核心问题:引入 spring-boot-starter-actuator 后,默认暴露大量端点(如 /actuator/env、/actuator/beans、/actuator/loggers、/actuator/threaddump、/actuator/heapdump 等),存在严重信息泄露风险。 额外痛点:引入 redisson-spring-boot-starter 会自动引入 Actuator,导致端点难以控制;引入 spring-boot-starter-security 后,所有接口(包括登录)默认需要认证。
本文总结了完整、可落地的修复方案,已在多个生产项目验证通过。
一、常见高危端点及风险
| 端点 | 路径示例 | 泄露内容示例 | 风险等级 |
|---|---|---|---|
| env | /actuator/env | 环境变量、数据库密码、密钥、Redis 配置 | ★★★★★ |
| beans | /actuator/beans | Bean 定义、类路径、依赖关系 | ★★★★☆ |
| loggers | /actuator/loggers | 可远程修改日志级别、查看敏感日志 | ★★★★★ |
| threaddump | /actuator/threaddump | 线程栈、可能泄露业务逻辑 | ★★★★☆ |
| heapdump | /actuator/heapdump | 内存快照(含对象数据、敏感信息) | ★★★★★ |
| metrics / prometheus | /actuator/metrics、/actuator/prometheus | 性能指标(可间接推断负载、业务量) | ★★★☆☆ |
| health (details=always) | /actuator/health | 数据库连接池、Redis 连接、磁盘空间等 | ★★★★☆ |
结论:任何项目上线前,必须把 Actuator 端点锁死。
二、最佳实践配置(线上推荐)
YAML
spring:
profiles:
active: prod
security:
user:
name: ${ACTUATOR_USERNAME:admin} # 外部化,生产必须传
password: ${ACTUATOR_PASSWORD} # 必须外部注入,无默认值
roles: ACTUATOR
management:
endpoints:
enabled-by-default: false # 全局关闭所有端点(最重要!)
web:
base-path: /actuator # 默认即可,可自定义
exposure:
include: health,info,prometheus # 线上只放这三个(或只 health,info)
# exclude: env,beans,loggers,heapdump,threaddump,mappings # 可显式排除
endpoint:
health:
enabled: true
show-details: when-authorized # 认证后才显示细节(最安全)
show-components: when-authorized
info:
enabled: true # 基本信息,可公开
prometheus:
enabled: true # 暴露 Prometheus 指标(监控用)
关键原则:
- enabled-by-default: false → 全局白名单模式
- show-details: when-authorized → 未认证只看到 {"status":"UP"}
- include 绝不写 * 或包含高危端点
三、依赖管理(pom.xml 推荐写法)
在 dependencyManagement 中统一管理:
XML
<dependencyManagement>
<dependencies>
<!-- Redisson - 排除自动引入的 Actuator -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Actuator 自己控制 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Prometheus 注册器(可选) -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<!-- Security 保护 Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
</dependencyManagement>
四、只保护 Actuator、不影响业务接口(最关键)
核心配置类(新建 SecurityConfig.java):
Java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
// 只保护 Actuator 路径
.requestMatchers("/actuator/**").authenticated()
// 所有其他路径公开(包括登录、业务接口、静态资源等)
.anyRequest().permitAll()
)
.httpBasic(Customizer.withDefaults()) // Basic Auth 用于 Actuator
.csrf(csrf -> csrf.disable()); // 关闭 CSRF(登录接口常用)
return http.build();
}
}
效果:
- /actuator/** → 需要 Basic Auth(admin + 密码)
- 登录接口、业务接口、Swagger 等 → 公开访问
- 再也不用一个个放行业务接口
五、常见问题 & 修复
- 登录接口 401 / 没反应 原因:Security 默认保护所有路径 解决:加上面 SecurityConfig,.anyRequest().permitAll()
- 未认证 health 直接显示详细组件 原因:show-details: always 或 Security 未生效 解决:改成 when-authorized + 确认 SecurityConfig 加载
- 其他端点(如 env/beans)还能访问 原因:enabled-by-default 未设 false 或 include 写错了 解决:全局设 false + include 只写允许的
- Redisson 自动引入 Actuator 解决:pom 中排除 + 自己引入 Actuator
六、线上安全加固 checklist
- enabled-by-default: false
- include 只含 health/info/prometheus
- show-details: when-authorized
- SecurityConfig 放行业务接口,只保护 actuator/**
- Actuator 密码外部化(-D 或环境变量)
- Nginx/网关加 IP 白名单或 Basic Auth
- 端口不对外开放(内网 + 反代)
- 定期轮换密码
七、结语
Actuator 是把双刃剑:开发神器,线上定时炸弹。 核心三板斧:
- enabled-by-default: false + 白名单 include
- when-authorized 控制细节显示
- SecurityConfig 精确匹配路径,只保护 /actuator/**
按上面配置 + 代码改完,99% 的 Actuator 漏洞都能堵死,同时不影响业务正常使用。
欢迎收藏、点赞、关注,一起让项目更安全~ 有疑问欢迎留言,我会持续更新。