Linux Cgroup与Device Whitelist详解

第一部分:Cgroup 是什么?

CgroupControl Group 的缩写。它的核心功能是:对一组进程及其未来创建的子进程进行资源限制、隔离和统计。

你可以把它想象成一个"管理员",这个管理员可以给不同的"进程组"(比如"前端服务组"、"数据库组"、"用户A的容器组")分配固定的资源配额,防止某个组占用过多资源而影响到其他组,甚至整个系统。

Cgroup 主要管理和限制以下几类资源:

  1. CPU :限制进程组可以使用多少 CPU 时间片(cpu 子系统)或核心(cpuset 子系统)。

  2. 内存:限制进程组可以使用的最大内存量,包括物理内存和交换分区。

  3. I/O:限制进程组的磁盘读写带宽或 IOPS(每秒读写次数)。

  4. 网络 :虽然传统 Cgroup 不直接管理网络,但可以通过 net_cls 给进程组的网络包打上标签,再结合 tc 等工具进行流量控制。

  5. 设备访问 :这就是我们下面要讲的 Device Whitelist Controller 所负责的。

Cgroup 的层次结构:

Cgroup 采用树形层次结构。系统有一个根 Cgroup,下面可以创建子 Cgroup,子 Cgroup 可以继续划分。子 Cgroup 会继承父 Cgroup 的某些属性,并且其资源限制不能超过父 Cgroup。

为什么 Cgroup 如此重要?

它是现代容器技术(如 DockerLXCKubernetes)的基石之一。当你运行一个 Docker 容器时,Docker 会为这个容器创建一个或多个 Cgroup,来限制容器能使用的 CPU、内存等资源,从而实现多个容器在同一台主机上安全、隔离地运行。


第二部分:Device Whitelist Controller(设备白名单控制器)是干嘛用的?

参考链接:Device Whitelist Controller --- The Linux Kernel documentation

Device Whitelist Controller 是 Cgroup 众多子系统(或叫控制器)中的一个,它的名字通常简写为 cgroup devices 或对应的文件系统条目是 devices

它的核心功能非常简单且强大:控制一个 Cgroup 内的进程可以访问哪些设备节点。

在 Linux 中,一切皆文件,硬件设备也不例外(如 /dev/sda1/dev/kvm/dev/dri/card0 等)。默认情况下,一个进程如果有足够的文件系统权限,它就可以访问这些设备文件,从而操作底层硬件。

Device Whitelist Controller 的作用就是打破这个默认规则,实现更细粒度的设备访问控制。

它是如何工作的?------ "白名单" 机制

它遵循 "默认拒绝,显式允许" 的原则。

  1. 默认情况 :当一个 Cgroup 被创建时,如果没有进行任何配置,其内部的进程默认无法访问任何设备节点。这是一个非常严格的安全策略。

  2. 配置白名单 :系统管理员需要显式地在这个 Cgroup 的配置文件中写入规则,明确"允许" 该 Cgroup 内的进程访问哪些设备。

  3. 规则生效 :配置完成后,该 Cgroup 内的进程就只能访问规则中明确允许的设备,其他所有设备的访问都会被内核拒绝(即使进程是以 root 身份运行的)。

如何配置?

主要通过操作 Cgroup 文件系统中 devices 子系统下的几个文件:

  • devices.allow:写入允许访问的规则。

  • devices.deny:写入拒绝访问的规则(在白名单模式下较少使用)。

  • devices.list:列出当前生效的规则。

规则格式:
<type> <major>:<minor> <access>

  • <type>:

    • a:代表 All,所有类型(字符设备和块设备)。

    • c:代表 Character,字符设备。

    • b:代表 Block,块设备。

  • <major>:<minor> :设备的主设备号和次设备号。可以用 a 来表示所有设备(即 *:*)。

  • <access>:访问权限。

    • r:读权限。

    • w:写权限。

    • m:创建设备节点的权限(mknod)。

举个例子:

假设我们有一个 Cgroup 路径:/sys/fs/cgroup/devices/container_a/

  1. 查看当前规则

    bash

    复制代码
    cat /sys/fs/cgroup/devices/container_a/devices.list

    (初始状态下可能为空,意味着所有访问都被拒绝)

  2. 允许访问所有设备(通常用于特权容器,但很不安全):

    bash

    复制代码
    echo "a *:* rwm" > /sys/fs/cgroup/devices/container_a/devices.allow
  3. 更安全的做法:只允许访问空设备(/dev/null)和零设备(/dev/zero)

    bash

    复制代码
    # 首先,清除所有规则(如果需要的话,通常从一个干净的状态开始)
    # echo "a *:* rwm" > devices.deny # 这会拒绝所有,但默认就是拒绝的
    
    # 允许访问 /dev/null (字符设备,主次设备号为 1:3)
    echo "c 1:3 rwm" > /sys/fs/cgroup/devices/container_a/devices.allow
    
    # 允许访问 /dev/zero (字符设备,主次设备号为 1:5)
    echo "c 1:5 rwm" > /sys/fs/cgroup/devices/container_a/devices.allow
    
    # 现在再查看规则列表
    cat /sys/fs/cgroup/devices/container_a/devices.list

    输出会是:

    text

    复制代码
    c 1:3 rwm
    c 1:5 rwm

    现在,container_a 这个 Cgroup 里的进程只能读写 /dev/null/dev/zero,尝试访问 /dev/sda1 等设备都会失败。

总结与关系

特性 Cgroup(控制组) Device Whitelist Controller(设备白名单控制器)
角色 资源管理的框架/管理者 Cgroup 框架下的一个具体功能模块
目的 限制和隔离进程组的资源(CPU、内存、IO等) 限制和隔离进程组对设备文件的访问
关系 整体 部分(子系统)
重要性 容器技术的基石,实现资源隔离 容器安全的关键,防止容器内的进程逃逸并访问宿主机敏感硬件

简单来说:

  • Cgroup 是一个大管家,负责给不同的"家庭"(进程组)分配预算(CPU、内存等)。

  • Device Whitelist Controller 是这个大管家手下一个专门管"钥匙"的保安。它决定每个"家庭"的成员可以进入哪些"房间"(设备),其他的房间一律禁止入内。

在 Docker 等容器引擎中,当你使用 --device 参数来将宿主机设备挂载到容器内时,或者当你使用 --privileged 参数时,底层就是在操作这个 Cgroup 的 devices 子系统,来动态地修改容器的设备访问白名单。

相关推荐
染指11104 小时前
36.渗透-端口
linux·运维·服务器
takashi_void4 小时前
如何在本地部署大语言模型(Windows,Mac,Linux)三系统教程
linux·人工智能·windows·macos·语言模型·nlp
EndingCoder4 小时前
WebSocket实时通信:Socket.io
服务器·javascript·网络·websocket·网络协议·node.js
勤源科技4 小时前
全链路智能运维中的多模态数据融合与语义对齐技术
运维
大聪明-PLUS4 小时前
QEMU:如何组织与 I2C 设备的透明交互
linux·嵌入式·arm·smarc
IsWillian5 小时前
OpenSSL生成自签名通配符证书
运维·服务器
一念&5 小时前
每日一个网络知识点:网络层NAT
服务器·网络·php
QWQ___qwq5 小时前
Swift中.gesture的用法
服务器·microsoft·swift
sulikey5 小时前
【Linux权限机制深入理解】为何没有目录写权限仍能修改文件权限?
linux·运维·笔记·ubuntu·centos