多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

90DaysOfDevOps 第 47 天:Docker 网络与容器安全实战指南

90DaysOfDevOps 第 47 天:Docker 网络与容器安全实战指南 文档/教程【免费下载链接】90DaysOfDevOpsThis repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.项目地址https://gitcode.com/gh_mirrors/90/90DaysOfDevOps点击查看免费下载本篇文章来自 90DaysOfDevOps 学习项目 2022 年路线图的 Day 47聚焦两个此前未系统展开的核心主题容器网络Container Networking与容器安全Container Security。你将学会使用docker network命令族管理网络、理解 bridge 网络的本质、通过端口映射NAT让容器服务对外可达并掌握非 root 用户运行、私有镜像仓库、精简镜像等降低攻击面的实战手段。文中所有命令均可在 Docker Desktop含 WSL 2 环境上直接复现。输出文章 输出文章90DaysOfDevOps 第 47 天Docker 网络与容器安全实战指南本篇文章来自 90DaysOfDevOps 学习项目 2022 年路线图的 Day 47聚焦两个此前未系统展开的核心主题容器网络Container Networking与容器安全Container Security。你将学会使用docker network命令族管理网络、理解 bridge 网络的本质、通过端口映射NAT让容器服务对外可达并掌握非 root 用户运行、私有镜像仓库、精简镜像等降低攻击面的实战手段。文中所有命令均可在 Docker Desktop含 WSL 2 环境上直接复现。Docker 网络基础认识 docker network 命令族在前面的容器专题练习中我们已经让很多容器跑起来了但始终没有从网络视角审视它们如何在后台工作也尚未涉及安全话题。本小节先建立容器网络的操作基础。打开终端输入主命令docker network这是配置和管理容器网络的核心命令。其帮助输出会展示该命令的用法Usage: docker network COMMAND以及全部可用的子命令子命令功能connect将容器连接至网络create创建新网络disconnect将容器从网络断开inspect查看一个或多个网络的详细信息ls列出网络prune移除所有未使用的网络rm移除一个或多个网络也就是说借助这一个命令族我们就能完成创建网络、列出已有网络、检查网络细节、删除网络的完整闭环。对任意子命令还可以通过docker network 子命令 --help获取更详细的参数说明。查看默认网络docker network list安装 Docker 后系统会预置一批网络。执行docker network list可以看到开箱即用的 Docker 网络视图。输出表格包含四列NETWORK ID、NAME、DRIVER、SCOPE。每张网络都有唯一的 ID 与名称并且与且仅与一个驱动driver关联。值得注意的细节名为bridge的网络其 DRIVER 也是bridge名为host的网络其 DRIVER 也是host——网络名与驱动同名不代表它们是同一个东西只是相关联而已。同时可以看到这些网络的 SCOPE 都是local即仅存在于当前 Docker 主机上。深入网络细节docker network inspectlist只给了概览若要查看某个网络的完整配置使用docker network inspect bridge该命令会返回指定网络名称的全部配置细节包括网络的名称Name与唯一 ID使用的驱动Driver作用域Scope已连接的容器列表Containers包含每个容器的名称、端点 ID、IPv4/IPv6 地址等以及子网、网关、内嵌 DNS、IPAM 配置等更多信息。正是通过inspect我们才能看到哪些容器接入了哪个网络、分到了什么 IP这类运行时事实。Bridge 网络单主机的虚拟交换机标准安装的 Docker Desktop 会预建一张名为bridge的网络如上文docker network list所示它关联的是bridge驱动。虽然名字相同但网络与驱动是两个层面的概念。从输出可以看到bridge 网络的作用域是local这意味着该网络只存在于当前这台 Docker 主机上。所有使用 bridge 驱动创建的网络都是如此——bridge 驱动提供的是单主机single-host网络能力。从底层实现看所有由 bridge 驱动创建的网络都基于Linux bridge构建Linux bridge 也就是常说的虚拟交换机virtual switch。它负责在同一主机内的容器之间、以及容器与主机网络之间转发数据帧。连接容器默认接入 bridge 网络bridge 网络是新容器的默认归属——只要你在运行时没有通过--network显式指定网络所有容器都会被连接到 bridge 网络。创建并保持一个后台运行的测试容器docker run -dt ubuntu sleep infinity这里的sleep infinity会让容器进程在后台持续运行从而让我们有充足的时间把玩这个容器。此时再用docker network inspect bridge检查 bridge 网络就能在Containers一节看到一条与我们刚部署的容器完全匹配的记录——这正是未指定网络则默认接入 bridge的直接证据。接着进入容器内部查看docker ps # 获取容器 ID例如 3a99af449ca2 docker exec -it 3a99af449ca2 bash进入容器后Ubuntu 基础镜像默认没有可用的 ping 工具需要先安装apt-get update apt-get install -y iputils-ping ping -c5 www.90daysofdevops.com成功返回 5 个回显包说明容器通过 bridge 网络的默认配置能够访问外部网络。练习完毕后用docker stop 3a99af449ca2停止该容器注意随后执行docker ps就看不到它了。配置 NAT 实现外部访问端口映射实战容器默认网络地址是主机私有的外部流量无法直接抵达。本小节演示通过**端口映射NAT**把 Docker 主机的 8080 端口映射到容器内部的 80 端口让流量主机 8080 → 容器 80。基于官方 NGINX 镜像启动一个具名容器docker run --name web1 -d -p 8080:80 nginx参数说明--name web1为容器指定名称便于后续管理-d后台运行detached-p 8080:80端口映射左侧为 Docker 主机端口右侧为容器内部端口nginx官方 NGINX 镜像。执行docker ps查看容器状态与端口映射。输出顶部即为运行 NGINX 的 web1 容器注意其 PORTS 列显示0.0.0.0:8080-80/tcp这表示所有主机接口上的 8080 端口都被映射到 web1 容器内部的 80 端口。正是这条映射使容器内的 Web 服务可以经Docker 主机 IP 8080 端口从外部被访问。接下来获取主机 IP。在 WSL 终端中执行ip addr记下主机接口的 IP 地址示例中为172.25.218.154你的环境可能不同然后打开浏览器访问http://172.25.218.154:8080/看到 NGINX 默认欢迎页面即证明端口映射链路主机 8080 → 容器 80完全打通容器服务已对外可达。这套 NAT 思路源自 2017 年 DockerCon 的官方演示至今仍然适用原演示后半部分涉及 Docker Swarm不在本专题范围内。容器安全从 root 权限迁移到非 root 用户与整机服务器配置相比容器为工作负载提供了更安全的环境它把应用拆分为更小、更松耦合且彼此隔离的组件从而从整体上缩小攻击面attack surface。但这并不意味着容器对攻击者免疫。只要系统存在可被利用的漏洞我们仍需要理解这项技术的安全陷阱并坚持最佳实践。第一个最典型的隐患就是权限过大。问题容器内的 root 进程到目前为止我们部署的所有容器其内部进程都是以 root 权限运行的。这意味着进程对容器乃至宿主机环境拥有完整的管理员访问权。练习环境里这些容器不会长期存活但以 root 起容器如此容易恰恰是危险所在。方案一在 Dockerfile 中创建非 root 用户更规范的做法是在构建镜像时就指定非 root 用户。90DaysOfDevOps 仓库的 Containers 目录 中就保存着这份示例 Dockerfile原文如下# 使用官方 Ubuntu 18.04 作为基础镜像 FROM ubuntu:18.04 # 安装 nginx 和 curl RUN apt-get update apt-get upgrade -y #RUN apt-get install -y nginx curl #RUN rm -rf /var/lib/apt/lists/* RUN groupadd -g 1000 basicuser useradd -r -u 1000 -g basicuser basicuser USER basicuser逐行拆解FROM ubuntu:18.04以官方 Ubuntu 18.04 为基础镜像RUN apt-get update apt-get upgrade -y更新软件源并升级系统包RUN groupadd -g 1000 basicuser useradd -r -u 1000 -g basicuser basicuser创建 GID/UID 均为 1000 的系统用户basicuser-r表示系统账户-u 1000指定 UID-g basicuser指定所属组USER basicuser声明镜像默认以basicuser身份运行这是最关键的一行——此后所有以该镜像启动的容器进程都不再以 root 执行。被注释掉的apt-get install -y nginx curl与rm -rf /var/lib/apt/lists/*也值得留意前者是安装服务软件的可选步骤后者是清理 apt 缓存以减小镜像体积的常用手段与后文精简镜像呼应。方案二docker run --user 运行时覆盖除了在 Dockerfile 中固化用户还可以在运行时临时指定docker run --user 1009 ubuntudocker run --user会覆盖 Dockerfile 中通过USER指令指定的任何用户。例如上面的命令会让容器始终以 UID 1009 运行。但这里有一个前提只有当 1009 本身具有最低权限级别时容器才真正以最小权限运行。更重要的是--user这种方式并不能修复镜像自身潜在的安全缺陷例如镜像里遗留的 root 属主敏感文件。因此更稳妥的做法仍然是在 Dockerfile 中显式指定非 root 用户让容器从设计上就始终安全运行。私有镜像仓库掌控镜像供应链镜像来源也是安全的重要一环。我们在前面的练习中大量使用了 DockerHub 这类公共仓库而如果由组织搭建私有容器镜像仓库既可以自主选择托管位置也可以使用市面上的托管服务本质收益是对团队可用镜像拥有完全控制权。相比之下DockerHub 适合作为获取基线的起点但它只提供基础服务使用公共镜像意味着你要把大量信任托付给镜像发布者——镜像是否包含恶意内容、是否被篡改都需要自行甄别。私有仓库可自建也可用托管服务则把这份信任风险收回组织内部。精简镜像减小攻击面镜像体积虽然不直接等同于安全却与安全密切相关如果应用运行根本用不到某些资源就不该把它们装进容器。容器体积越大潜藏的无用组件越多攻击面也就越大。作者特别提醒了对latest标签的担忧——拉取latest镜像常常会带入大量冗余bloat。DockerHub 上每个仓库中的镜像都会显示压缩后的体积可作为选型参考。查看本地已有镜像及其大小最直接的命令是docker image等价于docker images。该命令会列出本地的镜像仓库、标签、镜像 ID、创建时间与大小是体检镜像体积的第一入口。结合构建层面的实践如使用精简基础镜像、清理apt缓存、移除无用层可以把攻击面和存储开销同时压下来。小结Day 47 完成了容器专题中网络与安全两块拼图网络侧docker network命令族list / inspect / create / connect / rm 等是管理容器网络的入口bridge 网络基于 Linux 虚拟交换机提供单主机网络能力且是新容器的默认网络-p端口映射通过 NAT 打通主机端口 → 容器端口配合ip addr获取主机 IP即可在浏览器验证容器服务对外可达。安全侧非 root 用户运行Dockerfile 中USER指令或docker run --user临时覆盖、私有镜像仓库掌控镜像供应链、精简镜像缩小攻击面三者共同构成了日常容器安全的基本盘。仓库中与本节配套的素材包括 示例 Dockerfile 以及 Containers 目录下的 docker-compose 示例如 my_wordpress 与 ELK 栈的编排文件可作为下一步深入练习的起点。下一篇 Day 48 将继续容器主题的进阶内容。赞分享文档/教程【免费下载链接】90DaysOfDevOpsThis repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.项目地址https://gitcode.com/gh_mirrors/90/90DaysOfDevOps点击查看免费下载相关推荐90DaysOfDevOps 第 47 天Docker 网络与容器安全实战指南90DaysOfDevOps 第 47 天Docker 网络与容器安全实战指南 本篇文章是 90DaysOfDevOps 容器专题第 47 天的完整技术笔文档/教程90DaysOfDevOps 实战指南Docker 网络与安全Day 4790DaysOfDevOps 实战指南Docker 网络与安全Day 47 Docker 让我们能以一条命令快速拉起容器但容器之间、容器与宿主机之间如何文档/教程90DaysOfDevOps 第 48 天超越 Docker——Podman、LXC 与 Containerd 容器技术全景实战90DaysOfDevOps 第 48 天超越 Docker——Podman、LXC 与 Containerd 容器技术全景实战 Docker 是整个 90文档/教程上一篇XDM下载管理器终极指南6个技巧解锁5倍提速与视频一键下载下一篇QQ聊天记录解密终极指南从打不开的数据库到跨设备迁移一份保姆级抢救手册创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表