跳到主内容

v0.20.0 版本说明

EnerOS v0.20.0

发布日期:2025年06月01日 版本代号:ZeroTrust Git Tag:v0.20.0 支持状态:稳定(Stable) Crate 总数:56(新增 4 个) 测试用例数:8020+(新增 540)

版本概述

EnerOS v0.20.0「ZeroTrust」是 EnerOS v0.1.0 至 v0.39.0「内部迭代」阶段的安全收官版本,本版本的核心目标是引入零信任架构(Zero Trust Architecture),包括 mTLS 双向认证、服务网格、证书自动轮换与网络策略,使 EnerOS 集群在节点间通信、服务间调用、客户端访问三个层面均实现「永不信任,始终验证」的安全模型,满足 NERC CIP、IEC 62443 等电力行业安全合规要求。

传统安全模型采用「城堡与护城河」模式——内部网络被视为可信,仅在外部边界进行防护。一旦攻击者突破边界,即可在内部横向移动。电力系统作为国家关键信息基础设施,面临 APT 攻击、供应链攻击、内部威胁等多种风险,传统边界防护已无法满足要求。零信任架构假设「网络始终不可信」,所有通信均需双向认证、最小授权、持续校验,从根本上消除内部信任假设。

本版本引入了 eneros-trust(零信任核心)、eneros-trust-mtls(mTLS 双向认证)、eneros-trust-mesh(服务网格)、eneros-trust-cert(证书管理)四个新 crate。设计哲学是「身份即边界,加密即默认」——所有服务与节点均拥有 X.509 证书身份,所有通信默认 mTLS 加密,访问控制基于身份而非网络位置,证书生命周期全自动管理。

关键数据

指标v0.19.0v0.20.0提升
通信加密覆盖率30%100%全加密
证书轮换自动化手工全自动零运维
服务间认证单向双向 mTLS强身份
网络策略粒度IP 级服务级精细化
合规达标率80%99%+19pp

新特性

1. 零信任架构

引入 eneros-trust crate,作为零信任子系统的统一入口,统筹身份认证、访问控制、通信加密与策略执行。零信任架构遵循 NIST SP 800-207 标准,实现「主体(Subject)→ 资源(Resource)→ 策略(Policy)」的访问模型。

零信任模型

use eneros_trust::{ZeroTrust, TrustConfig, Identity, Policy};

let trust = ZeroTrust::new(TrustConfig {
    mtls_required: true,
    cert_authority: CertAuthority::internal("https://ca.internal:8200"),
    policy_engine: PolicyEngine::opa(),
    audit_all_access: true,
    default_deny: true,
})?;

// 注册服务身份
trust.register_identity(Identity::service("eneros-scheduler")
    .namespace("default")
    .permissions(&["topology:read", "dispatch:command"]))?;

// 启用零信任
trust.enable().await?;

零信任原则

原则实现说明
永不信任默认拒绝所有访问默认拒绝
始终验证每次请求认证不缓存信任
最小权限RBAC + ABAC仅授予必要权限
持续校验实时策略评估策略变更即时生效
加密通信mTLS 全覆盖所有流量加密
假设被入侵全面审计记录所有访问

2. mTLS 双向认证

引入 eneros-trust-mtls crate,为所有 EnerOS 内部通信(节点间、服务间、客户端-服务端)强制启用 mTLS 双向认证。通信双方均需出示有效 X.509 证书,证书由内部 CA 签发,身份基于证书 SAN(Subject Alternative Name)字段。

mTLS 配置

use eneros_trust_mtls::{MtlsConfig, MtlsManager};

let mtls = MtlsManager::new(MtlsConfig {
    ca_cert: "/etc/eneros/certs/ca.pem",
    server_cert: "/etc/eneros/certs/server.pem",
    server_key: "/etc/eneros/certs/server.key",
    client_cert: "/etc/eneros/certs/client.pem",
    client_key: "/etc/eneros/certs/client.key",
    min_tls_version: TlsVersion::V1_3,
    cipher_suites: CipherSuite::modern(),
    cert_rotation: RotationConfig::auto(Duration::days(30)),
})?;

// 应用到所有 gRPC / HTTP 服务器
ctx.apply_mtls(&mtls).await?;

// 应用到所有出站连接
ctx.apply_mtls_client(&mtls).await?;

证书身份模型

use eneros_trust_mtls::{CertificateIdentity, SpiffeId};

// 服务身份基于 SPIFFE ID
let identity = CertificateIdentity::from_spiffe(
    SpiffeId::new("spiffe://eneros/default/scheduler")
)?;

// 从证书提取身份
fn verify_peer(cert: &X509) -> Result<Identity> {
    let spiffe = cert.spiffe_id()?;
    let identity = Identity::from_spiffe(spiffe)?;
    
    // 校验证书有效性
    cert.verify_chain(&ca_cert)?;
    cert.verify_not_expired()?;
    cert.verify_not_revoked()?;
    
    Ok(identity)
}

mTLS 握手性能

阶段耗时说明
TCP 握手0.5ms基础连接
TLS 握手1.2ms含证书验证
会话恢复0.3ms0-RTT
总计(新连接)1.7ms可接受
总计(复用)0.3ms极低

3. 服务网格

引入 eneros-trust-mesh crate,实现轻量级服务网格,为 EnerOS 内部服务间通信提供透明的 mTLS 加密、负载均衡、熔断限流与可观测性。服务网格采用 Sidecar 模式,对应用透明,无需修改业务代码。

服务网格架构

use eneros_trust_mesh::{ServiceMesh, MeshConfig};

let mesh = ServiceMesh::new(MeshConfig {
    sidecar_image: "eneros/mesh-sidecar:0.20",
    control_plane: "mesh-control:15000",
    data_plane_port: 15001,
    mtls_enabled: true,
    auto_injection: true,
    tracing: true,
    metrics: true,
})?;

// 注册服务
mesh.register_service(Service::new("eneros-scheduler")
    .port(8080)
    .namespace("default")
    .mtls_required(true))?;

mesh.register_service(Service::new("eneros-twin")
    .port(8081)
    .namespace("default")
    .mtls_required(true))?;

mesh.start().await?;

服务网格能力

能力说明透明性
mTLS 加密自动加密服务间通信完全透明
负载均衡多实例请求分发完全透明
熔断故障实例自动隔离完全透明
限流服务级速率限制配置即可
重试自动重试失败请求配置即可
追踪全链路追踪完全透明
指标服务级指标暴露完全透明

流量策略

use eneros_trust_mesh::{TrafficPolicy, Rule};

// 定义流量策略
let policy = TrafficPolicy::new("scheduler-to-twin")
    .source("eneros-scheduler")
    .destination("eneros-twin")
    .mtls(MtlsMode::Strict)  // 强制 mTLS
    .load_balancing(LoadBalancing::round_robin())
    .circuit_breaker(CircuitBreaker::new()
        .error_threshold(0.1)
        .consecutive_errors(5)
        .cooldown(Duration::seconds(30)))
    .rate_limit(RateLimit::new(1000, Duration::seconds(1)))
    .retry(RetryPolicy::new()
        .max_attempts(3)
        .backoff(Backoff::exponential(Duration::milliseconds(50))));

mesh.apply_policy(policy).await?;

4. 证书自动轮换

引入 eneros-trust-cert crate,实现 X.509 证书的全生命周期自动化管理,包括签发、分发、轮换、撤销。证书轮换无需重启服务,通过热加载机制实现零停机更新。

证书管理

use eneros_trust_cert::{CertManager, CertConfig, CertSpec};

let cert_manager = CertManager::new(CertConfig {
    ca_endpoint: "https://ca.internal:8200",
    ca_token: env::var("CA_TOKEN")?,
    storage: CertStorage::disk("/etc/eneros/certs"),
    rotation_threshold: Duration::days(7),  // 到期前 7 天轮换
    rotation_check: Duration::hours(1),
})?;

// 为服务签发证书
let cert = cert_manager.issue(CertSpec::new("eneros-scheduler")
    .namespace("default")
    .san_dns("scheduler.eneros.svc")
    .san_spiffe("spiffe://eneros/default/scheduler")
    .validity(Duration::days(90))
    .key_type(KeyType::EcdsaP256)
    .key_usage(&[KeyUsage::DigitalSignature, KeyUsage::KeyEncipherment]))?;

自动轮换流程

// 证书轮换监控
cert_manager.on_rotation(|event| {
    log::info!("证书轮换: service={}", event.service);

    match event.phase {
        RotationPhase::Started => {
            log::info!("开始轮换 {} 的证书", event.service);
        }
        RotationPhase::NewCertIssued => {
            log::info!("新证书已签发,开始热加载");
        }
        RotationPhase::HotReloaded => {
            log::info!("证书已热加载,新连接使用新证书");
        }
        RotationPhase::Completed => {
            log::info!("旧证书已撤销,轮换完成");
        }
    }
});

// 启动自动轮换
cert_manager.start_auto_rotation().await?;

证书生命周期

阶段触发条件耗时影响
签发服务注册500ms新证书
分发签发后100ms证书到节点
轮换到期前 7 天2s零停机
热加载轮换后200ms新连接使用
撤销轮换后 24h100ms旧证书失效

证书撤销检查

use eneros_trust_cert::{RevocationList, OcspResponder};

// 配置撤销检查
let revocation = RevocationList::new()
    .ocsp_responder(OcspResponder::new("http://ocsp.internal"))
    .crl_check(CrlCheck::enabled())
    .cache(Duration::minutes(5));

// 在 mTLS 握手时检查撤销
mtls.with_revocation_check(revocation)?;

5. 网络策略

引入基于身份的网络策略,替代传统基于 IP 的防火墙规则。网络策略以服务身份为粒度,声明式定义允许的通信路径,默认拒绝所有未明确允许的流量。

网络策略定义

use eneros_trust::network::{NetworkPolicy, Rule, Direction};

let policy = NetworkPolicy::new("scheduler-allow-list")
    .namespace("default")
    .pod_selector(PodSelector::service("eneros-scheduler"))
    .ingress(Rule::allow()
        .from(IdentitySelector::service("eneros-gateway"))
        .to_ports(&[Port::tcp(8080)]))
    .ingress(Rule::allow()
        .from(IdentitySelector::service("eneros-dashboard"))
        .to_ports(&[Port::tcp(8080)]))
    .egress(Rule::allow()
        .to(IdentitySelector::service("eneros-twin"))
        .to_ports(&[Port::tcp(8081)]))
    .egress(Rule::allow()
        .to(IdentitySelector::service("eneros-timeseries"))
        .to_ports(&[Port::tcp(9090)]))
    .default_deny(Direction::Both);

trust.apply_network_policy(policy).await?;

网络策略示例表

源服务目标服务端口协议动作
eneros-gatewayeneros-scheduler8080TCP允许
eneros-dashboardeneros-scheduler8080TCP允许
eneros-schedulereneros-twin8081TCP允许
eneros-schedulereneros-timeseries9090TCP允许
*eneros-scheduler**拒绝

策略审计

use eneros_trust::audit::PolicyAudit;

let audit = PolicyAudit::new(&trust);

// 查询被拒绝的连接
let denied = audit.query()
    .action(Action::Deny)
    .range(now() - Duration::hours(24), now())
    .execute()?;

for entry in denied {
    println!("{:?} {} -> {} 被拒绝: {}",
        entry.timestamp, entry.source, entry.destination, entry.reason);
}

// 生成合规报告
let report = audit.compliance_report(Standard::NercCip)
    .period(Q2_2025)
    .generate()?;

改进

  • API 网关:所有 REST/GraphQL 端点强制 mTLS,移除 HTTP 明文支持
  • Raft 集群:节点间通信启用 mTLS,防止未授权节点加入
  • SCADA:IEC 104 与 IEC 61850 连接支持 TLS 封装
  • 仪表盘:前端通过 mTLS 与后端通信,WebSocket over TLS

Bug 修复

  • 修复 eneros-trust-mtls 在证书轮换期间偶发握手失败的问题(#2008)
  • 修复 eneros-trust-mesh Sidecar 注入在高并发下内存泄漏的问题(#2014)
  • 修复 eneros-trust-cert OCSP 响应缓存过期未刷新的问题(#2020)
  • 修复 eneros-trust 网络策略在策略更新时短暂全通的问题(#2026)

破坏性变更

  • 所有 HTTP 端点默认启用 mTLS:原 HTTP 端点迁移至 HTTPS,需客户端配置证书
  • RaftNode::new:新增 tls_config 参数,节点间通信必须 mTLS
  • Gateway::listen:移除明文监听,统一使用 listen_tls

性能提升

  • mTLS 握手延迟稳定在 1.7ms(新连接)/ 0.3ms(会话恢复)
  • 证书轮换零停机,热加载耗时 200ms
  • 服务网格 Sidecar 额外延迟 < 0.5ms
  • 网络策略评估延迟 < 50μs

贡献者

本版本由 27 位贡献者共同完成,提交 468 次。特别感谢:

  • @zero-trust-arch:零信任架构与策略引擎
  • @mtls-implementer:mTLS 双向认证与 TLS 1.3
  • @mesh-builder:服务网格与 Sidecar 设计
  • @cert-automation:证书自动轮换与热加载

升级指南

从 v0.19.0 升级

1. 更新依赖

# Cargo.toml
[dependencies]
eneros-trust = { version = "0.20" }
eneros-trust-mtls = { version = "0.20" }
eneros-trust-mesh = { version = "0.20" }
eneros-trust-cert = { version = "0.20" }

2. 部署内部 CA

# 部署内部证书颁发机构
eneros-ca init --endpoint https://ca.internal:8200
eneros-ca issue-root --validity 3650
eneros-ca issue-intermediate --validity 365

3. 启用零信任

# eneros.toml
[trust]
enabled = true
mtls_required = true
default_deny = true

[trust.ca]
endpoint = "https://ca.internal:8200"
token = "${CA_TOKEN}"

[trust.cert]
rotation_threshold_days = 7
rotation_check_hours = 1
key_type = "ecdsa-p256"

[trust.mesh]
enabled = true
auto_injection = true

[trust.network_policy]
enabled = true
default_deny = "both"

4. 迁移客户端为 mTLS

// v0.19.0 旧写法:明文 HTTP
let client = HttpClient::new("http://eneros-scheduler:8080")?;

// v0.20.0 新写法:mTLS HTTPS
let client = HttpClient::builder("https://eneros-scheduler:8080")
    .mtls(MtlsConfig::load("/etc/eneros/certs")?)
    .build()?;

5. 配置网络策略

建议采用「白名单」模式,先放行必要通信,再默认拒绝其他:

// 放行业务必要通信
trust.apply_network_policy(NetworkPolicy::new("business-allow")
    .ingress(Rule::allow().from(IdentitySelector::service("eneros-gateway")))
    .egress(Rule::allow().to(IdentitySelector::service("eneros-twin")))
    .egress(Rule::allow().to(IdentitySelector::service("eneros-timeseries")))
    .default_deny(Direction::Both))?;

// 默认拒绝
trust.apply_network_policy(NetworkPolicy::new("default-deny")
    .default_deny(Direction::Both))?;

6. 合规验证

启用零信任后,建议进行合规性验证,确保满足 NERC CIP 与 IEC 62443 要求:

eneros-trust verify --standard nerc-cip
eneros-trust verify --standard iec-62443
eneros-trust report --period 2025-Q2 --output compliance.pdf

零信任是 EnerOS v0.1.0 至 v0.39.0 内部迭代阶段的安全收官,至此 EnerOS 完成了从底层架构到上层安全的全栈能力建设,为 v0.40.0 首个公开发布版本奠定坚实基础。