SigmaOS多租户安全隔离机制深度分析

概述

SigmaOS作为一个实验性云操作系统,确实没有使用传统的系统虚拟化技术(如KVM、Xen等),而是采用了一套多层次的轻量级隔离机制来实现多租户环境下的安全隔离。这种设计在保证安全性的同时,显著降低了资源开销和启动延迟。

核心隔离机制

1. Realm-based逻辑隔离 (最高层)

1.1 Realm概念

// realm/srv/srv.go
type Realm struct {
    sync.Mutex
    named                    *proc.Proc // 每个realm的命名服务
    perRealmKernelSubsystems []*Subsystem // 每个realm的内核子系统
    sc                       *sigmaclnt.SigmaClnt
}

Realm是SigmaOS中最重要的隔离抽象,类似于传统云平台中的租户(Tenant)概念:

1.2 Realm创建流程

func (rm *RealmSrv) Make(ctx fs.CtxI, req proto.MakeReq, res *proto.MakeRep) error {
    rid := sp.Trealm(req.Realm)
    r := newRealm()

    // 1. 为realm创建独立的named服务
    p := proc.NewProc("named", []string{req.Realm})
    p.SetRealmSwitch(rid) // 设置realm切换

    // 2. 创建独立的网络
    cmd := exec.Command(MKNET, req.Network)

    // 3. 启动per-realm内核子系统
    rm.bootPerRealmKernelSubsystems(r, rid, sp.S3REL, req.GetNumS3())
    rm.bootPerRealmKernelSubsystems(r, rid, sp.UXREL, req.GetNumUX())
}

1.3 网络隔离

# create-net.sh
if ! docker network ls | grep -q "$1"; then
    docker network create --driver overlay $1 --attachable    
fi

每个realm创建独立的Docker overlay网络,实现网络层面的完全隔离。

2. 容器级隔离 (中间层)

2.1 Linux命名空间隔离

// scontainer/scontainer.go
cmd.SysProcAttr = &syscall.SysProcAttr{
    Cloneflags: syscall.CLONE_NEWUTS |    // UTS命名空间(主机名)
               syscall.CLONE_NEWIPC |     // IPC命名空间(进程间通信)
               syscall.CLONE_NEWPID |     // PID命名空间(进程ID)
               syscall.CLONE_NEWNS,       // Mount命名空间(文件系统)
}

关键特点: - PID隔离: 每个容器有独立的进程ID空间 - 文件系统隔离: 独立的mount命名空间 - IPC隔离: 进程间通信隔离 - UTS隔离: 主机名和域名隔离

2.2 Docker容器封装

// dcontainer/dcontainer.go
func StartDockerContainer(p *proc.Proc, mem proc.Tmem, mcpu proc.Tmcpu, 
                         kernelID string, ip string, net string) (*DContainer, error) {

    // 创建容器配置
    config := &container.Config{
        Image: sp.TARGET_IMAGE,
        Cmd:   cmd,
        Env:   p.GetEnv(),
    }

    // 主机配置 - 资源限制
    hostConfig := &container.HostConfig{
        Memory:     int64(mem) * 1024 * 1024, // 内存限制
        NanoCPUs:   int64(mcpu) * 1000000,    // CPU限制
        NetworkMode: container.NetworkMode(net), // 网络模式
    }
}

3. 进程级安全加固 (最底层)

3.1 Seccomp系统调用过滤

// rs/uproc-trampoline/src/main.rs
fn seccomp_proc(dialproxy: String) -> Result<(), Box<dyn std::error::Error>> {
    use libseccomp::*;

    // 创建seccomp过滤器,默认拒绝所有系统调用
    let mut filter = ScmpFilterContext::new_filter(ScmpAction::Errno(1))?;

    // 只允许安全的系统调用
    let allowed_syscalls = vec![
        ScmpSyscall::new("read"),
        ScmpSyscall::new("write"),
        ScmpSyscall::new("open"),
        ScmpSyscall::new("close"),
        ScmpSyscall::new("mmap"),
        ScmpSyscall::new("munmap"),
        ScmpSyscall::new("brk"),
        ScmpSyscall::new("rt_sigaction"),
        ScmpSyscall::new("rt_sigprocmask"),
        ScmpSyscall::new("rt_sigreturn"),
        ScmpSyscall::new("ioctl"),
        ScmpSyscall::new("pread64"),
        ScmpSyscall::new("pwrite64"),
        ScmpSyscall::new("readv"),
        ScmpSyscall::new("writev"),
        ScmpSyscall::new("access"),
        ScmpSyscall::new("pipe"),
        ScmpSyscall::new("select"),
        ScmpSyscall::new("sched_yield"),
        ScmpSyscall::new("mremap"),
        ScmpSyscall::new("msync"),
        ScmpSyscall::new("mincore"),
        ScmpSyscall::new("madvise"),
        // ... 更多允许的系统调用
    ];

    // 应用过滤器
    filter.load()?;
}

Seccomp机制的作用: - 系统调用白名单: 只允许应用使用预定义的安全系统调用 - 攻击面缩减: 大幅减少可被利用的内核接口 - 零开销: 在内核层面进行过滤,性能影响极小

3.2 Linux Capabilities权限控制

// 移除所有危险的capabilities
let dangerous_caps = vec![
    Capability::CAP_CHOWN,           // 改变文件所有者
    Capability::CAP_DAC_OVERRIDE,    // 绕过文件权限检查
    Capability::CAP_FSETID,          // 设置文件setuid/setgid位
    Capability::CAP_FOWNER,          // 绕过文件所有者检查
    Capability::CAP_NET_RAW,         // 使用原始套接字
    Capability::CAP_SETGID,          // 设置进程组ID
    Capability::CAP_SETUID,          // 设置用户ID
    Capability::CAP_SETFCAP,         // 设置文件capabilities
    Capability::CAP_SETPCAP,         // 设置进程capabilities
    Capability::CAP_NET_BIND_SERVICE,// 绑定特权端口
    Capability::CAP_SYS_CHROOT,      // 使用chroot
    Capability::CAP_KILL,            // 发送信号给其他进程
    Capability::CAP_AUDIT_WRITE,     // 写入审计日志
];

// 清除所有capabilities
caps::clear(None, CapSet::Effective)?;
caps::clear(None, CapSet::Permitted)?;
caps::clear(None, CapSet::Inheritable)?;

3.3 AppArmor强制访问控制

pub fn apply_apparmor(profile: &str) -> Result<(), Box<dyn std::error::Error>> {
    fs::write("/proc/self/attr/apparmor/exec", format!("exec {profile}"))?;
    Ok(())
}

// 在uproc-trampoline中应用
if aa {
    apply_apparmor("sigmaos-uproc").expect("apparmor failed");
}

AppArmor配置: - 文件系统访问控制: 限制进程只能访问指定的文件和目录 - 网络访问控制: 控制网络连接和端口绑定 - 系统资源访问: 限制对系统设备和特殊文件的访问

4. 资源隔离与限制

4.1 CGroup v2资源控制

// dcontainer/cgroup/manager.go
func (cmgr *CgroupMgr) SetMemoryLimit(cgroupPath string, membytes int64, memswap int64) error {
    ps := []string{
        filepath.Join(cgroupPath, "memory.max"),      // 内存限制
        filepath.Join(cgroupPath, "memory.swap.max"), // 交换空间限制
    }
    vals := []int64{membytes, memswap}

    for i := range ps {
        err := cmgr.cfs.writeFile(ps[i], uint64(vals[i]))
        if err != nil {
            return fmt.Errorf("Error setting memory limit: %v", err)
        }
    }
}

func (cmgr *CgroupMgr) SetCPUShares(cgroupPath string, n int64) error {
    // 设置CPU权重
    err := cmgr.cfs.writeFile(filepath.Join(cgroupPath, "cpu.weight"), uint64(n))
    return err
}

4.2 Realm级别的公平性保证

// realm/srv/srv.go
func (rm *RealmSrv) enforceResourcePolicy() {
    for {
        // 1. 获取各realm的资源使用情况
        running, err := rm.sd.GetRunningProcs(sp.Conf.Realm.N_SAMPLE)
        resourceUsage := rm.realmResourceUsage(running)

        // 2. 识别资源饥饿的realm
        maxRealm, starvedRealms := findStarvedRealms(resourceUsage)

        // 3. 检查队列积压情况
        realmQLens, err := rm.be.GetQueueStats(sp.Conf.Realm.N_SAMPLE)
        if queueBuildup(starvedRealms, realmQLens) {
            // 4. 选择受害者进程并驱逐
            victim := selectVictim(running[maxRealm])
            rm.sc.EvictRealmProc(victim.GetPid(), victim.GetKernelID())
        }
    }
}

5. 权限与访问控制

5.1 基于Principal的身份认证

// sigmap/principal.go
type Tprincipal struct {
    IDStr    string // Principal ID
    RealmStr string // 所属Realm
}

func NewPrincipal(id TprincipalID, realm Trealm) *Tprincipal {
    return &Tprincipal{
        IDStr:    id.String(),
        RealmStr: realm.String(),
    }
}

5.2 路径级访问控制

// spproto/srv/attach.go
func AttachAllowAllPrincipalsSelectPaths(pns []string) AttachAuthF {
    allowed := make(map[string]bool)
    for _, d := range pns {
        allowed[d] = true
    }

    return func(p *sp.Tprincipal, pn string) error {
        if p.GetRealm() == sp.ROOTREALM {
            // Root realm可以访问任何路径
            return nil
        }
        if allowed[pn] {
            // 允许访问指定路径
            return nil
        }
        // 拒绝未授权的访问
        return fmt.Errorf("Unauthorized attach from %v to %v", p, pn)
    }
}

安全隔离架构图

graph TB
    subgraph "Realm A (租户A)"
        A1[Named Service A]
        A2[App Processes A]
        A3[Network A]
        A4[File System A]
    end

    subgraph "Realm B (租户B)"
        B1[Named Service B]
        B2[App Processes B]
        B3[Network B]
        B4[File System B]
    end

    subgraph "Container Layer"
        C1[Linux Namespaces]
        C2[Docker Containers]
        C3[CGroup v2]
    end

    subgraph "Security Layer"
        S1[Seccomp Filters]
        S2[AppArmor Profiles]
        S3[Capabilities Drop]
        S4[uproc-trampoline]
    end

    subgraph "Hardware"
        H1[CPU]
        H2[Memory]
        H3[Network]
        H4[Storage]
    end

    A2 --> C1
    B2 --> C1
    C1 --> S1
    C2 --> S2
    C3 --> S3
    S4 --> H1
    S4 --> H2
    S4 --> H3
    S4 --> H4

    A3 -.->|隔离| B3
    A4 -.->|隔离| B4

多层防护机制

第一层:Realm逻辑隔离

第二层:容器物理隔离

第三层:进程安全加固

第四层:资源配额控制

与传统虚拟化的对比

特性 SigmaOS轻量级隔离 传统虚拟化
启动时间 毫秒级 秒到分钟级
资源开销 极低 (共享内核) 高 (独立OS)
隔离强度 强 (多层防护) 最强 (硬件级)
密度 极高 中等
管理复杂度 中等
安全性 最高

安全威胁模型与防护

1. 容器逃逸防护

2. 资源耗尽攻击防护

3. 侧信道攻击缓解

4. 权限提升防护

性能优势

1. 启动延迟分析

传统VM启动: 10-60
Docker容器: 1-5
SigmaOS进程: 10-100毫秒

2. 资源利用率

3. 扩展性

总结

SigmaOS通过创新的多层次轻量级隔离机制,在不使用传统虚拟化的情况下,实现了强大的多租户安全隔离:

  1. Realm系统提供了租户级别的逻辑隔离
  2. 容器技术提供了进程级别的物理隔离
  3. 安全加固提供了系统调用和权限级别的防护
  4. 资源控制提供了公平和可控的资源分配

这种设计在保证安全性的同时,显著提升了系统的性能、密度和响应速度,特别适合云原生和边缘计算场景。虽然在某些极端安全要求的场景下可能不如硬件虚拟化,但对于大多数云计算工作负载来说,这种轻量级隔离机制提供了最佳的性能-安全平衡点。