随意使用root和特权可能是不必要的风险。本文展示了特权与root的操作方式有何不同,以及特权的实际含义。很多熟悉Unix系统(比如macOS、Linux)的人都习惯通过sudo来随意提升我们的权限到root用户。在调试开发工具或尝试编辑受保护目录中的文件时,这种情况经常发生,许多人在第一次尝试后默认使用sudo,但该命令不起作用。理解Docker安全的基础是理解实际的容器Docker提供了一个类似--privileged的flag,这其实和我们随便使用sudo有很大的不同,它会让应用程序暴露在不必要的风险中。本文将展示这与以root身份运行有何不同(以及如何避免以root身份运行),并解释特权的实际含义。以root身份运行Docker允许它隔离主机操作系统上的进程、功能和文件系统,事实上,大多数容器默认以root身份运行。为了举例,本文将使用DockerHub上三个最流行的图像。Postgres:$dockerrun-itpostgres#whoamiroot#id-u0Couchbase:$dockerrun-itcouchbasesh#whoamiroot#id-u0Alpine:$dockerrun-italpinesh#whoamiroot#id-u0我们可以看到,默认情况下,大多数图像都是root运行的。这通常会简化调试过程,尤其是当我们要执行到容器中时。尽管root用户的Linux功能非常有限,但最好避免以root身份运行。避免以root身份运行虽然在容器中以root身份运行是完全正常的,但如果我们想要加固容器,仍然需要避免这种情况。首先,违反了最小权限原则,其次,更严格地说,容器将是运行Docker命令的同一用户命名空间的一部分,如果容器能够逃脱,它将有权访问卷等资源,套接字等。有两种方法可以避免以root身份运行。通过调整Dockerfile以使用特定用户://DockerfileFROMmicrosoft/windowsservercore#CreateWindowsuserinthecontainerRUNnetuser/addpatrick#SetitforsubsequentcommandsUSERpatrick在运行时覆盖用户ID:$dockerrun-it--user4000postgressh#whoamiwhoami:cannotfindnameforuserID4000#id-u4000关于权限--privilegseen用户ID直接映射到主机的用户ID,并使其可以不受限制地访问它选择的任何系统调用。即使root在容器内,在正常操作中,Docker也会限制容器的Linux功能,例如限制CAP_AUDIT_WRITE,它允许覆盖内核的审计日志,这是容器化工作负载不太希望使用的功能。事实上,该权限只应在我们真正需要的特定设置中使用,它使容器能够访问主机(以root身份)执行几乎所有操作。本质上,它是逃脱容器包含的文件系统、进程、套接字和其他包含项目的通行证。它有特定的用例,例如Docker-in-Docker、其他CI/CD工具要求(Docker容器内部需要Docker守护进程),以及需要极端网络的地方。这是一个使用Ubuntu映像的示例(在VM中测试,因此您不会破坏任何东西):无特权:#whoamiroot#Noticehere,wearstillroot!#id-u0#hostname382f1c400bd#sysctlkernel.hostname=Attackerssysctl:settingkey"kernel.hostname":只读文件系统#Yetwecan'tdothis是特权的:$dockerrun-it--privilegedubuntush#whoamiroot.#Rootagain#id-u0#hostname86c62e9bba5e#sysctlkernel.hostname=Attackerkernel.hostname=Attacker#Exceptnowweareprivileged#hostnameAttackerKubernetes通过安全上下文提供相同的文件系统Features:apiVersion:v1kind:Podmetadata:name:nginxspec:containers:-name:nginximage:nginxsecurityContext:privileged:true另外,Kubernetes有一个强制机制叫做PodSecurityPolicy,它是一个admissioncontroller(Kubernetes允许容器进入它会被检查在集群之前),这里强烈建议禁止使用特权Pod:apiVersion:policy/v1beta1kind:PodSecurityPolicymetadata:name:examplespec:privileged:false#Don'ta低特权豆荚!总结到目前为止,我们已经了解了一些关于root和--privileged标志的知识,以及它们与“主机”操作系统的关系。无论我们是想限制容器的安全性还是调试问题,我们都需要确保我们的应用程序安全。
