跳到主内容

v0.15.0 版本说明

EnerOS v0.15.0

发布日期:2025年02月16日 版本代号:Guardian Git Tag:v0.15.0 支持状态:稳定(Stable) Crate 总数:38(新增 4 个) 测试用例数:5240+(新增 560)

版本概述

EnerOS v0.15.0「Guardian」是 EnerOS 在「运行安全」方向上的核心版本,本版本的核心目标是引入安全守卫系统(Safety Guard),为电力系统中的危险操作提供多层级防护,包括操作沙箱、权限审计、危险操作拦截与安全策略引擎,确保任何可能影响电网物理安全的操作在执行前均经过严格校验。

电力系统是典型的「高危环境」——一次错误的开关操作可能导致设备损坏、电网解列甚至人员伤亡。传统操作系统的权限模型仅能控制「能否执行」,无法判断「执行是否安全」。例如,一个拥有开关操作权限的调度员,可能在带负荷情况下拉开隔离开关,造成带负荷拉刀闸事故。v0.15.0 将物理安全规则内建为操作系统的「守卫层」,在所有操作执行前进行物理可行性校验,从源头杜绝电气误操作。

本版本引入了 eneros-guardian(守卫核心)、eneros-guardian-sandbox(操作沙箱)、eneros-guardian-audit(权限审计)、eneros-guardian-policy(安全策略引擎)四个新 crate。设计哲学是「安全优先于功能」——当守卫判定操作危险时,无论操作者权限多高,均会被拦截并记录,需经安全审批流程后方可执行。

关键数据

指标v0.14.0v0.15.0提升
危险操作拦截率0%100%全面覆盖
守卫校验延迟N/A12μs微秒级
沙箱隔离强度N/A硬隔离系统级
审计完整性部分完整全链路
误拦截率N/A< 0.01%极低

新特性

1. 安全守卫系统

引入 eneros-guardian crate,作为所有危险操作的统一拦截层。守卫位于内核系统调用路径上,任何 ExecuteCommand 类系统调用均需通过守卫校验后方可执行。校验内容包括物理约束、操作规程、设备状态、操作顺序等多维度。

守卫架构

use eneros_guardian::{Guardian, GuardianConfig, SafetyLevel};

let guardian = Guardian::new(GuardianConfig {
    safety_level: SafetyLevel::Strict,
    enable_sandbox: true,
    enable_audit: true,
    policy_engine: PolicyEngine::default(),
    intercept_on_violation: true,
    require_approval_for: SafetyLevel::Critical,
})?;

// 守卫自动注入到系统调用路径
ctx.install_guardian(guardian).await?;

守卫校验流程

// Agent 发起开关操作
let cmd = Command::OpenSwitch { id: 42 };
match ctx.guardian().check(&cmd).await {
    Ok(SafetyReport::Safe) => {
        // 校验通过,执行操作
        ctx.syscall(ExecuteCommand(cmd)).await?;
    }
    Ok(SafetyReport::Warning(reason)) => {
        // 风险提示,需二次确认
        log::warn!("操作风险: {}", reason);
        ctx.require_confirmation().await?;
    }
    Err(InterceptError::Dangerous(violations)) => {
        // 危险操作,被拦截
        log::error!("操作被拦截: {:?}", violations);
        ctx.audit().record_intercept(cmd, violations).await?;
    }
}

守卫校验维度

维度校验内容示例
物理约束电气定律带负荷拉刀闸
操作规程标准流程操作顺序
设备状态当前工况设备检修中
权限边界角色权限越权操作
时机校验时间窗口检修窗口外

2. 操作沙箱

引入 eneros-guardian-sandbox crate,为高风险操作提供隔离执行环境。沙箱内的操作在虚拟电网(基于孪生体)上预演,预演通过后方可作用于真实电网。沙箱采用命名空间隔离 + 资源限制,确保沙箱内操作不会影响其他工作负载。

沙箱执行

use eneros_guardian_sandbox::{Sandbox, SandboxConfig};

// 创建一个操作沙箱
let sandbox = Sandbox::new(SandboxConfig {
    twin_snapshot: twin.snapshot().await?,
    resource_limits: ResourceLimits {
        cpu: 2,
        memory: 4 * 1024 * 1024 * 1024,
        max_duration: Duration::minutes(5),
    },
    network_isolation: true,
    rollback_on_exit: true,
})?;

// 在沙箱中预演操作
let result = sandbox.run(async {
    let cmd = Command::OpenSwitch { id: 42 };
    ctx.syscall(ExecuteCommand(cmd)).await?;
    
    // 观察预演结果
    let state = ctx.twin().current_state()?;
    Ok(state)
}).await?;

// 校验预演结果
if result.is_safe() {
    // 预演安全,在真实环境执行
    ctx.syscall(ExecuteCommand(cmd)).await?;
}

沙箱隔离层级

隔离层对象机制强度
网络流量命名空间完全隔离
存储数据副本写时复制
CPU计算cgroup软隔离
内存地址空间独立堆硬隔离
孪生体电网状态快照完全隔离

3. 权限审计

引入 eneros-guardian-audit crate,对所有操作进行全链路审计记录,包括操作者、操作内容、操作时间、校验结果、执行结果。审计日志采用追加写入 + 签名链,不可篡改,满足 NERC CIP、IEC 62443 等合规要求。

审计记录

use eneros_guardian_audit::{AuditLog, AuditEntry};

let audit = AuditLog::new(AuditConfig {
    storage: AuditStorage::append_only("/var/eneros/audit"),
    hash_chain: HashChain::sha256(),
    retention: Duration::days(365),
    real_time_sync: true,
})?;

// 审计自动记录所有操作
audit.record(AuditEntry {
    timestamp: now(),
    operator: ctx.user().id,
    tenant: ctx.tenant(),
    action: "open_switch",
    target: "switch-42",
    pre_check: SafetyReport::Safe,
    execution: ExecutionResult::Success,
    duration: Duration::milliseconds(120),
}).await?;

审计检索

// 检索某设备的操作历史
let history = audit.query()
    .target("switch-42")
    .range(now() - Duration::days(30), now())
    .execute()?;

// 检索被拦截的操作
let intercepted = audit.query()
    .filter(|e| e.pre_check.is_intercepted())
    .range(now() - Duration::days(7), now())
    .execute()?;

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

4. 危险操作拦截

守卫系统内置电力行业危险操作知识库,自动识别并拦截典型危险操作。拦截规则可配置为硬拦截(拒绝执行)、软拦截(需审批)或告警(记录但放行)。

内置危险操作规则

规则 ID危险操作默认动作说明
D001带负荷拉刀闸硬拦截物理约束
D002带电压合地刀硬拦截物理约束
D003误拉运行断路器软拦截需审批
D004检修中送电硬拦截工况校验
D005越限调整出力软拦截物理约束
D006解列大电网软拦截需审批
D007跨租户操作硬拦截权限校验
D008检修窗口外操作告警规程校验

自定义拦截规则

use eneros_guardian::{Interceptor, Rule, Action};

let interceptor = Interceptor::new()
    .rule(Rule::new("D009")
        .name("低频减载前未确认")
        .condition(|ctx, cmd| {
            cmd.is_low_frequency_load_shed()
                && !ctx.confirmed()
        })
        .action(Action::SoftIntercept)
        .message("低频减载操作需先确认负荷情况"))
    .rule(Rule::new("D010")
        .name("主变过载运行超时")
        .condition(|ctx, cmd| {
            let transformer = ctx.twin().transformer(cmd.target)?;
            transformer.loading > 1.2 && transformer.overload_duration > Duration::minutes(30)
        })
        .action(Action::HardIntercept)
        .message("主变过载运行已超 30 分钟,禁止进一步增负荷"));

guardian.register_interceptor(interceptor)?;

5. 安全策略引擎

引入 eneros-guardian-policy crate,提供可配置的安全策略引擎,支持基于 OPA(Open Policy Agent)的 Rego 策略与内置 DSL 两种模式。策略可按租户、角色、设备类型等维度灵活配置。

策略定义

use eneros_guardian_policy::{PolicyEngine, Policy, Effect};

let engine = PolicyEngine::new();

// 定义一个策略:非工作时间禁止关键操作
engine.add_policy(Policy::new("non-business-hour-restrict")
    .description("非工作时间限制关键操作")
    .match_|p| {
        p.action.in_(&["open_switch", "close_switch", "adjust_generation"])
            && p.target.is_critical()
    }
    .condition(|ctx| {
        !ctx.time().is_business_hour() && !ctx.user().has_role("emergency_operator")
    })
    .effect(Effect::Deny)
    .message("非工作时间禁止关键操作,如需操作请联系值班调度员"))?;

// 定义一个策略:检修设备禁止送电
engine.add_policy(Policy::new("maintenance-no-energize")
    .match_|p| p.action == "energize"
    .condition(|ctx, p| {
        ctx.twin().equipment(p.target)?.status == EquipmentStatus::Maintenance
    })
    .effect(Effect::Deny)
    .message("设备处于检修状态,禁止送电"))?;

Rego 策略集成

use eneros_guardian_policy::opa;

// 加载 Rego 策略
let rego = r#"
package eneros.guardian

default allow = false

allow {
    input.action == "read"
    input.user.role == "operator"
}

allow {
    input.action == "dispatch"
    input.user.role == "dispatcher"
    input.target.is_critical == false
    time.is_business_hour(input.timestamp)
}
"#;

engine.load_rego("dispatcher-policy", rego)?;

// 策略评估
let decision = engine.evaluate(DecisionRequest {
    action: "dispatch",
    user: ctx.user(),
    target: &target,
    timestamp: now(),
}).await?;

match decision.effect {
    Effect::Allow => { /* 放行 */ }
    Effect::Deny => { /* 拒绝 */ }
    Effect::Audit => { /* 记录 */ }
}

改进

  • 约束引擎eneros-constraint 与守卫系统深度集成,物理约束校验自动纳入守卫流程
  • 孪生体:孪生体支持快速快照,沙箱预演开销降低 80%
  • API 网关:所有写操作 API 自动经过守卫校验
  • 可观测性:新增守卫指标,包括拦截率、校验延迟、规则命中率

Bug 修复

  • 修复 eneros-guardian 在高并发下策略评估竞态条件的问题(#1507)
  • 修复 eneros-guardian-sandbox 沙箱退出时资源未完全释放的问题(#1513)
  • 修复 eneros-guardian-audit 审计链在重启后断裂的问题(#1519)
  • 修复 eneros-guardian-policy OPA 集成在大策略集下评估超时的问题(#1525)

破坏性变更

  • syscall(ExecuteCommand):所有执行类系统调用现在会经过守卫校验,原直接执行迁移至 syscall_unchecked
  • Command::execute:返回类型从 Result<()> 改为 Result<ExecutionReport>
  • AuditLog::record:改为 async,需 .await

性能提升

  • 守卫校验延迟稳定在 12μs 以内
  • 沙箱预演开销从 800ms 降至 160ms(提升 5 倍)
  • 审计日志写入吞吐从 2 万/秒提升至 15 万/秒
  • 策略评估延迟从 2ms 降至 200μs

贡献者

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

  • @guardian-core:守卫核心与拦截机制
  • @sandbox-arch:操作沙箱与隔离设计
  • @audit-chain:审计日志与哈希链
  • @policy-engine:策略引擎与 OPA 集成

升级指南

从 v0.14.0 升级

1. 更新依赖

# Cargo.toml
[dependencies]
eneros-guardian = { version = "0.15" }
eneros-guardian-sandbox = { version = "0.15" }
eneros-guardian-audit = { version = "0.15" }
eneros-guardian-policy = { version = "0.15", features = ["opa"] }

2. 启用守卫系统

# eneros.toml
[guardian]
enabled = true
safety_level = "strict"
enable_sandbox = true
enable_audit = true

[guardian.audit]
storage = "/var/eneros/audit"
retention_days = 365
hash_chain = "sha256"

3. 适配系统调用变更

// v0.14.0 旧写法:直接执行
ctx.syscall(ExecuteCommand(cmd)).await?;

// v0.15.0 新写法:经守卫校验(默认行为)
let report = ctx.syscall(ExecuteCommand(cmd)).await?;
if report.intercepted {
    return Err(report.violations);
}

// 如需跳过守卫(不推荐,需特权)
ctx.syscall_unchecked(ExecuteCommand(cmd)).await?;

4. 配置危险操作规则

建议根据本电网实际情况,自定义危险操作拦截规则:

use eneros_guardian::{Interceptor, Rule, Action};

let interceptor = Interceptor::new()
    .rule(Rule::new("custom-001")
        .name("本电网特有危险操作")
        .condition(|ctx, cmd| { /* ... */ })
        .action(Action::HardIntercept));

guardian.register_interceptor(interceptor)?;

5. 审计合规配置

如需满足 NERC CIP 或 IEC 62443 合规要求,参考合规手册配置审计存储与保留策略,确保审计日志满足「不可篡改、长期保留、可追溯」三项要求。