【Docker】容器使用规范--安全挂载建议
容器挂载过程和安全挂载建议
绑定挂载
本文所提到的挂载主要指绑定挂载(bind mount),即通过-v /xx/xx:/xx/xx 和 --mount type=bind,xxx,xxx两种方式设置的容器挂载(其余docker卷的管理方式,如tmpfs、volume,本文暂不讨论),容器的挂载操作,简单点来讲,就是进入到容器Mount Namespace(该Namespace用于隔离挂载信息)后,调用Linux的mount()函数进行挂载。而操作系统进行(绑定)挂载的本质就是替换容器目标文件或目录inode的过程(类似硬连接,但不是),也就是使容器里面的目标文件或目录和宿主机上文件或目录使用同一个inode号(但Links不会增加)。(硬连接和bind mount的区别可见:https://www.cxyzjd.com/article/shengxia1999/52060354)
容器解析挂载的过程:
docker 对于挂载操作分为三个部分:参数解析(docker-cli)、校验+设置挂载点(dockerd(moby))、执行挂载操作(runC)。
当用户从命令行输入容器挂载相关的指令后,其运行流程如下:
1.在命令行输入--mount 和 -v 参数后,docker-cli会将其进行解析存入相应的数据结构(containerConfig.HostConfig.Mounts和containerConfig.HostConfig.Binds)。
2.docker-cli将容器配置通过请求发送给dockerd进程。
(对应上图黄色处)
3.dockerd接收到 创建或运行 的请求后会完成相应的动作,但是不管创建还是运行都会对挂载点进行注册。注册时会对HostConfig.Mounts和HostConfig.Binds验证,
但只验证Mounts里面的源路径,不验证Binds的源路径,如果Mounts里面的源路径不存在则会报错。验证完成后将这两个结构体里面的值都存入container.MountPoints。
(这个新编辑器代码模块没有go,暂时用python代替)
4.dockerd遍历container.MountPoints,又会检查每个挂载点的源路径是否存在,如果不存在就会对该路径进行逐层创建(0755权限),这里判断源路径是否存在是通过os.stat()来判断的,并不会做软链接校验,前面第3步也没做,唯一做了挂载路径软链接解析的地方是路径创建完成后,会通过defer关键字里面调用EvalSymlinks()来解析,但是此处解析后是为了设置mountLabel(是否为软链接并不影响这个label,具体见https://github.com/moby/moby/blob/6f4fbef82718212e593626419182f31a9f604316/pkg/idtools/idtools_unix.go#L25),所以,docker是允许挂载软链接的,但是这样做存在很大的风险。设置好挂载点之后dockerd会把这些挂载信息写入容器配置中。
5.dockerd随后会通过通过调用containerd-shim运行runC。
(对应上图蓝色处)
6.runC会读取容器的配置,调用操作系统的mount函数进行挂载。
(对应上图绿色处)
具体源码解析可见:http://3ms.huawei.com/km/blogs/details/13209943
安全挂载建议:
- docker支持多个容器挂载相同目录,挂载方式有只读、读写两种形式。应尽量避免容器之间以读写(rw)形式挂载相同目录,否则如果某容器被黑客控制,可以更改其他容器在该目录的文件。
- 不要在容器上挂载敏感的主机系统目录,如/(根目录)、/boot、/etc、/dev、/lib、/proc、/sys、/usr、/var/run(或者/run)。
- 不要将docker.sock挂载进容器。该文件是docker客户端和服务端通信的套接字文件,挂载后会导致dockerd暴露。
- 确认挂载传播模式为私有模式(private或默认的rprivate),如果以共享模式挂载会对所有挂载卷进行复制,任何一个挂载卷的修改会传播到所有其它挂载卷,且此模式下不会限制其它容器挂载和对该卷进行更改。
- 在挂载前最好先事先保证挂载的文件存在且权限正确,并且最好使用只读挂载,即在使用-v或--volume时加上ro,使用--mount进行挂载时加上readonly。
- 尽量保证挂载目录隔离,即宿主机进程不会访问挂载的目录。
- 以最小范围原则进行挂载,即能挂载子目录就绝不挂载父目录,能挂载文件就不要挂载该文件的整个目录。
- 不要挂载软链接。
参考资料:
- http://ilearning.huawei.com/edx/next/courses-learn?courseId=100015201&articleId=18119 (张磊的课)
- http://isource.huawei.com/w00428594/container_security_summary/tree/master (大佬的总结)
- https://w3.huawei.com/ipd/tsl/#!tsl_new/standard/standard.html?standardId=44180 (公司规范)
- http://www.sel.zju.edu.cn/blog/2018/05/10/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3docker%E5%AE%B9%E5%99%A8%E5%BC%95%E6%93%8Erunc%E6%89%A7%E8%A1%8C%E6%A1%86%E6%9E%B6/ (runC代码解读)
- https://studygolang.com/articles/16906 (docker-cli以及dockerd代码解读)
- http://3ms.huawei.com/km/groups/2034125/home?l=zh-cn#category=8652607 (容器安全圆桌交流)
欢迎大家一起探讨、补充!
本文来自博客园,作者:易先讯,转载请注明原文链接:https://www.cnblogs.com/gongxianjin/p/16895175.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
2021-11-16 EdgeCore初学习
2021-11-16 前端开发环境搭建