云原生集群管理容器编排任务调度【免费下载链接】mesosApache Mesos项目地址https://gitcode.com/gh_mirrors/meso/mesos点击查看免费下载Apache Mesos 的linux/seccompisolator 为通过 Mesos Containerizer 启动的容器安装 Linux Seccomp 过滤器通过白名单方式过滤系统调用syscall来缩小容器进程可触达的内核攻击面。本文基于仓库中的 linux-seccomp.md 文档结合 isolator 实现、过滤器封装 和集成测试 源码系统讲解 Seccomp 配置文件的编写、Agent 与 Task 两级配置方式以及过滤器从解析到加载进内核的完整调用链。读完本文你可以独立编写与校验一份 Seccomp profile并将其部署到 Mesos Agent 中为全部或部分容器启用系统调用过滤。1. Seccomp 过滤器与隔离器的定位Seccomp filter 通过过滤特定系统调用为 Linux 内核提供一层攻击面收敛机制要求 Linux 内核 3.5 或更新版本。Seccomp filter 由一份Seccomp profile定义该 profile 必须与 Docker 的 Seccomp profile 格式兼容因此可以直接复用 Docker 社区维护的默认 profile 作为起点。仓库内提供的示例文件是 docs/examples/seccomp_default.json。注意Mesos Containerizer 使用了pivot_root系统调用切换根文件系统因此该调用必须出现在 Seccomp profile 中。通常 Docker 默认 profile 里只列出了chroot需要将pivot_root追加到同一个数组中即names: [chroot, pivot_root]否则容器将无法正常启动。仓库的示例 profile 与集成测试使用的 profile 都已包含该调用见 linux_seccomp_isolator_tests.cpp 第 705 行附近的pivot_root条目。从源码结构看linux/seccomp与cgroups/*、namespaces/*等一样属于 Mesos Containerizer 的 isolator 插件isolator 负责在容器生命周期中执行某一项隔离操作这里对应的就是为容器进程安装 seccomp filter。该 isolator 声明同时支持嵌套容器与独立容器supportsNesting()与supportsStandalone()均返回true见 isolators/linux/seccomp.cpp。1.1 构建前提需要显式启用编译选项从源码结构看该 isolator 并非默认编入 Agent。在 cmake/CompilationConfigure.cmake 中编译选项ENABLE_SECCOMP_ISOLATOR的描述即为 Whether to enablelinux/seccompisolator且默认值为 FALSE启用后 src/CMakeLists.txt 会把linux/seccomp/seccomp.cpp、seccomp_parser.cpp与 isolator 源文件加入编译并链接libseccomp库可使用系统安装的 libseccomp见 cmake/CompilationConfigure.cmake 中的UNBUNDLED_LIBSECCOMP选项。因此使用前的适用前提是在 Linux 上以 root 权限运行 Agent内核支持 seccomp filter≥ 3.5编译 Mesos 时打开ENABLE_SECCOMP_ISOLATOR或等价地构建了对应发行版包。2. Agent 级配置启动参数与默认 profile2.1 三个关键启动参数Linux Seccomp isolator 仅在 Agent 的--isolation标志包含linux/seccomp时才会被加载。该 isolator 需要 root 权限才能安装过滤器原因是为无特权用户安装 seccomp filter 需要设置no_new_privs位而这会带来副作用例如容器内以非特权用户运行ping、sudo等 set-user-ID 二进制会失败。参数含义是否必填--isolation隔离机制列表需包含linux/seccomp可与其他 isolator 逗号拼接是--seccomp_config_dir存放 Seccomp profile 文件的目录路径启用 isolator 时必填--seccomp_profile_name默认 Seccomp profile 文件名相对于--seccomp_config_dir的路径应用于所有 Mesos 容器。省略该标志则不定义默认 profile即默认不应用任何 Seccomp 过滤否以上行为均可在源码中印证isolator 的工厂函数LinuxSeccompIsolatorProcess::create首先校验geteuid() ! 0即报 Linux Seccomp isolator requires root permissions随后用prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, nullptr)探测内核支持返回-1且errno EFAULT表示支持--seccomp_config_dir缺失时直接返回错误 Missing required--seccomp_config_dirflag只有设置了--seccomp_profile_name时才会读取并解析默认 profile见 isolators/linux/seccomp.cpp。参数在 src/slave/flags.cpp 中注册其中对--seccomp_profile_name的说明明确标注 profile must be compatible with the Docker Seccomp profile format。一个典型的 Agent 启动命令如下sudo mesos-agent --mastermaster ip --ipagent ip \ --work_dir/var/lib/mesos \ --isolationlinux/seccomp[,other isolation flags] \ --seccomp_config_dir/etc/mesos/seccomp \ --seccomp_profile_namedefault.json2.2 默认 profile 的加载时机从 isolators/linux/seccomp.cpp 可以看到Agent 启动时解析seccomp_config_dir/seccomp_profile_name指向的文件解析失败如 profile 内容非法会导致 isolator 初始化失败、Agent 无法带该 isolator 启动。集成测试ROOT_InvalidDefaultProfile验证了这一点——喂入一个空对象{}作为 profile 时MesosContainerizer::create返回包含 Failed to parse Seccomp profile 的错误见 linux_seccomp_isolator_tests.cpp。3. Seccomp profile 文件结构与字段详解Mesos 的 profile 解析器 src/linux/seccomp/seccomp_parser.cpp 将 Docker 格式 JSON 反序列化为内部 protobuf 类型 ContainerSeccompProfile因此 profile 中各字段与该 protobuf 一一对应。3.1 顶层字段以仓库示例 docs/examples/seccomp_default.json 为参照profile 顶层包含三部分defaultAction必填未命中任何显式规则时的默认动作。取值必须带SCMP_前缀解析器会剥离前缀后按 protobuf 枚举解析见 seccomp_parser.cpp 的parseSyscallAction。支持的动作枚举为SCMP_ACT_KILL、SCMP_ACT_TRAP、SCMP_ACT_ERRNO、SCMP_ACT_TRACE、SCMP_ACT_ALLOW。示例 profile 使用defaultAction: SCMP_ACT_ERRNO即默认拒绝并返回 EPERNO 错误的白名单模式。archMap必填架构映射数组每项含architecture如SCMP_ARCH_X86_64与subArchitectures数组如SCMP_ARCH_X86、SCMP_ARCH_X32。解析器parseArchMap会调用SeccompFilter::nativeArch过滤出与当前宿主机原生架构匹配的项仅将匹配项及其子架构写入 profile 的architectures字段见 seccomp_parser.cpp不匹配的架构条目被安全忽略这就是 Docker 通用 profile 可以直接用于 Mesos 的原因。syscalls必填规则数组每项定义一组系统调用及其动作字段如下names系统调用名列表如[chroot, pivot_root]非空action命中时的动作取值同defaultActionargs参数级比较规则可为null或数组。每项包含index第几个参数、op比较运算符、value、valueTwo四个字段。运算符枚举有CMP_NE、CMP_LT、CMP_LE、CMP_EQ、CMP_GE、CMP_GT、CMP_MASKED_EQ掩码相等先对参数做位与再比较includes/excludes规则过滤条件可含arches架构列表与caps以CAP_前缀书写的 Linux capability 列表如CAP_SYS_ADMIN。3.2 动作、架构与运算符的完整枚举内部 protobuf include/mesos/seccomp/seccomp.proto 与 libseccomp 的映射实现在 src/linux/seccomp/seccomp.cpp 中类别取值libseccomp 映射ActionACT_KILL/ACT_TRAP/ACT_ERRNO/ACT_TRACE/ACT_ALLOWSCMP_ACT_KILL/SCMP_ACT_TRAP/SCMP_ACT_ERRNO(EPERM)/SCMP_ACT_TRACE(EPERM)/SCMP_ACT_ALLOW见 seccomp.cppArchitectureARCH_X86、ARCH_X86_64、ARCH_X32、ARCH_ARM、ARCH_AARCH64、ARCH_MIPS、ARCH_MIPSEL、ARCH_MIPS64、ARCH_MIPSEL64、ARCH_MIPS64N32、ARCH_MIPSEL64N32、ARCH_PPC、ARCH_PPC64LE、ARCH_S390、ARCH_S390XSCMP_ARCH_*常量见 seccomp.cppArg OperatorCMP_NE/CMP_LT/CMP_LE/CMP_EQ/CMP_GE/CMP_GT/CMP_MASKED_EQSCMP_CMP_*常量见 seccomp.cpp3.3 includes/excludes 的两阶段过滤Docker profile 的includes/excludes同时支持按架构与按 capability 过滤规则。Mesos 解析器采用两阶段处理见 seccomp_parser.cpp 中的注释架构过滤在解析期完成解析时若includes.arches列出的架构与宿主机原生架构都不匹配该规则直接省略若excludes.arches匹配当前架构规则同样省略capability 过滤推迟到容器启动时完成因为解析 profile 时尚不知道容器进程将获得哪些 capabilities解析器只把caps列表存入includes/excludes字段留待 launcher 阶段处理。ROOT_MissingConfigDir、ROOT_InvalidDefaultProfile之外的解析细节均可在上述源码中找到对应分支。4. Task 级配置按容器覆盖或禁用 Seccomp默认 profile 应用于全部 Mesos 容器但框架可以为单个任务做覆盖或豁免。任务需在ContainerInfo的LinuxInfo字段的Seccomp子消息中声明所需配置该消息定义见 include/mesos/mesos.protomessage SeccompInfo { // 相对于 --seccomp_config_dir 的 profile 文件名 optional string profile_name 1; // 为 true 时容器不应用 Seccomp // 此时不得同时指定 profile_name optional bool unconfined 2; }由此得出三种任务级语义实现见 isolators/linux/seccomp.cpp 的prepare方法指定profile_name为该容器加载seccomp_config_dir/profile_name指向的 profile替代 Agent 默认值。若文件不存在或解析失败容器启动失败——测试ROOT_SECCOMP_LaunchWithOverriddenNonExistentProfile验证了设置不存在的 profileabsent会导致launch失败见 linux_seccomp_isolator_tests.cpp指定unconfined true该容器不安装任何 Seccomp 过滤器日志会输出 Seccomp is not applied to container两者都不指定仅设置了Seccomp消息本身prepare返回 Missing Seccomp profile name 错误同时设置unconfined true与profile_name也是非法配置会报 profile_name given even though unconfined Seccomp setting is enabled。例如Agent 以默认 profile 启动时框架只需在对应任务的ContainerInfo.LinuxInfo.Seccomp中设置unconfined true即可为单个任务关闭 Seccomp 过滤。5. 过滤器如何进入内核源码级调用链从 Agent 决策到内核生效完整链路如下。5.1 Isolator 决策阶段prepareMesosContainerizer启动容器前会调用各 isolator 的prepare。linux/seccompisolator 在 isolators/linux/seccomp.cpp 中按任务配置 → Agent 默认值的优先级选出 profile将其 protobuf 拷贝进ContainerLaunchInfo.seccomp_profile并打印 Using Seccomp profile for container 。5.2 Profile 校验创建即预演parseProfileseccomp_parser.cpp在解析完成后会预先构造一次完整的 libseccomp 过滤器SeccompFilter::create做校验任何未知动作、未知架构、未识别的系统调用名都会在此以错误形式暴露而不是等到容器运行期。这意味着默认 profile 在 Agent 启动时、任务级 profile 在容器 prepare 时都会经历一次干跑验证。5.3 Launcher 阶段过滤规则与 capabilities 联动真正seccomp_load的时机在 Linux launcher 的容器准备流程中。src/slave/containerizer/mesos/launch.cpp 里若launchInfo携带 seccomp profile读取当前进程的 capabilities并根据effective/bounding配置calculateCapabilities计算出容器进程最终的能力集合调用SeccompFilter::create(profile, capabilities)构建过滤器filter-load()将其加载进内核失败则容器启动失败过滤器加载发生在setuid/setgid切换用户之前切换用户逻辑在 launch.cpp 的后续位置保证过滤器以正确的权限上下文安装。SeccompFilter::create的核心逻辑在 src/linux/seccomp/seccomp.cpp以 profile 的default_action调用seccomp_init初始化上下文显式关闭no_new_privs位seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, 0)与 Docker daemon 的做法一致——前提是 Agent 以 root持有CAP_SYS_ADMIN运行否则非特权容器进程将无法运行 set-user-ID 程序源码注释说明了这一取舍见 seccomp.cpp逐个添加architectures重复架构-EEXIST仅记日志不视为致命错误对每条 syscall 规则先做 capability 过滤若规则的includes.capabilities不是容器 bounding set 的子集则跳过若excludes.capabilities与 bounding set 有交集则跳过见 seccomp.cpp通过seccomp_syscall_resolve_name把系统调用名解析为编号未知名称报错 Unrecognized syscall 带参数的规则走seccomp_rule_add_array否则走seccomp_rule_addload()最终调用seccomp_load提交给内核见 seccomp.cpp。6. 行为验证集成测试给出的可复现证据src/tests/containerizer/linux_seccomp_isolator_tests.cpp 使用一份改造自 Docker 默认 profile 的测试 profile同样放开了pivot_root在真实启动容器的前提下覆盖了关键行为可作为运维排障时预期行为的权威参照测试验证内容ROOT_MissingConfigDir未设置seccomp_config_dir时创建 containerizer 报错 Missing required--seccomp_config_dirflagROOT_InvalidDefaultProfile默认 profile 非法如{}时 containerizer 创建失败错误含 Failed to parse Seccomp profileROOT_SECCOMP_LaunchWithDefaultProfile默认 profile 生效时id env uname hostname等命令正常执行、退出码为 0白名单足够宽ROOT_SECCOMP_LaunchWithUnameDisabledprofile 中把uname标记为SCMP_ACT_ERRNO后运行uname的容器退出码非 0——内核按规则拦截了该系统调用ROOT_SECCOMP_LaunchWithSeccompDisabled任务级unconfined true时同一份禁用uname的默认 profile 不再影响该容器ROOT_SECCOMP_LaunchWithOverriddenProfile任务级profile_name成功覆盖 Agent 默认 profileROOT_SECCOMP_LaunchWithOverriddenNonExistentProfile覆盖指向不存在的 profile 时容器启动失败相关代码入口见 linux_seccomp_isolator_tests.cpp其中LaunchWithUnameDisabled用的最小 profiledefaultAction: SCMP_ACT_ALLOW 单条uname - SCMP_ACT_ERRNO规则也是编写自定义 profile 的一个简洁模板。7. 配置与排障小结加载条件--isolation含linux/seccomp Agent 以 root 运行 编译时启用ENABLE_SECCOMP_ISOLATOR三者缺一isolator 不会出现或不可用。目录与命名--seccomp_profile_name是相对于--seccomp_config_dir的路径如default.json任务级SeccompInfo.profile_name同理两者都必须指向可解析的 Docker 格式 JSON 文件。pivot_root必留从 Docker 复制 profile 时务必把pivot_root并入chroot所在的names数组否则 Mesos Containerizer 切换根文件系统会被过滤器拦截。unconfined与profile_name互斥二者同现会直接导致容器准备失败。规则不生效的排查方向确认架构条目与宿主机匹配不匹配的架构及其子架构会被静默忽略确认 capability 过滤条件includes非 bounding 子集、excludes与 bounding 相交都会使规则被跳过确认系统调用名能被当前 libseccomp 解析未知名称在 prepare 阶段即报错。适用边界该 isolator 仅对 Mesos Containerizer 的容器有效且仅在 Linux 平台可用它对容器内所有进程含 executor 与任务进程统一生效因为过滤器在 launcher 切换用户前加载到容器准备进程中并随fork/exec继承。参考文件汇总linux-seccomp.md、seccomp_default.json、isolators/linux/seccomp.cpp、linux/seccomp/seccomp.cpp、linux/seccomp/seccomp_parser.cpp、include/mesos/seccomp/seccomp.proto、include/mesos/mesos.proto、slave/containerizer/mesos/launch.cpp、slave/flags.cpp、tests/containerizer/linux_seccomp_isolator_tests.cpp。赞分享云原生集群管理容器编排任务调度【免费下载链接】mesosApache Mesos项目地址https://gitcode.com/gh_mirrors/meso/mesos点击查看免费下载相关推荐rkt Seccomp 隔离器实战指南用系统调用过滤加固 Linux 容器rkt Seccomp 隔离器实战指南用系统调用过滤加固 Linux 容器 导读 seccompSECure COMputing是 Linux 内核提供容器运行时云原生网络CANN社区项目提交规范完整指南避免常见错误CANN社区项目提交规范完整指南避免常见错误 CANN社区项目提交规范是确保代码质量、协作效率和项目可维护性的关键环节。本文将详细介绍CANN社区项目的提交规示例工程CANNAscend终极指南Docker容器安全配置与seccomp系统调用过滤终极指南Docker容器安全配置与seccomp系统调用过滤 Docker容器技术为Jupyter应用提供了便捷的部署方式但安全配置始终是生产环境中不可忽视云原生开发工具数据科学上一篇如何免费突破网盘下载限制终极网盘直链下载助手完整指南下一篇阴阳师自动化脚本终极指南告别繁琐日常每天节省2.5小时游戏时间创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?