<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>技术原理 on CAO ZUOHUA</title><link>https://caozuohua.github.io/categories/%E6%8A%80%E6%9C%AF%E5%8E%9F%E7%90%86/</link><description>Recent content in 技术原理 on CAO ZUOHUA</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Fri, 11 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://caozuohua.github.io/categories/%E6%8A%80%E6%9C%AF%E5%8E%9F%E7%90%86/index.xml" rel="self" type="application/rss+xml"/><item><title>容器并非沙箱：为什么 Docker 组权限即是 Root？</title><link>https://caozuohua.github.io/posts/2026-09-11-docker-group-is-root/</link><pubDate>Fri, 11 Sep 2026 00:00:00 +0000</pubDate><guid>https://caozuohua.github.io/posts/2026-09-11-docker-group-is-root/</guid><description>&lt;p&gt;在多用户 Linux 环境中，常听到一种说法：将开发者加入 &lt;code&gt;docker&lt;/code&gt; 组只是为了方便运行容器，不必输入 &lt;code&gt;sudo&lt;/code&gt;。然而，从安全审计的角度来看，&lt;strong&gt;将用户加入 &lt;code&gt;docker&lt;/code&gt; 组本质上等同于赋予其宿主机的 Root 权限&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;h3 id="为什么-docker-组--root"&gt;为什么 Docker 组 = Root？&lt;/h3&gt;&#10;&lt;p&gt;Docker 守护进程（&lt;code&gt;dockerd&lt;/code&gt;）默认以 &lt;code&gt;root&lt;/code&gt; 用户身份运行。由于 &lt;code&gt;docker.sock&lt;/code&gt; 套接字文件通常被设置为 &lt;code&gt;root:docker&lt;/code&gt; 用户组权限（&lt;code&gt;660&lt;/code&gt;），任何属于该组的用户都可以直接通过该套接字与 daemon 通信。&lt;/p&gt;&#10;&lt;p&gt;这不仅仅是“方便”的问题。一旦拥有了 &lt;code&gt;docker.sock&lt;/code&gt; 的读写权限，你就可以操纵守护进程执行以下操作来实现“容器逃逸”：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;挂载宿主机根目录&lt;/strong&gt;：你可以启动一个挂载了宿主机 &lt;code&gt;/&lt;/code&gt; 的容器，在容器内执行 &lt;code&gt;chroot&lt;/code&gt;。此时，宿主机的完整文件系统就在你的掌握之中。&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker run -v /:/host -it alpine chroot /host&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;启动特权容器&lt;/strong&gt;：通过 &lt;code&gt;--privileged&lt;/code&gt; 参数，容器可以直接访问宿主机的硬件设备（如 &lt;code&gt;/dev/sda&lt;/code&gt;），轻易地绕过 Namespace 隔离。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h3 id="容器不是天然的安全边界"&gt;容器不是天然的安全边界&lt;/h3&gt;&#10;&lt;p&gt;容器技术的本质是 Linux 内核特性的“协同工作”：&lt;strong&gt;Namespace&lt;/strong&gt; 负责隔离进程视图，&lt;strong&gt;Cgroup&lt;/strong&gt; 负责限制资源消耗。但它们并非严密的安防屏障：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;共享内核&lt;/strong&gt;：所有容器与宿主机共享同一个内核。一旦发生提权逃逸，攻击者可以直接与内核交互，完全无视 Namespace 的限制。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Daemon 权限滥用&lt;/strong&gt;：Docker 的设计哲学是将 daemon 作为系统的“全权委托者”。能够指示 daemon 工作，也就意味着获得了系统的最高控制权。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="总结与防御"&gt;总结与防御&lt;/h3&gt;&#10;&lt;p&gt;为了防止因 Docker 权限配置不当引发的系统级风险，建议采取以下防范措施：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;最小权限原则&lt;/strong&gt;：严格审计 &lt;code&gt;docker&lt;/code&gt; 组，移除不必要的用户。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Rootless Docker&lt;/strong&gt;：在支持的发行版上使用无根模式，这样即使 daemon 被劫持，它也仅拥有当前用户的权限，无法直接侵害系统核心。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;拥抱 daemon-less&lt;/strong&gt;：如使用 &lt;strong&gt;Podman&lt;/strong&gt;，它默认无需守护进程，从架构上彻底消除了 &lt;code&gt;docker.sock&lt;/code&gt; 带来的 root 等效问题。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;作为开发者，我们不仅要利用好工具的便利性，更要看透其背后的权限契约。在 AI 环境部署和 presales 工具链的设计中，始终将“权限最小化”作为第一原则。&lt;/p&gt;</description></item></channel></rss>