零信任与安全增强
EnerOS 全面落地零信任架构:从不信任,始终校验(Never Trust, Always Verify)。所有内部服务间通信强制 mTLS 双向认证,由内置 CA 签发证书;所有命令决策链路通过 HMAC 签名链式审计并落入 WORM 取证存储;同时配套入侵检测(IDS)、密钥管理(KMS)与合规框架(NERC CIP / IEC 62443 / GB/T 22239)。
零信任安全由 eneros-trust、eneros-ids、eneros-audit 三个 crate 协同提供,覆盖身份、传输、决策、存储四个维度。
安全架构总览
┌────────────────────────────────────────────────────────────┐
│ 外部访问层 │
│ REST / GraphQL / WebSocket / SSE ──▶ Gateway (mTLS) │
└──────────────────────────┬─────────────────────────────────┘
│
┌──────────────────────────▼─────────────────────────────────┐
│ 身份与授权层 │
│ X.509 + SPIFFE ─▶ RBAC + ABAC ─▶ Audit Decision │
└──────────────────────────┬─────────────────────────────────┘
│
┌──────────────────────────▼─────────────────────────────────┐
│ 服务间通信层 │
│ Agent ◀─mTLS──▶ Kernel Agent ◀─mTLS──▶ Agent │
│ 所有 RPC 强制 TLS 1.3 + PQC 混合 cipher │
└──────────────────────────┬─────────────────────────────────┘
│
┌──────────────────────────▼─────────────────────────────────┐
│ 审计与取证层 │
│ HMAC 链式审计 ─▶ WORM 存储(7 年保留) │
│ IDS 规则 + 异常检测 ─▶ SOC 告警通道 │
└────────────────────────────────────────────────────────────┘
| 安全维度 | 实现 crate | 关键技术 |
|---|---|---|
| 身份认证 | eneros-trust | mTLS + X.509 + SPIFFE SVID |
| 授权决策 | eneros-trust | RBAC + ABAC 策略引擎 |
| 传输加密 | eneros-trust | TLS 1.3 + Kyber768 混合 |
| 审计链 | eneros-audit | HMAC-SHA256 链式结构 |
| 取证存储 | eneros-audit | WORM + Zstd + 7 年保留 |
| 入侵检测 | eneros-ids | 规则匹配 + 行为基线 |
| 密钥管理 | eneros-trust | SoftHSM2 / PKCS#11 / 云 KMS |
内部 CA 与证书
EnerOS 内置私有 CA,自动签发与轮转所有内部服务证书。CA 支持 Root CA 与 Intermediate CA 两级结构,遵循 X.509 v3 标准。
use eneros_security::{Ca, CertificateSpec, KeyUsage, KeyAlgorithm};
use std::time::Duration;
let ca = Ca::builder()
.root_key_path("/etc/eneros/ca.key")
.root_cert_path("/etc/eneros/ca.crt")
.intermediate_key_path("/etc/eneros/intermediate.key")
.intermediate_cert_path("/etc/eneros/intermediate.crt")
.build().await?;
// 为内部服务签发证书
let spec = CertificateSpec::new("agent-runtime.eneros.internal")
.sans(vec!["agent-runtime", "10.0.0.5", "agent-runtime.default.svc"])
.validity(Duration::from_secs(86400 * 90))
.key_usage(KeyUsage::ServerAndClient)
.key_algorithm(KeyAlgorithm::EcdsaP256)
.extensions(vec![
Extension::spiffe_uri("spiffe://eneros/agent-runtime"),
Extension::basic_constraints(ca: false, path_len: 0),
]);
let cert = ca.issue(spec).await?;
println!("签发证书序列号: {}", cert.serial_number);
println!("有效期至: {}", cert.not_after);
证书自动轮转
CA 监控所有已签发证书,到期前 30 天自动续签,零停机:
use eneros_security::ca::RotationPolicy;
let rotation = RotationPolicy::new()
.renew_before(Duration::from_secs(86400 * 30))
.on_renew(|old, new| async move {
kernel.reload_tls_cert(new).await?;
notify_service("agent-runtime").await
})
.parallelism(4); // 并发续签
ca.enable_rotation(rotation).await?;
CA 配置参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| root_key_path | /etc/eneros/ca.key | Root CA 私钥路径 |
| root_cert_path | /etc/eneros/ca.crt | Root CA 证书路径 |
| validity | 90 天 | 服务证书有效期 |
| renew_before | 30 天 | 提前续签时间窗 |
| key_algorithm | ECDSA P-256 | 证书签名算法 |
| signature_algorithm | SHA-256 | 哈希算法 |
| serial_length | 128 bit | 序列号长度 |
mTLS 双向认证
所有 RPC 通道(Agent ↔ Kernel、Agent ↔ Agent、Gateway ↔ Backend)强制 mTLS,未通过认证的连接在 TCP 握手阶段即被拒绝。
use eneros_security::tls::{TlsConfig, TlsVersion, CipherSuite};
let tls = TlsConfig::mutual()
.server_cert("/etc/eneros/certs/server.crt")
.server_key("/etc/eneros/certs/server.key")
.client_ca("/etc/eneros/ca.crt")
.min_version(TlsVersion::TLS_1_3)
.cipher_suites(CipherSuite::post_quantum())
.session_resumption(false)
.client_auth(ClientAuth::RequireAnyCert)
.verify_callback(|cert| async move {
let chain = cert_chain_store.verify(&cert).await?;
if !chain.has_spiffe_uri() {
return Err(TlsError::InvalidIdentity);
}
Ok(())
});
server.listen(addr, tls).await?;
TLS 配置参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| min_version | TLS 1.3 | 最低 TLS 版本 |
| cipher_suites | PQC 混合 | 加密套件(含 Kyber768) |
| session_resumption | false | 会话恢复(安全考虑关闭) |
| client_auth | RequireAnyCert | 客户端证书要求 |
| verify_timeout | 5s | 证书验证超时 |
| handshake_timeout | 10s | 握手超时 |
HMAC 链式审计
每条审计记录都包含前一条的 HMAC-SHA256,形成不可篡改的链式结构。任何中间记录被修改都会导致后续所有记录的链断裂。
use eneros_security::audit::{AuditChain, AuditEntry, AuditContext};
use std::collections::HashMap;
let mut chain = AuditChain::open("/var/eneros/audit.chain")?;
// 第一条记录自动形成创世块(genesis)
chain.append(AuditEntry::new()
.actor("dispatch_agent")
.actor_identity("spiffe://eneros/dispatch-agent")
.action("open_breaker")
.target(breaker_id.to_string())
.target_type("breaker")
.verdict("allow")
.context(AuditContext::new()
.insert("reason", "fault_isolation")
.insert("command_id", "cmd-7821")
.insert("safety_check", "passed"))
.timestamp(now())).await?;
// 后续记录自动引用前一条的 HMAC
chain.append(AuditEntry::new()
.actor("self_healing_agent")
.action("restore_power")
.target(feeder_id.to_string())
.verdict("allow")
.timestamp(now())).await?;
// 验证链完整性
let valid = chain.verify().await?;
assert!(valid, "审计链被篡改");
审计字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| actor | String | 操作发起者(Agent 名 / 用户) |
| actor_identity | String | SPIFFE SVID 身份标识 |
| action | String | 操作类型(open_breaker / restore_power 等) |
| target | String | 操作目标 ID |
| target_type | String | 目标类型(breaker / feeder / generator) |
| verdict | String | 决策结果(allow / deny / modified) |
| context | HashMap | 自定义上下文 |
| prev_hash | [u8; 32] | 前一条记录的 HMAC |
| hash | [u8; 32] | 当前记录的 HMAC |
WORM 取证存储
审计日志写入 WORM(Write Once Read Many)存储,满足 NERC CIP-007 与 IEC 62443 要求。底层使用带只读挂载的文件系统,任何后续修改尝试都会被文件系统直接拒绝。
use eneros_security::worm::{WormStore, Compression, HashAlgo, RetentionPolicy};
let worm = WormStore::mount("/var/eneros/worm")?
.retention(RetentionPolicy::years(7)) // 7 年保留
.compression(Compression::Zstd { level: 6 })
.hash_chain(HashAlgo::Sha256)
.segment_size(64 * 1024 * 1024) // 64MB 段
.immutable_after_close(true);
worm.append(&audit_entry).await?;
// 试图篡改将失败
let result = worm.overwrite(0, &fake_entry).await;
assert!(result.is_err(), "WORM 存储拒绝写入");
// 读取历史审计
let records = worm.query(Query::by_actor("dispatch_agent")
.range(now() - Duration::from_secs(86400) .. now()))
.await?;
WORM 配置参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| mount_path | /var/eneros/worm | 挂载点 |
| retention | 7 年 | 保留期 |
| compression | Zstd level 6 | 压缩算法 |
| hash_chain | SHA-256 | 哈希算法 |
| segment_size | 64MB | 单段大小 |
| immutable_after_close | true | 段关闭后不可变 |
入侵检测(IDS)
内置基于规则与异常的 IDS,覆盖典型电力 OT 攻击模式。规则可在运行时热加载,无需重启服务。
use eneros_security::ids::{Ids, Signature, AlertAction, Severity};
let mut ids = Ids::new()
.signature(Signature::modbus_anomaly()
.severity(Severity::High))
.signature(Signature::scada_unauthorized_command()
.severity(Severity::Critical))
.signature(Signature::rapid_breaker_operation()
.window(Duration::from_secs(60))
.threshold(10)) // 命令风暴:60 秒内 ≥10 次开关操作
.signature(Signature::lateral_movement()
.severity(Severity::High))
.signature(Signature::unusual_login_time()
.baseline(Duration::from_secs(86400 * 30)))
.action_on_alert(AlertAction::BlockAndNotify);
ids.start().await?;
// 订阅告警
while let Some(alert) = ids.alerts().recv().await {
println!("[{}] {}", alert.severity, alert.message);
notify_soc(&alert).await?;
if alert.severity == Severity::Critical {
kernel.lockdown().await?;
}
}
IDS 规则库
| 规则 | 检测场景 | 默认动作 |
|---|---|---|
| modbus_anomaly | Modbus 异常功能码 | Block + Notify |
| scada_unauthorized_command | SCADA 未授权命令 | Block + Notify |
| rapid_breaker_operation | 命令风暴(开关频繁切换) | Block |
| lateral_movement | 横向移动 | Notify + Trace |
| unusual_login_time | 异常时间登录 | Notify |
| port_scan | 端口扫描 | Block |
| dga_domain | DGA 域名访问 | Block + Notify |
| iec104_apdu_flood | IEC 104 APDU 洪泛 | Block |
密钥管理(KMS)
支持本地 KMS、SoftHSM2、PKCS#11 硬件 HSM 与云 KMS 集成:
use eneros_security::kms::{Kms, KeyId, KeyAlgorithm, KmsBackend, KeyPolicy};
let kms = Kms::builder()
.backend(KmsBackend::SoftHsm2)
.config("/etc/eneros/kms.conf")
.build().await?;
// 创建密钥
let key_id = kms.create_key(KeyAlgorithm::Aes256Gcm)
.policy(KeyPolicy::rotate_every(Duration::from_secs(86400 * 90)))
.await?;
// 加密 / 解密
let ciphertext = kms.encrypt(&key_id, plaintext).await?;
let plaintext = kms.decrypt(&key_id, &ciphertext).await?;
// 密钥轮转
kms.rotate(&key_id).await?;
// 列出密钥
for key in kms.list_keys().await? {
println!("密钥 {} 当前版本 {}", key.id, key.current_version);
}
KMS 后端对比
| 后端 | 安全等级 | 性能 | 适用 |
|---|---|---|---|
| 本地文件 | 低 | < 50μs | 开发测试 |
| SoftHSM2 | 中 | < 200μs | 生产环境 |
| PKCS#11 HSM | 高 | < 500μs | 关键基础设施 |
| AWS KMS | 高 | < 50ms | 云部署 |
| Azure Key Vault | 高 | < 50ms | 云部署 |
合规框架
EnerOS 内置多套合规框架,可按租户配置:
| 标准 | 覆盖范围 | 状态 | 强制项 |
|---|---|---|---|
| NERC CIP | 北美电力可靠性 | ✅ | CIP-007 审计、CIP-011 数据保护 |
| IEC 62443 | 工控安全 | ✅ | 区域分级、访问控制 |
| GB/T 22239 | 中国等保 2.0 三级 | ✅ | 安全审计、入侵防范 |
| ISO 27001 | 信息安全管理体系 | ✅ | 风险评估、合规审计 |
| GDPR | 欧盟数据保护 | ✅ | 数据主体权利、跨境传输 |
安全能力矩阵
| 能力 | 实现技术 | 强制级别 |
|---|---|---|
| 身份认证 | mTLS + X.509 + SPIFFE | 内核强制 |
| 授权 | RBAC + ABAC 策略引擎 | 内核强制 |
| 加密传输 | TLS 1.3 + PQC 混合 | 默认开启 |
| 加密存储 | AES-256-GCM | 默认开启 |
| 审计 | HMAC 链式 + WORM | 内核强制 |
| 入侵检测 | 规则 + 异常基线 | 默认开启 |
| 密钥管理 | KMS + HSM | 默认开启 |
| 密钥轮转 | 自动,90 天 | 默认开启 |
| 安全网关 | 多层防护 + 速率限制 | 内核强制 |
| 数据脱敏 | 动态脱敏 + 静态脱敏 | 可配置 |
性能指标
| 操作 | 延迟 | 吞吐 |
|---|---|---|
| mTLS 握手 | < 5ms | 1 万次/秒 |
| 证书签发 | < 100ms | - |
| HMAC 链式审计写入 | < 50μs | 5 万次/秒 |
| WORM 写入 | < 100μs | 2 万次/秒 |
| IDS 规则匹配 | < 5μs | 100 万次/秒 |
| KMS 加密 | < 200μs | - |
| ABAC 决策 | < 100μs | 10 万次/秒 |
| 证书验证 | < 2ms | - |
与其他能力的关系
- 安全守卫:安全网关基于身份认证结果执行决策,详见 安全守卫
- 多租户隔离:租户身份绑定证书,按租户分配 SPIFFE 命名空间
- 国际化合规:合规框架支持多区域差异化配置,详见 国际化与合规
- 物联网接入:IoT 设备使用专用证书体系接入,详见 物联网泛在接入
- 高可用:审计日志跨区域复制,WORM 段在副本间保持强一致