LXC 3.2.1 已发布¶
2019 年 7 月 24 日
简介¶
LXC 团队很高兴地宣布发布 LXC 3.2.1!
由于 3.2.0 版本发布过程中的问题,我们最终不得不立即发布 3.2.1 版本,修复了 configure.ac
文件中标识版本为稳定的问题。
新功能¶
seccomp:支持将系统调用转发到用户空间¶
较新的内核允许 seccomp 将拦截的系统调用转发到专用的文件描述符。这些消息可以被读取,系统调用参数可以被检查,如果发现安全,具有足够权限的用户空间进程可以执行内核通常为容器执行的操作。
LXC 引入了一个新协议来发送和接收消息到另一个进程。用户可以通过 lxc.seccomp.notify.proxy
指定一个 unix 套接字地址,格式为 unix:<path>
,LXC 将把拦截的系统调用转发到该地址,并等待适当的响应。
用户可以通过 lxc.seccomp.notify.cookie
设置一个 cookie,LXC 将将其发送回读取转发系统调用的进程。这将例如允许监听进程识别哪个容器发送了消息。
借助此功能,LXD 例如支持通过通常在容器中禁止的 mknod()
和 mknodat()
系统调用创建设备节点,以用于一组定义明确的安全设备。
添加 lxc.seccomp.allow_nesting
配置键¶
此版本添加了 lxc.seccomp.allow_nesting api 扩展。如果 lxc.seccomp.allow_nesting
设置为 1,则 seccomp 配置文件将被叠加。这样,嵌套容器就可以在其外部容器可能应用的策略之上加载自己的 seccomp 策略。
网络:添加 IPVLAN 支持¶
LXC 已获得 IPVLAN 支持。以下是如何设置网络的示例
lxc.net[i].type=ipvlan lxc.net[i].ipvlan.mode=[l3|l3s|l2] (defaults to l3) lxc.net[i].ipvlan.flags=[bridge|private|vepa] (defaults to bridge) lxc.net[i].link=eth0 lxc.net[i].flags=up
网络:添加第 2 层(ARP/NDP)代理模式¶
LXC 现在支持第 2 层 ARP/NDP 代理模式。可以使用以下方法启用它
lxc.net.[i].l2proxy = [0,1] (defaults to 0)
网络:添加网关设备路由模式¶
LXC 现在支持使用 dev
值指定 lxc.net.[i].ipv4.gateway
和/或 lxc.net.[i].ipv6.gateway
。这将导致 LXC 设置设备路由作为默认网关。
网络:添加对静态路由的支持¶
此版本引入了两个新的配置键
lxc.net.[i].veth.ipv4.route lxc.net.[i].veth.ipv6.route
允许用户在 veth 类型接口上设置静态路由。
网络:添加路由器 veth 模式¶
LXC 已获得 veth 网络的新路由器模式。这种“路由器”模式将通过在主机上添加指向容器主机端 veth 接口的容器 IP 的静态路由来配置主机作为容器的路由器。它还会添加主机链路接口 IP 或主机端 veth 接口上的静态设置 IP 的静态 IP 代理条目,以提供容器到主机的网关。
以下是如何设置网络的示例
lxc.net.0.type = veth lxc.net.0.veth.mode = router lxc.net.0.link = eth0 lxc.net.0.flags = up lxc.net.0.ipv4.address = 192.168.1.x/32 lxc.net.0.ipv6.address = 2a02:xxx:xxx:1::x/128 lxc.net.0.ipv4.gateway = auto lxc.net.0.ipv6.gateway = auto lxc.net.0.link = host-eth0 lxc.net.0.l2proxy = 1
这提供了一种类似 ipvlan 的网络模式,具有以下特性
- 在较旧的内核上工作。
- 使用主机的路由表(和 netfilter 规则)来路由数据包(可能从不同的接口或容器之间),与 ipvlan 不同。
- 防止容器更改其 IP。
- 防止广播/组播流量到/从容器。
- 对所有容器提供相同的外部 MAC。
- 无需管理桥接接口。
- 支持仅第 3 层模式,适用于主机上运行 BGP(或其他路由协议)以在本地路由表中分发容器 IP 到更广泛网络的设置。
- 容器可以选择使用现有的
l2proxy
和link
设置在本地局域网上以第 2 层访问 IP。
pidfd:添加对新的 pidfd api 的初始支持¶
较新的内核版本允许通过进程文件描述符 (pidfd) 与进程交互。这消除了例如发送信号或检索进程信息时出现的各种竞争条件。此 LXC 版本使用了 pidfd_send_signal() 系统调用和 clone() 系统调用中的 CLONE_PIDFD 标志。
强化:添加更多基于编译器的强化¶
在过去几个版本中,我们启用了编译器提供的用于强化 C 代码库的选项。此版本启用了
-Wlogical-op -Wmissing-include-dirs -Wold-style-definition -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=return-type -Werror=incompatible-pointer-types -Wformat=2 -Wimplicit-fallthrough=5 -Wshadow -Wendif-labels -Werror=overflow -fdiagnostics-show-option -fstack-protector-strong -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs -fasynchronous-unwind-tables -pipe -fexceptions
强化:删除所有堆栈分配¶
基于堆栈的内存分配(例如,通过 alloca()
)会导致非常严重的内存错误。因此,LXC 已删除所有基于堆栈的内存分配,并且不允许新代码添加任何分配。
强化:添加对 LGTM¶
LXC 已获得对 LGTM 代码分析工具的支持。我们很高兴 LXC 的代码目前被评为 A+。
强化:添加对 coccinelle¶
LXC 已获得对 coccinelle 代码转换工具的支持。这使我们能够自动更改代码,消除由于手动替换例如 alloca()
等弃用函数而导致的错误。
强化:基于编译器的资源清理¶
代码库将逐渐切换,以使用编译器(如 gcc
和 clang
)支持的清理属性。
强化:从代码库中删除 fgets()
¶
为了提高安全性,所有对 fgets()
的使用都已从代码库中删除。强烈建议在新代码中不要使用此函数。
强化:扩展关闭执行的使用¶
所有可以设置为关闭执行的文件描述符现在都设置为关闭执行。
对 cgroup v2 使用 /sys/kernel/cgroup/delegate
文件¶
此文件导出可委托的 cgroups v2 文件列表(每行一个),即应将所有权更改为委托人的用户 ID 的文件。LXC 将使用此文件来确定如何正确委托 cgroups。
处理没有 cgroups 的布局¶
这允许 LXC 在没有可写 cgroups 的系统上启动容器。
处理 cpuset 中的脱机 cpu¶
除了从容器的 cgroup 中删除隔离的 cpu 之外,LXC 现在还将从容器的 cpuset 中删除脱机 cpu。
为每个容器生成新的引导 ID¶
LXC 现在将为每个容器生成一个新的随机引导 ID,并将其挂载到 /proc/sys/kernel/random/boot_id
。这将允许 systemd
识别每个容器的引导。
统一网络创建¶
LXC 有一种新的统一方法来为特权和非特权容器创建网络,极大地简化了代码。
安全:runC CVE-2019-5736 的修复¶
此版本包含对今年早些时候发现的特权容器逃逸的修复。根据我们的政策,我们不认为特权容器是根安全,因此 LXC 并未收到此问题的 CVE。但是,我们仍然在此版本中提供修复程序。有关更多详细信息,请参阅 这篇博文。
错误修复¶
- lxc-download:兼容性的预发布版本提升
- seccomp:打开 memfd 读写
- 文档:记录 lxc.net.[i].veth.mode 选项
- 网络:添加 veth 路由器模式静态路由和代理条目
- 网络:向 veth 网络设置添加模式参数(桥接、路由器)
- lxc/log:添加 error_log_errno 宏
- 文档:将 lxc.comp.notify.cookie 添加到日语 lxc.container.conf(5)
- cgroup:检查非空 conf
- seccomp:编码风格
- af_unix:删除未使用的变量
- seccomp:与代理请求一起发送调用者 pidfd
- seccomp:使用 MSG_TRUNC 进行 recvmsg
- 文档:记录 lxc.seccomp.notify.cookie
- seccomp:延迟重新连接到代理
- seccomp:不断重试重新连接到代理
- seccomp:在没有代理的情况下发送默认响应
- seccomp:重试一次连接到代理
- seccomp:在没有代理的情况下不要忽略系统调用
- seccomp:删除重新连接循环
- seccomp:对通知代理使用 SOCK_SEQPACKET
- seccomp:断言通知响应中的 __reserved 为 0
- seccomp:更新通知 api
- conf:添加 lxc.seccomp.notify.cookie
- file_utils:添加 lxc_recvmsg_nointr_iov
- af_unix:添加 lxc_unix_connect_type
- af_unix:添加 lxc_abstract_unix_recv_fds_iov()
- af_unix:添加 lxc_abstract_unix_send_fds_iov
- pidf_send_signal:修复返回值
- lxccontainer:在挂载注入失败时正确清理
- start:尽早调用 lxc_find_gateway_addresses
- 网络:简化 lxc_network_move_created_netdev_priv()
- 网络:为所有非平凡网络类型发送名称
- 网络:为 instantiate_phys() 记录 created_name
- 网络:简化 instantiate_phys()
- 网络:为 instantiate_vlan() 记录创建的名称
- 网络:简化 instantiate_vlan()
- 网络:为 instantiate_ipvlan() 记录创建的名称
- 网络:简化 instantiate_ipvlan()
- 网络:在 instantiate_macvlan() 中暂存创建的名称
- 网络:简化 instantiate_macvlan()
- 网络:s/loDev/loop_device/g
- cgroups:处理 cpuset 初始化竞争
- 网络:删除错误的限制
- 修复 do_storage_create 中的内存泄漏
- cgroups:将变量移入更紧密的范围
- cgroups:正确排序变量
- cgroups:简化 cgfsng_nrtasks()
- cgroups:简化 cgfsng_setup_limits()
- cgfsng:修复 lxc_cpumask_to_cpulist 中的内存泄漏
- lxccontainer:重构 seccomp 通知 API 函数
- cgfsng:写入正确祖先的 cpuset.mems
- parse.c:修复 memfd_create 中的 fd 泄漏
- lxc.pc.in:添加 libs.private 用于静态链接
- 修复网络命名空间的文件描述符泄漏
- 网络:修复 lxc_netdev_rename_by_index()
- 从 gnutls 切换到 openssl 用于 sha1
- 文档:在日语文档中添加关于共享 ns + LSM 的说明
- seccomp:不要设置 SECCOMP_FILTER_FLAG_NEW_LISTENER
- 集中化挂钩名称
- seccomp:为 SECCOMP_FILTER_FLAG_NEW_LISTENER 添加 ifdefine
- seccomp:s/SCMP_FLTATR_NEW_LISTENER/SECCOMP_FILTER_FLAG_NEW_LISTENER/g
- seccomp:s/HAVE_DECL_SECCOMP_NOTIF_GET_FD/HAVE_DECL_SECCOMP_NOTIFY_FD/g
- seccomp:/sseccomp_notif_free/seccomp_notify_free/g
- seccomp:s/seccomp_notif_alloc/seccomp_notify_alloc/g
- seccomp:s/seccomp_notif_id_valid/seccomp_notify_id_valid/g
- seccomp:s/seccomp_notif_send_resp/seccomp_notify_respond/g
- seccomp:s/seccomp_notif_receive/seccomp_notify_receive/g
- seccomp:s/seccomp_notif_get_fd/seccomp_notify_fd/g
- seccomp:s/SCMP_ACT_USER_NOTIF/SCMP_ACT_NOTIFY/g
- cgroups:防止段错误
- 启动:修复 lxc_init 失败时处理程序内存泄漏
- lxc_usernsexec:在 unshare 失败后继续会导致令人困惑且误导性的错误消息
- 如果缓冲区太小,getgrgid_r 会失败并返回 ERANGE。使用更大的缓冲区重试。
- lxc_clone:添加关于堆栈大小的注释
- lxc_clone:将堆栈大小增加到 8MB
- 配置:删除额外的逗号
- lxccontainer:清理附加函数
- 附加:不要重新加载容器
- 网络:修复了阻止物理网络设备运行下行挂钩的错误
- 网络:将物理网络设备移回监视器的网络 ns,而不是 pid 1 的
- lxc_clone:摆脱一些间接性
- 文档:添加关于共享 ns + LSM 的一个小说明
- lxc_clone:将非堆栈分配的堆栈传递给 clone
- 配置:处理交叉编译时的检查
- 在可用时使用 %m 代替 strerror()
- 配置:检查 %m 的可用性
- initutils:修复 realloc 失败时的内存泄漏
- zfs:修复 zfs_snapshot 错误时的返回值
- lvm:如果 lvm_create_clone 失败,修复返回值
- criu:删除 _exit() 后的不必要返回值
- criu:使用 -v4 代替 -vvvvvv
- 选项 --busybox-path 而不是 --bbpath
- 新选项 --bbpath 和不必要的 --rootfs 检查
- 编码风格:更新
- 启动:使用 CLONE_PIDFD
- api:添加 network_phys_macvlan_mtu 扩展
- 网络:在容器关闭时恢复物理设备 MTU
- 网络:为物理和 macvlan 类型添加 mtu 支持
- raw_syscalls:简化汇编
- utils:改进 switch_to_ns()
- 文档:修复和改进日语翻译
- 文档:更新日语 lxc.container.conf(5)
- 网络:重新设计 veth 网关逻辑
- 网络:使 vlan 网络接口在调用 upscript 之前设置 mtu
- 网络:为 ipvlan 接口添加自定义 mtu 支持
- seccomp:记录路径计算
- 编译器:添加 __returns_twice 属性
- seccomp:发送进程内存 fd
- 命名空间:允许使用命名空间共享的 nsfd 的路径名
- seccomp:确保字段设置为 0
- seccomp:删除对齐要求
- seccomp:通知器修复
- 网络:使一些路由函数变为静态
- 网络:修复 macvlan 模式选择中的错误
- 网络:修复 vlan 挂钩脚本
- 网络:修复错误消息中的一个小错别字
- 启动:静默 clang
- 修复“zfs get”命令顺序
- lxc-start:删除错误的文档
- netns_getifaddrs:适应内核更改
- 配置:s/LDLAGS/LDFLAGS/
- conf:在 lxc.mount.fstab 之后立即进行 lxc.mount.entry 挂载
- raw_syscalls:lxc_raw_clone()
- hooks/nvidia:处理 NVIDIA_REQUIRE 变量中的空格
- 存储:更新 zfs
- 存储:防止未初始化变量警告
- cgroups:修复潜在的空指针解引用
- 附加:使用更紧密的范围来获取 fd 变量
- 修复:#2927 api 文档生成在源代码外构建下失败。
- 修复监视器 pdeathsig 处理
- 修复用户命名空间 pdeathsig 处理
- 网络:修复网络设备删除
- 文档:将 apparmor 配置文件生成的描述添加到手册页
- 文档:将 lxc.rootfs.managed 添加到 lxc.container.conf(5)
- 文档:将 lxc.cgroup.relative 添加到 lxc.container.conf(5)
- lvm:更新 lvcreate 以擦除签名(如果支持),如果不支持则回退到旧命令。
- lxccontainer:检查 do_lxcapi_init_pid() 是否失败
- 启动:修复传递给 lxc_set_death_signal 的父 PID
- utils:修复 lxc_set_death_signal 中 PID 命名空间的处理
- btrfs:确保末尾有 \0 字节
- 修复 lxc.cgroup2。
在仅 cgroup2 的系统上 - conf:避免编译器警告
- confile:使 parse_limit_value() 变为静态
- confile_utils:使 update_hwaddr() 变为静态
- confile_utils:lxc_config_net_is_hwaddr()
- cgroups:删除未使用的变量
- 附加:删除未使用的变量
- 修复 Android 编译
- CODING_STYLE:更新
- conf:删除未使用的变量
- gpg:如果设置了 http_proxy,则使用代理
- conf:简化 idmaptool_on_path_and_privileged
- lxc-attach:切换到 attach_run_wait
- travis:运行 coccinelle
- 修复现有挂载目标检查
- cve-2019-5736:添加测试
- rexec:尝试 sendfile() 回退到 fd_to_fd()
- [V2] rexec:处理旧内核
- rexec:使用 __do_close_prot_errno
- memory_utils:引入 __do_close_prot_errno
- 宏:引入 steal_fd()
- 命令:将声明移入更紧密的范围
- 启动:将变量移入更紧密的范围
- 挂载:清理允许过度挂载
- 挂载:允许过度挂载
- 网络:不要记录假朋友
- conf:不要记录 devpts umount2() 失败
- rexec:删除 envp 解析,转而使用 environ
- apparmor:改进 apparmor python 脚本的测试
- apparmor:捕获配置文件打开错误
- rexec:使重新执行对库调用者可选
- include:为 Android 的 Bionic 添加 fexecve()
- 解析:处理 \r
- cgfsng:修复 cgroup 创建
- coccinelle:使用标准退出标识符
- coccinelle:s/while({1,true})/for(;;)/
- lxc-init:在等待失败时退出并返回错误
- 启动:防止签名问题
- cgfsng:删除不必要的检查
- 命令:删除不必要的检查
- caps:检查 uid 和 euid
- memory_utils:添加 memory_utils.h
- 修复 bash 完成目录的 rpm 打包。
- cgroups:使用 /sys/kernel/cgroup/delegate 文件
- 文档:将 lxc.seccomp.allow_nesting 添加到日语 lxc.container.conf(5)
- prlimit:删除已弃用且不必要的头文件
- 编译器:删除已弃用且不必要的头文件
- conf:将 0 0 附加到嵌套帮助程序挂载条目
- 在 configure_busybox() 中使用 BUSYBOX_EXE 变量
- conf:检查挂载条目解析是否成功
- 安装 udhcpc 的 default.script
- 避免双重 lxc-freeze/unfreeze
- 更新 freezer.c
- 处理 Android 上的备用循环设备位置
- 修复 Android 上的挂钩功能,其中“sh”放置在 /system/bin 下
- 修复 cgroup_exit 中的内存泄漏
- conf.c:修复内存泄漏和挂载错误
- 启动:启动失败时,__lxc_start 返回 -1
- 网络:使用 uid 信息作为 veth 接口名称的前缀
- 启动:处理缺少的 CLONE_NEWCGROUP
- 修复为 Android 编译时的编译错误
- 合并拉取请求 #2774 来自 hn/master
- 修复:无特权的 veth 设备(例如 vethFWABHX)在随机生成的设备名称部分从不包含“Z”字符,因为对模数运算不需要从 strlen() 中减去 1。
- cgfsng:不要在出错时释放 container_full_path
- confile:添加 lxc.seccomp.allow_nesting
- lxccontainer:修复容器复制
- conf:在 lxc_write_to_file 错误时使用 SYSERROR
- lxccontainer:修复挂载 API(mount_injection_file)
- 存储:不要销毁预先存在的 rootfs
- 终端:删除 sigwinch 命令
支持和升级¶
LXC 3.2 不是 LTS 版本,因此只会在 LXC 3.3 发布之前得到支持。我们建议需要更强支持承诺的用户保留在我们的 LTS 版本之一上。
下载¶
- LXC 发布包:lxc-3.2.1.tar.gz (GPG: lxc-3.2.1.tar.gz.asc)