Storm 安全加固:Kerberos 认证、ACL 权限与多租户隔离
Apache Storm 作为分布式实时计算框架,广泛应用于实时数据处理场景。随着企业级应用的需求增长,Storm 平台的安全性也日益重要。本文将详细介绍 Storm 安全加固的三大核心机制:Kerberos 认证、ACL 权限控制与多租户隔离,帮助企业构建安全的流处理环境。
1. Storm Kerberos 认证机制详解
Kerberos 是一种网络认证协议,通过密钥加密技术为客户端/服务器应用提供强认证。在 Storm 中,Kerberos 认证确保只有经过授权的用户和进程才能访问集群资源。
1.1 Kerberos 认证配置流程
首先需要在集群中配置 Kerberos 服务器,并创建 Storm 相关的主体(principals)。以下是关键步骤:
- 在 KDC(Kerberos 密钥分发中心)中创建 Storm 服务主体:
```
storm/NODE1.EXAMPLE.COM@EXAMPLE.COM
nimbus/NODE1.EXAMPLE.COM@EXAMPLE.COM
supervisor/NODE2.EXAMPLE.COM@EXAMPLE.COM
worker/NODE2.EXAMPLE.COM@EXAMPLE.COM
```
- 创建 Storm 用户主体:
```
stormuser1@EXAMPLE.COM
stormuser2@EXAMPLE.COM
```
- 为各主体生成并分发密钥tab文件(keytab)。
- 在 Storm 配置文件 storm-site.xml 中设置相关参数:
```xml
<property>
<name>storm.security.authentication</name>
<value>kerberos</value>
</property>
<property>
<name>storm.kerberos.login.principal</name>
<value>storm/NODE1.EXAMPLE.COM@EXAMPLE.COM</value>
</property>
<property>
<name>storm.kerberos.login.keytab</name>
<value>/path/to/storm.keytab</value>
</property>
```
1.2 客户端认证流程
客户端使用 Storm 命令行工具(如 storm jar)提交拓扑时,需要进行 Kerberos 认证:
# 获取 Kerberos 票据 kinit stormuser1@EXAMPLE.COM # 使用票据提交拓扑 storm jar /path/to/topology.jar com.example.TopologyMain此图展示了客户端通过 Kerberos 认证访问 Storm 集群的完整流程:从用户认证开始,获取 TGT(票据授权票据),请求服务票据,最终获得集群访问权限。
2. Storm ACL 权限控制实现
ACL(Access Control List) 是 Storm 中用于管理用户权限的关键机制,通过细粒度的权限控制,确保只有授权用户才能执行特定操作。
2.1 ACL 配置方式
Storm 支持多种 ACL 配置方式:
- 全局配置:在 storm.yaml 中设置:
```yaml
# 开启 ACL
storm.security.authorization: true
# 设置超级用户
storm.zookeeper.superusers: "admin"
# 设置授权提供者
storm.auth.method: "org.apache.storm.security.auth.authorize.SimpleACLAuthorizer"
```
- 拓扑级别:在提交拓扑时设置:
```java
Map<String, String> topoConf = new HashMap<>();
// 设置拓扑所属用户
topoConf.put(TOPOLOGY_USER, "stormuser1");
// 设置拓扑权限
topoConf.put(TOPOLOGY_SUBMITTER_USER, "stormuser1");
topoConf.put(TOPOLOGY_NAME, "test-topology");
// 设置 ACL
topoConf.put("topology.owner.permission", "read,write");
```
2.2 权限类型与控制
Storm 定义了多种操作权限:
| 权限类型 | 说明 |
|---|---|
| read | 读取拓扑信息、配置、状态等 |
| write | 修改拓扑配置、重启拓扑、杀死拓扑等 |
| execute | 提交新拓扑 |
| supervising | 管理其他用户的拓扑 |
此图展示了 Storm 中不同层级与用户的权限控制关系:超级用户具有完全控制权限,可以管理所有资源;普通用户只能访问自己的拓扑资源,权限受限。
2.3 ACL 实践案例
假设我们有两个用户:stormuser1 和 stormuser2,需要配置以下权限:
- stormuser1 可以提交和管理自己的拓扑,但不能访问 stormuser2 的拓扑
- stormuser2 只能查看集群状态,不能提交或管理拓扑
配置示例:
// stormuser1 的拓扑配置 Map<String, Object> topoConf1 = new HashMap<>(); topoConf1.put(TOPOLOGY_USER, "stormuser1"); topoConf1.put(TOPOLOGY_NAME, "user1-topology"); topoConf1.put("topology.owner.permission", "read,write"); topoConf1.put("topology.users.permissions", "stormuser1:r,w"); // stormuser2 的集群配置(仅读权限) Map<String, Object> clusterConf2 = new HashMap<>(); clusterConf2.put("cluster.users.permissions", "stormuser2:r");3. Storm 多租户隔离实践
多租户隔离是企业级 Storm 集群的关键需求,通过资源隔离与权限控制,确保不同租户之间的互不干扰。
3.1 资源隔离策略
Storm 提供多种资源隔离机制:
- 资源调度隔离:
```yaml
# 设置资源权重隔离
nimbus.thrift.max.buffer.size: 1048576
supervisor.slots.ports:
- 6700
- 6701
- 6702
- 6703
- 6704
- 6705
- 6706
- 6707
# 设置租户资源配额
resource.isolation.plugin: "org.apache.storm.scheduler.resource.strategies.SchedulingWithSharing"
resource.wheel.share.strategy: "org.apache.storm.scheduler.resource.strategies.scheduling.DefaultResourceAwareStrategy"
```
- 网络隔离:
```yaml
# 为不同租户设置不同的 RPC 端口
supervisor.slots.ports:
- tenant1:6700-6703
- tenant2:6704-6707
```
- 存储隔离:
```bash
# 为不同租户创建独立的 Zookeeper 路径
/storm/tenant1/topologies
/storm/tenant2/topologies
```
3.2 多租户配置示例
此图展示了 Storm 中多租户隔离的架构,包括独立的命名空间、隔离的数据区以及资源配额配置,确保不同租户之间互不干扰。
3.3 实战配置案例
下面是一个完整的多租户 Storm 安全配置示例:
// Storm 安全配置类 public class StormSecurityConfig { // Kerberos 配置 public static Map<String, Object> getKerberosConfig() { Map<String, Object> conf = new HashMap<>(); conf.put("storm.security.authentication", "kerberos"); conf.put("storm.kerberos.login.principal", "storm/NODE1.EXAMPLE.COM@EXAMPLE.COM"); conf.put("storm.kerberos.login.keytab", "/etc/storm/storm.keytab"); return conf; } // ACL 配置 public static Map<String, Object> getAclConfig() { Map<String, Object> conf = new HashMap<>(); conf.put("storm.security.authorization", true); conf.put("storm.auth.method", "org.apache.storm.security.auth.authorize.SimpleACLAuthorizer"); return conf; } // 多租户配置 public static Map<String, Object> getMultiTenantConfig(String tenantId) { Map<String, Object> conf = new HashMap<>(); // 设置租户资源配额 conf.put("topology.memory.request.mb", 512); conf.put("topology.cpu.percent", 20.0); // 设置租户网络隔离 conf.put("topology.worker.childopts", "-Djava.net.preferIPv4Stack=true -Dstorm.zookeeper.tenant=" + tenantId); // 设置租户权限 conf.put(TOPOLOGY_USER, tenantId); conf.put("topology.owner.permission", "read,write"); conf.put("topology.users.permissions", tenantId + ":r,w"); return conf; } // 提交租户拓扑 public static void submitTenantTopology(String topologyJar, String topologyName, String tenantId, MainClass mainClass) throws Exception { // 合并配置 Map<String, Object> conf = new HashMap<>(); conf.putAll(getKerberosConfig()); conf.putAll(getAclConfig()); conf.putAll(getMultiTenantConfig(tenantId)); // 创建拓扑 TopologyBuilder builder = new TopologyBuilder(); // 构建拓扑逻辑... // 提交拓扑 StormSubmitter.submitTopology(topologyName, conf, builder.createTopology()); } }4. 最小示例与注意事项
下面是一个完整的 Storm 安全加固最小示例:
import org.apache.storm.Config; import org.apache.storm.StormSubmitter; import org.apache.storm.topology.TopologyBuilder; import org.apache.storm.security.auth.kerberos.KerberosRealm; public class SecureStormTopology { public static void main(String[] args) throws Exception { // 1. 创建 Storm 配置 Config conf = new Config(); // 2. 启用 Kerberos 认证 conf.set(Config.STORM_SECURITY_AUTHENTICATION, "org.apache.storm.security.auth.authenticator.KerberosSaslAuthenticator"); conf.set(Config.STORM_KERBEROS_LOGIN_PRINCIPAL, "storm/NODE1.EXAMPLE.COM@EXAMPLE.COM"); conf.set(Config.STORM_KERBEROS_LOGIN_KEYTAB, "/etc/storm/storm.keytab"); // 3. 启用 ACL conf.set(Config.STORM_SECURITY_AUTHORIZATION, true); conf.set(Config.STORM_AUTH_METHOD, "org.apache.storm.security.auth.authorize.SimpleACLAuthorizer"); // 4. 设置多租户配置 conf.set(Config.TOPOLOGY_USER, "tenant1"); conf.set("topology.owner.permission", "read,write"); conf.set("topology.users.permissions", "tenant1:r,w"); // 5. 设置资源配额 conf.set(Config.TOPOLOGY_WORKERS, 2); conf.set(Config.TOPOLOGY_MEMORY_REQUEST_MB, 512); conf.set(Config.TOPOLOGY_CPU_PERCENT, 20.0); // 6. 创建拓扑 TopologyBuilder builder = new TopologyBuilder(); builder.setSpout("word-spout", new WordSpout(), 1); builder.setBolt("word-bolt", new WordBolt(), 2) .shuffleGrouping("word-spout"); // 7. 提交拓扑 StormSubmitter.submitTopology("secure-word-count", conf, builder.createTopology()); } }注意事项
- Kerberos 配置:
- 确保 KDC 服务器可访问
- 正确配置主体(principal)和密钥tab文件
- 定期更新密钥tab文件,增强安全性
- ACL 配置:
- 为不同用户设置最小必要权限
- 定期审查 ACL 配置,移除不再需要的权限
- 谨慎设置超级用户权限
- 多租户配置:
- 为每个租户分配独立的资源配额
- 监控各租户的资源使用情况,防止资源争用
- 考虑使用容器技术进一步隔离租户资源
- 整体安全:
- 定期更新 Storm 到最新稳定版本
- 启用 Storm UI 的安全访问控制
- 配置防火规则,限制不必要的网络访问
通过以上配置,企业可以构建一个安全、可靠的 Storm 流处理平台,保障数据安全和业务连续性。