强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Bubblewrap 容器入门教程 / 第 2 章 - 安装与环境配置

第 2 章:安装与环境配置

本章详细介绍 Bubblewrap 在各主流 Linux 发行版上的安装方法、内核配置要求、命名空间支持检测以及常见问题排查。


2.1 包管理器安装

各发行版安装命令

发行版 包名 安装命令
Fedora / RHEL bubblewrap sudo dnf install bubblewrap
Debian / Ubuntu bubblewrap sudo apt install bubblewrap
Arch Linux bubblewrap sudo pacman -S bubblewrap
openSUSE bubblewrap sudo zypper install bubblewrap
Gentoo sys-apps/bubblewrap sudo emerge sys-apps/bubblewrap
Alpine bubblewrap sudo apk add bubblewrap
Void Linux bubblewrap sudo xbps-install -S bubblewrap
NixOS bubblewrap environment.systemPackages 中添加

验证安装

# 检查版本
bwrap --version
# bubblewrap 0.9.0

# 查看帮助
bwrap --help

2.2 从源码编译安装

当包管理器提供的版本过旧,或需要最新特性时,可以从源码编译。

依赖项

依赖 用途 安装(Debian/Ubuntu)
libcap Linux 权能操作 libcap-dev
libseccomp seccomp 系统调用过滤 libseccomp-dev(可选)
meson 构建系统 meson
ninja 构建后端 ninja-build
docbook-xsl 文档生成 docbook-xsl(可选)
gcc / clang C 编译器 gccclang

编译步骤

# 1. 安装构建依赖(Debian/Ubuntu)
sudo apt install -y meson ninja-build libcap-dev libseccomp-dev docbook-xsl xsltproc

# 2. 克隆仓库
git clone https://github.com/containers/bubblewrap.git
cd bubblewrap

# 3. 查看可用的版本标签
git tag -l | sort -V | tail -5
# v0.8.0
# v0.9.0
# v0.10.0

# 4. 切换到稳定版本(可选)
git checkout v0.10.0

# 5. 配置构建
meson setup builddir \
  -Drequire-userns=true \
  -Dman=enabled \
  -Ddocs=disabled

# 6. 编译
ninja -C builddir

# 7. 测试(可选)
ninja -C builddir test

# 8. 安装
sudo ninja -C builddir install

# 9. 验证
which bwrap
# /usr/local/bin/bwrap

Meson 构建选项

选项 默认值 说明
require-userns false 是否要求 user namespace 支持
man auto 是否生成 man page
docs disabled 是否生成文档
selinux auto 是否启用 SELinux 支持

Fedora 特殊编译选项

Fedora 默认使用 setuid 模式安装 bwrap(需要 suid 位),以兼容不支持 user namespace 的场景:

# Fedora 默认编译(带 setuid 支持)
meson setup builddir -Drequire-userns=false

# 安装后需要设置 setuid
sudo chmod u+s /usr/bin/bwrap

2.3 内核要求

最低内核版本

功能 最低内核版本 说明
基本运行 2.6.x(setuid 模式) 不推荐,安全性差
User Namespace 3.8 非特权模式的基本要求
Mount Namespace 2.4.19 文件系统隔离
PID Namespace 2.6.19 进程隔离
Network Namespace 2.6.29 网络隔离
UTS Namespace 2.6.19 主机名隔离
Cgroup Namespace 4.6 cgroup 视图隔离
seccomp-BPF 3.5 系统调用过滤
推荐内核 >= 5.x 完整功能支持

检查当前内核版本

uname -r
# 6.1.0-23-amd64

# 查看内核编译配置中命名空间的支持情况
cat /proc/config.gz | gunzip | grep NAMESPACE
# 或
grep NAMESPACE /boot/config-$(uname -r)

2.4 命名空间支持检测

检测 User Namespace 支持

# 方法 1: 检查内核配置
grep CONFIG_USER_NS /boot/config-$(uname -r)
# CONFIG_USER_NS=y

# 方法 2: 直接测试
unshare --user --map-root-user echo "User namespace works"
# User namespace works

# 方法 3: 查看系统参数
cat /proc/sys/kernel/unprivileged_userns_clone
# 1 (表示允许非特权用户创建 user namespace)

检测所有命名空间支持

#!/bin/bash
# check-ns-support.sh - 检测命名空间支持

declare -A NAMESPACES=(
    [user]="unshare --user echo OK"
    [mount]="unshare --mount echo OK"
    [pid]="unshare --pid --fork echo OK"
    [net]="unshare --net echo OK"
    [uts]="unshare --uts echo OK"
    [cgroup]="unshare --cgroup echo OK"
    [ipc]="unshare --ipc echo OK"
)

echo "命名空间支持检测:"
echo "=================="

for ns in "${!NAMESPACES[@]}"; do
    if eval "${NAMESPACES[$ns]}" &>/dev/null; then
        printf "  %-10s: ✅ 支持\n" "$ns"
    else
        printf "  %-10s: ❌ 不支持\n" "$ns"
    fi
done

运行输出:

命名空间支持检测:
==================
  user      : ✅ 支持
  mount     : ✅ 支持
  pid       : ✅ 支持
  net       : ✅ 支持
  uts       : ✅ 支持
  cgroup    : ✅ 支持
  ipc       : ✅ 支持

2.5 权限配置

模式对比

Bubblewrap 有两种运行模式:

模式 原理 安全性 要求
User Namespace 模式 利用 user namespace 创建隔离 较高(无特权提升) 内核支持 unprivileged userns
Setuid 模式 bwrap 以 root 身份运行 较低(存在提权风险) chmod u+s /usr/bin/bwrap

启用 Unprivileged User Namespace

某些发行版默认禁用了非特权 user namespace,需要手动启用:

Debian / Ubuntu

# 检查当前设置
cat /proc/sys/kernel/unprivileged_userns_clone
# 0 表示禁用

# 临时启用
sudo sysctl kernel.unprivileged_userns_clone=1

# 永久启用
echo "kernel.unprivileged_userns_clone=1" | sudo tee /etc/sysctl.d/00-local-userns.conf
sudo sysctl --system

RHEL / CentOS / Fedora

# 检查当前设置
cat /proc/sys/user/max_user_namespaces
# 0 表示禁用

# 临时启用
sudo sysctl user.max_user_namespaces=28633

# 永久启用
echo "user.max_user_namespaces=28633" | sudo tee /etc/sysctl.d/userns.conf
sudo sysctl --system

Arch Linux

# Arch 默认启用 user namespace,无需额外配置
# 如果使用 hardened 内核,可能需要:
sudo sysctl kernel.unprivileged_userns_clone=1

使用 sysctl 安全模块限制

# 通过 sysctl 配置文件
cat /etc/sysctl.d/99-bubblewrap.conf
# 允许非特权 user namespace
kernel.unprivileged_userns_clone = 1
# 设置最大 user namespace 数量
user.max_user_namespaces = 28633

Setuid 模式配置

当 user namespace 不可用时,需要使用 setuid 模式:

# 安装 setuid 版本(通常由发行版打包完成)
sudo chmod u+s /usr/bin/bwrap

# 验证
ls -la /usr/bin/bwrap
# -rwsr-xr-x 1 root root 123456 ... /usr/bin/bwrap

⚠️ 安全警告:setuid 模式意味着 bwrap 以 root 权限运行,如果 bwrap 存在漏洞,可能导致本地提权。强烈推荐使用 user namespace 模式。


2.6 发行版特定注意事项

Fedora

# Fedora 默认使用 setuid bwrap,因为其 user namespace 策略较保守
# 检查 bwrap 是否为 setuid
stat -c '%a %U' /usr/bin/bwrap
# 4755 root

# 可选:切换到 user namespace 模式
# 1. 取消 setuid
sudo chmod u-s /usr/bin/bwrap
# 2. 启用 user namespace
sudo sysctl user.max_user_namespaces=28633
# 3. 测试
bwrap --ro-bind / / --unshare-user echo "It works"

Ubuntu(AppArmor 冲突)

Ubuntu 使用 AppArmor 对 bwrap 进行限制,可能会导致某些操作失败:

# 查看 AppArmor 对 bwrap 的策略
sudo aa-status | grep bwrap

# 如果遇到 AppArmor 拒绝(denied),可以临时切换到 complain 模式
sudo aa-complain /usr/bin/bwrap

# 或者调整 AppArmor 策略
cat /etc/apparmor.d/bwrap

Debian

# Debian 12+ 默认启用 user namespace
# 如遇到权限问题,检查:
cat /proc/sys/kernel/unprivileged_userns_clone
# 应为 1

NixOS

# configuration.nix 中添加
{ pkgs, ... }:
{
  # 启用 user namespace
  security.unprivilegedUsernsClone = true;

  # 安装 bubblewrap
  environment.systemPackages = [ pkgs.bubblewrap ];

  # NixOS 特殊:需要配置 bwrap wrapper
  programs.bwrap = {
    enable = true;
  };
}

2.7 安装验证测试

安装完成后,运行以下测试确认一切正常:

基本功能测试

#!/bin/bash
# test-bwrap-install.sh

echo "=== Bubblewrap 安装验证 ==="
echo ""

# 1. 版本检查
echo "1. 版本信息:"
bwrap --version
echo ""

# 2. 基本沙箱测试
echo "2. 基本沙箱测试:"
if bwrap --ro-bind / / --unshare-user --unshare-pid --fork echo "Sandbox OK" 2>/dev/null; then
    echo "   ✅ 基本沙箱运行正常"
else
    echo "   ❌ 基本沙箱运行失败"
fi

# 3. 文件系统隔离测试
echo "3. 文件系统隔离测试:"
SANDBOX_HOSTNAME=$(bwrap --ro-bind / / --unshare-uts -- hostname 2>/dev/null)
HOST_HOSTNAME=$(hostname)
if [ "$SANDBOX_HOSTNAME" = "$HOST_HOSTNAME" ]; then
    # UTS namespace 在只读绑定下可能共享主机名,这是正常的
    echo "   ✅ UTS 命名空间可用"
else
    echo "   ✅ UTS 命名空间已隔离: 沙箱=$SANDBOX_HOSTNAME, 宿主=$HOST_HOSTNAME"
fi

# 4. 隔离完整性测试
echo "4. 隔离完整性测试:"
if bwrap --ro-bind / / --unshare-all --proc /proc --dev /dev \
   bash -c 'echo "PID namespace: $(echo $$)"' 2>/dev/null; then
    echo "   ✅ 完整隔离测试通过"
else
    echo "   ⚠️ 部分隔离功能可能不可用"
fi

# 5. tmpfs 测试
echo "5. tmpfs 测试:"
if bwrap --ro-bind / / --tmpfs /tmp bash -c \
   'echo "test" > /tmp/sandbox_test && cat /tmp/sandbox_test && rm /tmp/sandbox_test' 2>/dev/null; then
    echo "   ✅ tmpfs 可写"
else
    echo "   ❌ tmpfs 测试失败"
fi

echo ""
echo "=== 验证完成 ==="

预期输出

=== Bubblewrap 安装验证 ===

1. 版本信息:
bubblewrap 0.9.0

2. 基本沙箱测试:
   ✅ 基本沙箱运行正常

3. 文件系统隔离测试:
   ✅ UTS 命名空间可用

4. 隔离完整性测试:
   ✅ 完整隔离测试通过

5. tmpfs 测试:
   ✅ tmpfs 可写

=== 验证完成 ===

2.8 常见问题排查

问题 1:Operation not permitted

bwrap: Creating new namespace failed: Operation not permitted

原因:user namespace 被禁用或不支持。

解决

# 检查并启用 user namespace
sudo sysctl kernel.unprivileged_userns_clone=1

# 或检查是否为 setuid 模式
ls -la /usr/bin/bwrap
# 如果没有 setuid 位且 user namespace 被禁用:
sudo chmod u+s /usr/bin/bwrap

问题 2:No space left on device

bwrap: Can't mkdir /tmp/sandbox: No space left on device

原因:tmpfs 空间不足。

解决

# 使用 --tmpfs 时指定大小
bwrap --tmpfs /tmp --size 512 ...

问题 3:AppArmor DENIED

kernel: audit: type=1400 audit(...): apparmor="DENIED" operation="..."

解决

# 查看 AppArmor 日志
sudo journalctl -k | grep apparmor | grep bwrap

# 切换 AppArmor 到 complain 模式
sudo aa-complain /usr/bin/bwrap

问题 4:mount failed

bwrap: Can't mount proc on /newroot/proc: Permission denied

解决

# 确保使用 --proc 参数而非手动 mount
bwrap --ro-bind / / --proc /proc ...

# 或检查是否存在 AppArmor/SELinux 限制
getenforce  # SELinux
sudo aa-status  # AppArmor

2.9 注意事项

⚠️ 重要提醒

  1. 不要同时使用 setuid 和 user namespace 模式:这可能产生安全风险。选择一种模式并保持一致。

  2. 发行版策略差异:不同发行版对 user namespace 的默认策略不同。Fedora 倾向于 setuid,Ubuntu 倾向于 user namespace + AppArmor。

  3. 更新内核:如果遇到命名空间相关的奇怪错误,优先考虑升级内核。

  4. Docker 中的 bwrap:在 Docker 容器内使用 bwrap 需要特殊配置(详见第 9 章)。


2.10 扩展阅读


上一章:第 1 章 - Bubblewrap 概述 | 下一章:第 3 章 - 基本用法