文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

使用 root 用户执行Docker、K8s命令?No!!!

2024-12-03 02:14

关注

随意使用 root 和特权可能会带来不必要的风险。本文展示了特权与 root 运行方式的不同之处以及特权的实际意义。

很多熟悉 Unix 系统的人(例如 macOS、Linux)都习惯于通过使用 sudo 随意提升我们的特权给 root 用户。在调试开发工具或尝试编辑受保护目录中的文件时,经常会发生这种情况,许多人在第一次尝试之后,执行命令不成功,都会默认使用 sudo。

了解 Docker 安全性的基础是了解实际的容器

Docker 提供了一个类似 --privileged flag,实际上这与我们随意使用的 sudo 有很大不同,它可能会使应用程序面临不必要的风险。本文将展示这与 root 运行方式有何不同(以及如何避免以 root 用户身份运行),并介绍特权(privileged)的实际含义。

作为 root 运行

Docker 允许其在主机操作系统上隔离进程、功能和文件系统,并且实际上,大多数容器默认以 root 身份运行。为了示例,本文将使用 DockerHub 上的三个最受欢迎镜像。

Postgres: 

  1. $ docker run -it postgres   
  2. #whoami   
  3. root   
  4. #id -u   

Couchbase: 

  1. $ docker run -it couchbase sh   
  2. #whoami   
  3. root   
  4. #id -u   

Alpine: 

  1. $ docker run -it alpine sh   
  2. #whoami   
  3. root   
  4. #id -u   

我们可以看到,默认情况下,大多数镜像都以 root 用户身份运行。通常这可以简化调试过程,尤其是在我们要 exec 到容器时。尽管 root 用户的 Linux 功能非常有限,但最好还是避免以 root 用户身份运行。

避免以 root 身份运行

尽管在容器内部以 root 身份运行是非常正常的事,但是如果我们想要强化容器,仍然需要避免这种情况。首先,违反了最小特权原则,其次,更严格地说,容器将成为运行 Docker 命令的同一用户命名空间的一部分,并且如果容器能够转义,它将可以访问 volume、socket 等资源。

有两种避免以 root 用户身份运行的方法。

通过调整 Dockerfile 以使用特定用户: 

  1. // Dockerfile   
  2. FROM microsoft/windowsservercore  
  3. # Create Windows user in the container  
  4. RUN net user /add patrick  
  5. # Set it for subsequent commands 
  6.  USER patrick 

在运行时重写 User ID: 

  1. $ docker run -it --user 4000 postgres sh  
  2. # whoami  
  3. whoami: cannot find name for user ID 4000  
  4. # id -u  
  5. 4000 

关于特权

--privileged flag 将我们之前看到的用户 ID 直接映射到主机的用户 ID,并使其不受限制地访问其选择的任何系统调用。即使 root 在容器内部,在正常操作中,Docker 也会限制容器的 Linux 功能,例如限制 CAP_AUDIT_WRITE,它允许覆盖内核的审计日志,这是容器化工作负载不太需要的功能。

实际上,特权应该只在我们真正需要的特定设置中使用,它可以使容器访问主机(作为 root)几乎可以执行所有操作。从本质上讲,这是一个通行证,可以逃避容器包含的文件系统、进程、套接字和其他包含的项目。它有特定的用例,例如 Docker-in-Docker,其他 CI/CD 工具要求(从 Docker 容器内部需要 Docker 守护程序)以及需要极端网络的地方。

下面看一个使用 Ubuntu 镜像的示例(在 VM 内测试,这样就不会破坏任何东西):

没有特权: 

  1. # whoami  
  2. root # Notice here, we are still root!  
  3. # id -u  
  4.  
  5. # hostname  
  6. 382f1c400bd  
  7. # sysctl kernel.hostname=Attacker  
  8. sysctl: setting key "kernel.hostname": Read-only file system  # Yet we can't do this 

有特权: 

  1. $ docker run -it --privileged ubuntu sh  
  2. # whoami  
  3. root. # Root again  
  4. # id -u  
  5.  
  6. # hostname  
  7. 86c62e9bba5e  
  8. # sysctl kernel.hostname=Attacker  
  9. kernel.hostname = Attacker # Except now we are privileged  
  10. # hostname  
  11. Attacker  

Kubernetes 通过安全上下文提供相同的功能: 

  1. apiVersion: v1  
  2. kind: Pod  
  3. metadata:  
  4.   name: nginx  
  5. spec:  
  6.   containers:  
  7.   - name: nginx  
  8.     image: nginx  
  9.     securityContext:  
  10.       privileged: true 

此外,Kubernetes 有一个称为 PodSecurityPolicy 的强制机制,它是一个准入控制器(Kubernetes 在允许容器进入集群之前会对其进行检查),这里强烈建议不允许使用特权 Pod: 

  1. apiVersion: policy/v1beta1  
  2. kind: PodSecurityPolicy  
  3. metadata: 
  4.   name: example  
  5. spec: 
  6.   privileged: false  # Don't allow privileged pods! 

总结

到此为止,我们了解了一些有关 root 和 --privileged flag 的信息,以及它们与“主机”操作系统的关系。无论我们是否想限制容器的安全性或调试问题,都需要确保应用程序安全。 

 

来源:良许Linux内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯