Docker:渗透前置容器化核心基础

Docker:渗透前置容器化核心基础

  • Docker:渗透前置容器化核心基础
  • 前言:容器环境与渗透学习链路
    • [1 Docker 容器核心认知](#1 Docker 容器核心认知)
      • [1.1 容器核心定义](#1.1 容器核心定义)
      • [1.2 容器VS虚拟机客观认知纠正](#1.2 容器VS虚拟机客观认知纠正)
      • [1.3 渗透场景下Docker核心价值](#1.3 渗透场景下Docker核心价值)
      • [1.4 Docker核心三要素:镜像/容器/仓库](#1.4 Docker核心三要素:镜像/容器/仓库)
      • [1.5 底层依托:Linux Namespace/Cgroups极简原理](#1.5 底层依托:Linux Namespace/Cgroups极简原理)
    • [2 Docker Kali系统标准化安装](#2 Docker Kali系统标准化安装)
      • [2.1 系统残留冲突组件清理](#2.1 系统残留冲突组件清理)
      • [2.2 Docker Engine官方正规安装](#2.2 Docker Engine官方正规安装)
      • [2.3 国内镜像源加速器配置](#2.3 国内镜像源加速器配置)
      • [2.4 docker用户组权限规范(免sudo安全说明)](#2.4 docker用户组权限规范(免sudo安全说明))
      • [2.5 服务启停与开机自启管理](#2.5 服务启停与开机自启管理)
      • [2.6 安装报错与环境自检排错](#2.6 安装报错与环境自检排错)
    • [3 Docker 镜像核心管理](#3 Docker 镜像核心管理)
      • [3.1 镜像分层存储原理](#3.1 镜像分层存储原理)
      • [3.2 pull 拉取镜像与标签规范](#3.2 pull 拉取镜像与标签规范)
      • [3.3 images 本地镜像列表完整解析](#3.3 images 本地镜像列表完整解析)
      • [3.4 tag 镜像重命名与私有打标](#3.4 tag 镜像重命名与私有打标)
      • [3.5 rmi 删除镜像](#3.5 rmi 删除镜像)
      • [3.6 虚悬/废弃镜像批量清理](#3.6 虚悬/废弃镜像批量清理)
    • [4 Docker 容器核心操作命令](#4 Docker 容器核心操作命令)
      • [4.1 run 容器创建启动(渗透核心指令)](#4.1 run 容器创建启动(渗透核心指令))
        • [4.1.1 -p 端口映射原理与实操](#4.1.1 -p 端口映射原理与实操)
        • [4.1.2 -v 数据挂载核心作用](#4.1.2 -v 数据挂载核心作用)
        • [4.1.3 --name / -d 后台运行参数](#4.1.3 --name / -d 后台运行参数)
      • [4.2 ps 容器状态查看字段解析](#4.2 ps 容器状态查看字段解析)
      • [4.3 start/stop/restart 容器生命周期控制](#4.3 start/stop/restart 容器生命周期控制)
      • [4.4 exec 进入容器终端(主流交互方式)](#4.4 exec 进入容器终端(主流交互方式))
      • [4.5 attach 交互模式坑点规避](#4.5 attach 交互模式坑点规避)
      • [4.6 rm 容器删除与批量清理](#4.6 rm 容器删除与批量清理)
    • [5 容器数据持久化与挂载实战](#5 容器数据持久化与挂载实战)
      • [5.1 容器临时数据丢失机制](#5.1 容器临时数据丢失机制)
      • [5.2 绑定挂载Bind Mount实操](#5.2 绑定挂载Bind Mount实操)
      • [5.3 数据卷Volume管理](#5.3 数据卷Volume管理)
      • [5.4 渗透场景挂载风险警示](#5.4 渗透场景挂载风险警示)
    • [6 Docker 信息排查与取证命令](#6 Docker 信息排查与取证命令)
      • [6.1 inspect 容器/镜像底层信息解析](#6.1 inspect 容器/镜像底层信息解析)
      • [6.2 logs 容器运行日志查看](#6.2 logs 容器运行日志查看)
      • [6.3 top 查看容器内部进程](#6.3 top 查看容器内部进程)
      • [6.4 diff 检测容器文件篡改痕迹](#6.4 diff 检测容器文件篡改痕迹)
    • [7 Dockerfile 自定义渗透镜像](#7 Dockerfile 自定义渗透镜像)
      • [7.1 镜像分层构建原理](#7.1 镜像分层构建原理)
      • [7.2 高频指令:FROM/RUN/COPY/CMD 详解](#7.2 高频指令:FROM/RUN/COPY/CMD 详解)
      • [7.3 build 构建自定义镜像](#7.3 build 构建自定义镜像)
    • [8 Docker Compose 靶场编排核心](#8 Docker Compose 靶场编排核心)
      • [8.1 Compose 适用场景(多服务靶场)](#8.1 Compose 适用场景(多服务靶场))
      • [8.2 yaml 配置文件核心字段解析](#8.2 yaml 配置文件核心字段解析)
      • [8.3 up/down/logs 核心编排命令](#8.3 up/down/logs 核心编排命令)
        • [8.3.1. 启动靶场:docker compose up](#8.3.1. 启动靶场:docker compose up)
        • [8.3.2. 销毁靶场:docker compose down](#8.3.2. 销毁靶场:docker compose down)
        • [8.3.3. 查看日志:docker compose logs](#8.3.3. 查看日志:docker compose logs)
        • [8.3.4. 其他常用编排命令](#8.3.4. 其他常用编排命令)
      • [8.4 一键部署开源漏洞靶场实操(Vulhub)](#8.4 一键部署开源漏洞靶场实操(Vulhub))
        • [步骤 1:安装 git 工具](#步骤 1:安装 git 工具)
        • [步骤 2:克隆 Vulhub 仓库](#步骤 2:克隆 Vulhub 仓库)
        • [步骤 3:选择漏洞环境并进入目录](#步骤 3:选择漏洞环境并进入目录)
        • [步骤 4:查看编排配置文件](#步骤 4:查看编排配置文件)
        • [步骤 5:一键启动漏洞环境](#步骤 5:一键启动漏洞环境)
        • [步骤 6:查看服务运行状态](#步骤 6:查看服务运行状态)
        • [步骤 7:访问漏洞页面验证](#步骤 7:访问漏洞页面验证)
        • [步骤 8:销毁漏洞环境](#步骤 8:销毁漏洞环境)
    • [9 Docker 安全风险与渗透攻防要点](#9 Docker 安全风险与渗透攻防要点)
      • [9.1 docker组权限逃逸原理与防御](#9.1 docker组权限逃逸原理与防御)
      • [9.2 挂载宿主机目录高危漏洞](#9.2 挂载宿主机目录高危漏洞)
      • [9.3 容器内信息搜集与环境探测](#9.3 容器内信息搜集与环境探测)
      • [9.4 容器逃逸基础前置认知](#9.4 容器逃逸基础前置认知)
    • 总结

Docker:渗透前置容器化核心基础

前言:容器环境与渗透学习链路

在学习完《Kali Linux:渗透前置终端核心基础 》后,你已经掌握了 Linux 系统底层逻辑、终端命令、权限体系、进程日志与网络基础 。这些内容是渗透测试的硬件级地基 ,而本章要讲解的 Docker ,是渗透测试的软件级工程地基

很多入门学习者会有一个误区:掌握 Kali 命令后,直接上手漏洞复现、靶场渗透、工具开发 ,最终频繁遇到环境报错、依赖冲突、系统污染、版本不兼容 等问题。究其根本,不是你的命令基础不扎实,而是缺少标准化的隔离运行环境

在当下的红队攻防、渗透测试、漏洞研究 领域,Docker 已经成为刚需基础设施,而非可选工具。我们可以直白定义它的核心价值:Docker 是一套基于 Linux 内核的轻量级容器引擎,用于打包、分发、隔离运行程序与完整环境


1 Docker 容器核心认知

1.1 容器核心定义

从Linux内核视角来看,容器是一种基于内核隔离技术的轻量级虚拟运行环境 。它并非完整复刻一套操作系统,而是依托宿主机原生Linux内核,通过资源隔离与文件封装,为程序提供独立的运行目录、网络空间、进程视图与权限边界。

简单通俗定义:容器就是把程序、依赖库、运行环境打包在一起,在隔离空间内运行的"便携沙箱" 。它复用宿主机内核,仅隔离用户态资源,因此具备体积小、启动快、性能无损耗三大核心特征,这也是它区别于虚拟机的本质根源。


1.2 容器VS虚拟机客观认知纠正

绝大多数初学者会混淆容器与虚拟机,甚至认为二者只是"大小区别",这是典型认知误区,必须从底层架构纠正。

虚拟机(VM) :属于硬件级虚拟化,基于Hypervisor虚拟化CPU、内存、磁盘、网卡整套硬件资源,内部需要完整加载独立操作系统内核(Windows/Linux)。虚拟机拥有完整硬件栈隔离,但占用资源大、启动慢、内核层级冗余

容器(Docker) :属于系统级虚拟化,不虚拟化硬件,不自带内核,直接复用Kali宿主机Linux内核,仅通过内核API隔离进程、文件、网络、用户组。容器秒级启动、磁盘占用极小、性能与原生主机无差异。

渗透场景一句话区分:虚拟机用来隔离整套系统,容器用来隔离单个/一组攻防服务与工具环境


1.3 渗透场景下Docker核心价值

脱离渗透谈Docker开发用法没有意义,本节聚焦红队/渗透测试专属价值,也是你必须掌握Docker的核心原因:

  1. 环境零污染 :所有靶场、老旧工具、特殊依赖全部运行在容器内,删除容器即可清空环境,永不污染宿主Kali系统;

  2. 依赖强制统一 :老旧漏洞、Python2、特定版本组件可封装进镜像,规避本机依赖冲突;

  3. 快速搭建靶场 :当代绝大多数CVE漏洞靶场、AWD攻防环境、WEB漏洞平台均基于Docker Compose编排;

  4. 工具便携分发 :自定义封装带后门、扫描器、代理环境的专属镜像,任意主机拉取即可直接作战;

  5. 隔离边界防护:容器默认资源受限,可规避恶意工具、恶意样本直接读取宿主机敏感文件,提升测试安全性。


1.4 Docker核心三要素:镜像/容器/仓库

Docker的全部操作,本质围绕镜像、容器、仓库三个核心对象流转,三者关系必须牢记:

镜像(Image) :只读的静态模板,相当于系统/工具的"安装包",包含程序、依赖、配置、基础文件系统,不可写入修改

容器(Container) :由镜像运行生成的可运行实例,是读写的动态沙箱,一个镜像可以同时启动无数个独立容器;

仓库(Registry):存放、分发镜像的远程服务器,官方公共仓库为Docker Hub,企业/团队可搭建私有仓库存放专属攻防镜像。

极简流转逻辑:仓库拉取镜像 → 镜像运行生成容器 → 容器修改后可重新打包为新镜像 → 推送至仓库分发


1.5 底层依托:Linux Namespace/Cgroups极简原理

Docker本身不是虚拟化技术,也没有独立开发隔离逻辑,它全部的隔离、限制能力都调用Linux内核自带底层模块实现,这也是Windows、Mac系统必须依靠虚拟机搭载Linux内核才能运行Docker的根本原因。前面章节我们学习过Linux进程、用户、权限、网络等基础内容,Namespace与Cgroups就是内核专门用来切割资源边界的两套核心组件,是理解容器逃逸、容器权限漏洞的前置理论,不能浅尝辄止。

简单概括两者分工:Namespace负责「隔离看得到什么」,Cgroups负责「限制能用多少」。两套机制叠加,才构成容器完整的隔离边界。


Namespace(命名空间):视图隔离,分割"可见范围"

Namespace的作用是给进程分配独立视图。同一个宿主机上,宿主机进程能看到全部系统资源,容器内进程只能看见分配给自己的那一部分,看不见宿主机及其他容器的资源。Linux内核提供7种标准命名空间,Docker全部启用,分别隔离不同维度资源:

Namespace类型 隔离对象 渗透核心意义
PID Namespace 进程编号 容器内PID从1重新计数,看不到宿主机进程;但宿主机能看到容器全部进程,是权限不对等关键点
Mount Namespace 文件挂载点 容器拥有独立文件系统视图,默认无法读取宿主机根目录;-v手动挂载会直接打通,是容器逃逸最常用突破口
Network Namespace 网络栈 每个容器有独立网卡、IP、端口、路由表;默认容器间无法互通,需端口映射或网桥打通
User Namespace 用户/用户组ID 容器内root映射到宿主机为普通低权限用户;多数靶场为方便操作关闭该隔离,逃逸风险大幅提升
UTS Namespace 主机名/域名 容器可自定义独立hostname,与宿主机互不干扰
IPC Namespace 进程间通信 容器内进程只能与同容器进程交互,阻断跨容器IPC通信
Cgroup Namespace 控制组视图 容器内无法读取宿主机Cgroup限制配置

只要任意一种Namespace存在隔离缺陷,攻击者就可以突破视图限制,读取宿主机进程、文件、网络信息,完成信息搜集与权限探测。


Cgroups(控制组):资源限流,约束"可用资源上限"

Namespace解决"看得见哪些资源",Cgroups解决"最多能用多少资源"。专门对一组进程做硬件资源配额限制,防止单个容器恶意占用整机资源,造成宿主机卡顿、崩溃,渗透场景下可抵御恶意靶场、恶意样本发起资源耗尽攻击。

Cgroup子系统 限制内容 渗透场景作用
CPU Cgroup CPU核心数、最大使用率 防止容器满负载跑满全部处理器,避免宿主机死机
Memory Cgroup 最大可用内存 超出阈值进程被内核强制终止,防止恶意程序疯狂占内存
BlkIO Cgroup 磁盘读写速度 限制容器磁盘IO速率,避免大量读写拖慢宿主机整体性能
Net_cls Cgroup 网络带宽 标记容器网络数据包,配合tc工具限制上下行带宽,防止流量占满

核心结论必须牢记:Docker隔离 = Namespace视图隔离 + Cgroups资源限制。所有容器逃逸、权限绕过漏洞,本质都是突破这两层内核机制中的某一层或多层。理解这个底层逻辑,后面学习容器逃逸、Docker提权时才能真正看懂原理,而不是死记命令。


2 Docker Kali系统标准化安装

2.1 系统残留冲突组件清理

Kali系统自带旧版docker相关组件,版本老旧且容易与官方新版Docker Engine产生端口、服务冲突,安装前必须彻底卸载清理。执行清理命令移除docker.io、docker-doc等系统预装包,同时删除残留配置目录,避免后续启动失败。

bash 复制代码
apt remove docker.io docker-doc docker-compose podman-docker containerd runc -y
rm -rf /var/lib/docker /etc/docker

清理完成后通过apt list --installed | grep docker校验,无任何docker相关输出即代表清理干净。

bash 复制代码
apt list --installed | grep docker

2.2 Docker Engine官方正规安装

不推荐直接使用apt默认仓库的简化版docker,性能与功能存在阉割,渗透靶场编排、自定义镜像构建会出现兼容问题。本节采用Docker官方Deb源完整安装Docker Engine,包含客户端、服务端、容器运行时全套组件。

操作流程分为三步:导入官方GPG密钥校验软件合法性、写入Docker专属软件源、更新索引后批量安装docker-ce、docker-ce-cli、containerd。

bash 复制代码
apt update && apt install ca-certificates curl gnupg lsb-release -y
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update && apt install docker-ce docker-ce-cli containerd.io -y

安装结束执行docker -v查看版本,输出版本号说明安装成功。

bash 复制代码
docker -v

显示如下版本号即为安装成功


2.3 国内镜像源加速器配置

默认从Docker Hub拉取镜像网络延迟极高,大体积漏洞靶场镜像极易出现超时失败,需要配置国内镜像加速器加速拉取。通过修改docker守护进程配置文件/etc/docker/daemon.json写入镜像地址,配置完成重载docker服务生效。

bash 复制代码
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["国内镜像地址"]
}
EOF
systemctl daemon-reload
systemctl restart docker

使用docker info命令查看加速器配置是否加载成功,镜像加速器仅作用于镜像下载,不影响容器网络访问。

bash 复制代码
docker info

能看到这部分说明已经配置好了


2.4 docker用户组权限规范(免sudo安全说明)

docker服务后台进程以root最高权限运行,默认只有root用户能直接调用docker相关命令。普通用户直接执行docker psdocker pull会报权限不足,每次操作都要额外加上sudo,使用十分繁琐。我们可以将当前登录的普通用户加入docker系统用户组,实现免sudo执行所有docker操作。

bash 复制代码
usermod -aG docker $USER
  • usermod:系统修改用户信息工具
  • -aG:将用户追加至指定附属用户组,不覆盖用户原有分组权限
  • docker:系统内置docker专属权限组
  • $USER:环境变量,自动指代当前登录用户名

未执行这条命令前的现象(直接运行docker命令会报错)

直接在终端输入docker ps,终端输出权限拒绝报错,效果如下:

执行这条命令后发生的变化

  1. 系统把你当前登录的普通用户,添加进名为docker的系统权限组;
  2. 当前终端会话权限不立刻更新,此时敲docker命令依然会权限报错;
  3. 注销Kali账户、重新登录系统后,权限完全生效,无需输入sudo就能直接使用所有docker指令(docker pull、docker run、docker ps等)。

    可以看到这里的倒数第二个已经有docker了说明执行成功了

这个时候再次运行docker ps就不会显示权限问题了

安全重点提醒:docker用户组权限等同于半root管理员权限,这是渗透测试必须重视的高危风险点。宿主机的/var/run/docker.sock套接字文件归属于docker组,拥有该组权限即可完全操控容器引擎。一旦运行容器时使用高危挂载参数,攻击者就能突破容器隔离实现容器逃逸,读取、篡改宿主机全部文件,造成内网密钥、渗透报告、账号密码等敏感数据泄露。日常搭建靶场、运行工具时,尽量不要挂载宿主机根目录、docker套接字等高风险路径。


2.5 服务启停与开机自启管理

Docker依托systemd进行服务管理,命令格式与前文学习的systemctl统一。常用操作包含启动、停止、重启docker服务,设置开机自启、取消开机自启。

bash 复制代码
systemctl start docker
systemctl stop docker
systemctl restart docker
systemctl enable docker
systemctl disable docker

实操配置建议:

  1. 必执行开机自启命令 systemctl enable docker

    每次开机自动启动Docker后台服务,无需手动启动,重启机器后靶场、镜像配置全部保留,适合长期做漏洞复现、搭建攻防环境;此时需要输入管理员密码

  2. start/stop/restart属于临时操作,无需提前配置,出现镜像拉取失败、服务异常时再执行重启;

  3. 仅长期不使用容器、离线节省系统资源时,执行systemctl disable docker取消开机自启。

  4. 使用systemctl status docker检测docker是否已经启动了

渗透实操场景:离线环境可临时关闭docker节省内存;长期搭建靶场环境设置开机自启,重启主机后容器自动恢复运行。


2.6 安装报错与环境自检排错

整理Kali安装Docker高频故障:源密钥校验失败、端口被旧组件占用、镜像加速器配置格式错误、用户组权限未生效、服务启动崩溃。

自检流程:查看docker服务状态、读取服务日志journalctl、校验daemon.json语法、核对系统内核版本是否满足最低要求,按流程排查可快速定位绝大多数安装异常。

bash 复制代码
systemctl status docker
journalctl -u docker
  1. systemctl status docker

    直观展示服务启停状态,绿色active (running)代表正常运行;出现红色报错、inactive (dead)说明服务启动失败,可初步判断故障。

  2. journalctl -u docker

    读取systemd记录的Docker完整运行日志,配置文件写错、端口冲突、镜像源解析失败、内核不兼容等底层报错都会完整输出,用于深度排错。


3 Docker 镜像核心管理

3.1 镜像分层存储原理

Docker 镜像采用分层只读存储架构,是镜像的核心底层设计,所有镜像均由多层文件堆叠构成:

  1. 基础底层:操作系统基础文件层(如debian、alpine),本地多个镜像可共享同一基础层,避免重复占用磁盘;
  2. 增量只读层:执行安装软件、修改配置等操作时,仅新增一层只读文件,上层同名文件会覆盖下层,底层原始分层永久不变;
  3. 容器临时读写层:容器启动时,会在镜像最顶层自动生成一层可读写临时层,容器销毁后该读写层同步删除,原始镜像文件完全不受修改影响。

分层存储两大优势:多镜像共享分层节省磁盘;更新镜像仅下载变更分层,大幅提升拉取速度。

通俗大白话解释:

  1. 镜像像搭积木,底层系统积木所有镜像共用,只存一份,不重复占硬盘;

  2. 镜像每一步操作单独做成一层积木,所有积木只能看不能改,新文件直接盖住旧文件,底层原始内容永远不会损坏;

  3. 镜像本身固定不变,只有启动容器时才会多一层临时可修改空间,你在容器里改的所有内容都只存在这一层,删掉容器,修改内容直接消失,镜像完好如初;

  4. 优势总结:共享底层减少磁盘占用,更新镜像只下载改动的分层,不用完整重下,下载速度更快。
    补充:镜像 vs 容器核心区别

  5. 镜像:静态、只读的安装包模板,相当于系统/软件安装光盘,不能运行、无法写入修改;

  6. 容器:基于镜像运行出来的动态实例,相当于装好系统正在运行的电脑,拥有独立可读写临时层,可以修改文件、运行程序;

  7. 关系:一个镜像可以同时启动无数个独立容器;删除容器不会损伤镜像,删除镜像会导致无法再新建容器。


3.2 pull 拉取镜像与标签规范

docker pull 作用:从远程镜像仓库(Docker Hub/私有仓库)下载镜像至本地。

bash 复制代码
docker pull [仓库地址]/镜像名:标签

标签规范说明:

  1. 标签代表镜像版本,不写标签默认拉取 latest(最新版),生产/靶场环境不推荐latest,版本不稳定;
  2. 常用标签:系统版本(ubuntu:22.04)、软件版本(mysql:5.7)、轻量化alpine版(nginx:alpine);

例如:

bash 复制代码
docker pull maven:3.9
docker pull nginx:stable-alpine

这里我们拉去一个docker的hello-world镜像


3.3 images 本地镜像列表完整解析

查看本地全部已下载镜像基础命令:

bash 复制代码
docker images

输出字段解析:

  1. REPOSITORY:镜像仓库/镜像名称;
  2. TAG:镜像版本标签;
  3. IMAGE ID:镜像唯一ID,全局唯一标识镜像;
  4. CREATED:镜像制作时间;
  5. SIZE:镜像占用本地磁盘大小。

现象说明:如果执行docker images后表格空白,代表本地无任何镜像,多为pull拉取镜像失败导致。

拓展查询命令:

显示所有镜像(包含虚悬废弃镜像)

bash 复制代码
docker images -a

仅打印镜像ID,用于批量删除操作

bash 复制代码
docker images -q

过滤查询指定名称镜像

bash 复制代码
docker images nginx

3.4 tag 镜像重命名与私有打标

docker tag 不会复制镜像文件,仅给原有镜像新增别名标签,共享同一分层,不额外占用磁盘。

语法:

bash 复制代码
docker tag 原镜像名:原标签 新镜像名:新标签

实操场景:

  1. 本地镜像重命名:docker tag nginx:stable-alpine mynginx:v1

  2. 私有仓库打标上传:docker tag nginx:stable-alpine 192.168.1.100:5000/nginx:stable-alpine


3.5 rmi 删除镜像

docker rmi 用于删除本地无用镜像,支持「镜像名+标签」「镜像ID」两种删除语法。

  1. 根据镜像名称+标签删除
bash 复制代码
docker rmi 镜像名:标签

例如:docker rmi nginx:stable-alpine

执行 docker rmi nginx:stable-alpine 只输出 Untagged(取消标签绑定),没有删除镜像实体因为还有另外两个标签指向该镜像,底层分层文件依然保留,所以列表里还能看到这条镜像 ID

  1. 根据镜像ID删除(支持短ID)
bash 复制代码
docker rmi 镜像ID

实操示例(本机nginx完整ID)

bash 复制代码
docker rmi 0d3b80406a13

镜像 ID 0d3b80406a13 绑定了2 个不同仓库标签:

192.168.1.100:5000/nginx:stable-alpine、mynginx:v1

普通 docker rmi 镜像ID 无法直接删除多标签镜像,必须加 -f 强制删除。

短ID简写示例(只输入前4位即可识别)

bash 复制代码
docker rmi d561

特性:通过镜像ID删除会一次性解绑该镜像全部标签,无容器占用时直接彻底删除镜像文件,无需逐个删除标签。

  1. 强制删除(镜像被容器占用无法正常删除时加 -f 参数)
bash 复制代码
docker rmi -f 镜像名:标签 / 镜像ID

标签强制删除示例

bash 复制代码
docker rmi -f mynginx:v1

镜像ID强制删除示例

bash 复制代码
docker rmi -f 0d3b80406a13

说明:镜像正在被容器使用时,直接执行 docker rmi 会报错,必须添加 -f 强制清理镜像;不推荐频繁强制删除,优先删除关联容器后再删镜像。


3.6 虚悬/废弃镜像批量清理

虚悬镜像(dangling):镜像名、标签均为,构建镜像残留无用分层,长期堆积占用大量磁盘。

单独清理虚悬镜像:

bash 复制代码
docker image prune

一键清理全部未使用镜像(虚悬+无容器关联的废弃镜像):

bash 复制代码
docker image prune -a

无交互自动清理(脚本批量执行适用,无需手动确认y):

bash 复制代码
docker image prune -a -f

4 Docker 容器核心操作命令

此处为了实验方便我们再次运行docker pull nginx:stable-alpine

4.1 run 容器创建启动(渗透核心指令)

4.1.1 -p 端口映射原理与实操

通用语法

bash 复制代码
-p 宿主机端口:容器端口

示例

bash 复制代码
docker run -p 8080:80 nginx:stable-alpine

容器内部是独立隔离网络,默认外部主机无法直接访问容器内的服务端口;-p 的作用是建立端口转发通道,把宿主机端口流量转发到容器内部端口。

  • 冒号前面 8080 = Kali 宿主机端口,外部浏览器访问 127.0.0.1:8080
  • 冒号后面 80 = Nginx 容器内部服务端口
  • 访问宿主机 8080,流量会自动转发到容器 80 端口,从而打开 Nginx 网页。
    此时终端会显示

4.1.2 -v 数据挂载核心作用

通用语法

bash 复制代码
-v 宿主机目录:容器内目录

示例

bash 复制代码
docker run -v /www:/usr/share/nginx/html nginx:stable-alpine

容器默认数据存在临时读写层,容器销毁则数据全部清空;-v 实现宿主机目录与容器目录双向绑定,文件永久保存在宿主机磁盘,容器删除数据也不会丢失。

-v /www:/usr/share/nginx/html

  • 冒号前面 /www = Kali 宿主机本地文件夹,可直接在系统里修改 html 源码
  • 冒号后面 /usr/share/nginx/html = Nginx 容器存放网页的根目录
  • 宿主机 /www 内的文件会实时同步到容器网页目录,修改文件页面立刻更新。

4.1.3 --name / -d 后台运行参数

-d 后台运行语法

bash 复制代码
docker run -d 镜像名:标签

--name 指定容器名语法

bash 复制代码
docker run --name 自定义容器名 镜像名:标签

组合示例

bash 复制代码
docker run -d --name web-nginx -p 8080:80 nginx:stable-alpine

注意这里直接运行会报错,因为前面已经启动过一次了,用4.2及以后的知识来关掉

4.2 ps 容器状态查看字段解析

基础查看运行中容器

bash 复制代码
docker ps

查看全部容器(含已停止)

bash 复制代码
docker ps -a

仅输出容器ID

bash 复制代码
docker ps -q

4.3 start/stop/restart 容器生命周期控制

启动停止重启通用语法

bash 复制代码
docker start 容器名/容器ID
docker stop 容器名/容器ID
docker restart 容器名/容器ID

停止刚刚运行的两个容器

bash 复制代码
docker stop awesome_meitner
docker stop pedantic_herschel

此时再次运行docker run -d --name web-nginx -p 8081:80 -v /www:/usr/share/nginx/html nginx:stable-alpine

此时删除旧容器

bash 复制代码
docker rm web-nginx

输出 web-nginx,代表名称为 web-nginx 的旧容器已成功删除,名字占用冲突解除。

此时再次运行就好了

使用docker ps检查一遍


4.4 exec 进入容器终端(主流交互方式)

通用语法

bash 复制代码
docker exec -it 容器名/ID 终端解释器

示例

bash 复制代码
docker exec -it web-nginx /bin/sh
bash 复制代码
退出容器回到宿主机
bash 复制代码
exit

可在容器内执行的验证命令

  • 查看网页挂载目录,验证 - v 挂载是否生效
bash 复制代码
ls /usr/share/nginx/html

在宿主机 /www 创建测试页面

bash 复制代码
echo "<h1>测试挂载页面</h1>" > /www/index.html

再次进入容器查看目录

bash 复制代码
docker exec -it web-nginx /bin/sh
ls /usr/share/nginx/html

此时就能看到 index.html 文件

  • 查看 nginx 配置文件
bash 复制代码
cat /etc/nginx/conf.d/default.conf
  • 退出容器回到 kali 宿主机终端
bash 复制代码
exit

alpine 系列镜像无bash,只能使用 /bin/sh 进入交互终端;完整发行版镜像(如普通nginx、centos)才支持 /bin/bash

4.5 attach 交互模式坑点规避

bash 复制代码
docker attach 容器名/ID

① docker attach(不推荐)

作用:直接连上容器前台主进程

缺点:输入 exit 退出终端时,容器主进程直接关闭,容器就停止下线,网站 / 服务直接断。

② docker exec -it(推荐)

作用:新建一个独立的终端窗口,和容器主进程分开

优点:输入 exit 只是退出这个临时终端,容器照常后台运行,不会停机。

4.6 rm 容器删除与批量清理

单容器删除语法

bash 复制代码
docker rm 容器名/ID

说明:仅能删除已停止的容器,运行中容器直接执行会报错

强制删除运行中容器

bash 复制代码
docker rm -f 容器名/ID

说明:-f 强制参数,先停止容器再删除,不用手动执行 stop

批量清理所有停止容器

bash 复制代码
docker container prune

说明:一键清空所有状态为 Exited、Created 的无用容器,不会影响正在 Up 运行的容

首先查看所有容器,确认要删的名字 / ID

bash 复制代码
docker ps -a

发现STATUS中,正在运行的

① Up X hours/minutes

比如 web-nginx:Up 2 hours → 已经持续运行 2 小时,8080 端口正常可访问

② Exited (0) X hours ago

已经停止、下线的废弃容器,图里下面两个都是这种状态:

e5bfd97b5079、2fb906e9d76b 均已停止,没用可以清理

批量一键清理所有 Exited 容器

bash 复制代码
docker container prune

现在列表里只剩 web-nginx 这一个容器,状态 Up 2 hours,正在正常后台运行,8080 端口网页服务可用,其余废弃停用容器全部清理干净。

批量清理命令只会清除停机容器,不会影响正在运行的服务,日常清理垃圾容器非常方便。


5 容器数据持久化与挂载实战

5.1 容器临时数据丢失机制

容器默认所有数据都存储在容器内部的临时读写层,数据生命周期和容器绑定:

  1. 容器运行时,在容器内部新建、修改的文件都保存在读写层;
  2. 容器删除(docker rm)后,读写层随容器一起销毁,所有数据永久丢失;
  3. 容器重建后,恢复为镜像初始状态,之前的修改全部消失。

验证数据丢失实验

  1. 启动一个测试容器,在内部创建文件
bash 复制代码
docker run -d --name test-data nginx:stable-alpine
docker exec -it test-data /bin/sh
echo "测试数据" > /tmp/test.txt
cat /tmp/test.txt
exit

首先我们输入docker images检查一下我们的目录

普通用户已经在 docker 用户组 → 不用 sudo、不用切 root,直接执行所有 docker 命令,不同于上面第4节里面所说的在根目录创建 /www,文件夹归属 root,普通 kali 用户无写入权限,所以当时必须切换到root目录

运行完命令之后可以发现

echo 命令在 /tmp 目录创建 test.txt 文件,cat 命令能正常输出 "测试数据" 三个字,证明文件创建成功

此时这个 test.txt 文件只存在于 test-data 容器的临时读写层中,宿主机磁盘上找不到这个文件,它完全依附于这个容器。


  1. 删除并重建同名容器
bash 复制代码
docker rm -f test-data
docker run -d --name test-data nginx:stable-alpine
docker exec -it test-data /bin/sh
cat /tmp/test.txt

重新 ·docker run· 启动一个同名新容器,返回新的容器 ID,这是一个全新的、干净的容器实例

结果:文件不存在,提示 No such file or directory,证明容器数据不持久化。

结论:网页、配置、数据库、日志等需要长期保存的数据,必须通过挂载持久化到宿主机。


5.2 绑定挂载Bind Mount实操

Bind Mount 直接把宿主机的某个目录映射到容器内部,两边文件实时同步。

通用语法

-v 宿主机绝对路径:容器内路径

实操示例(Nginx网页挂载)

bash 复制代码
docker run -d --name web-nginx -p 8080:80 -v /www:/usr/share/nginx/html nginx:stable-alpine

参数说明

参数位置 示例值 说明
冒号前 /www Kali宿主机本地文件夹路径,文件永久保存在这里
冒号后 /usr/share/nginx/html Nginx容器内网页根目录,容器从这里读取网页文件

验证挂载效果

  1. 宿主机创建网页文件
bash 复制代码
sudo echo "<h1>绑定挂载测试页面</h1>" > /www/index.html
  1. 进入容器查看,文件已同步
bash 复制代码
docker exec -it web-nginx /bin/sh
ls /usr/share/nginx/html
cat /usr/share/nginx/html/index.html
exit
  1. 浏览器访问 http://127.0.0.1:8080,页面显示自定义内容,挂载生效。
优点 缺点
宿主机直接可见、可编辑文件,修改立刻生效 依赖宿主机固定目录,迁移麻烦
适合网页、源码、配置文件等需要频繁修改的场景 普通用户可能遇到目录权限不足(permission denied)

5.3 数据卷Volume管理

Volume 是 Docker 官方推荐的持久化方案,由 Docker 统一管理存储,不依赖宿主机具体目录。

  • Bind Mount:你手动指定宿主机哪个目录,Docker 直接把这个目录映射进容器,目录位置、权限全由你自己控制;
  • Volume:你只需要给卷起个名字,Docker 自动在内部管理目录里创建存储区域,权限、位置全部由 Docker 自动适配,不用手动管。

常用命令

命令 作用
docker volume create 卷名 创建一个数据卷
docker volume ls 查看所有数据卷列表
docker volume inspect 卷名 查看卷的详细信息(存储路径等)
docker volume rm 卷名 删除指定数据卷
docker volume prune 批量清理所有未使用的数据卷
  1. 创建数据卷
bash 复制代码
docker volume create html-data

执行后输出 html-data,代表名为 html-data 的数据卷创建成功。

这一步只是在 Docker 内部注册了一个卷,容器还没启动,卷里是空的。

  1. 查看数据卷列表
bash 复制代码
docker volume ls
  • DRIVER:卷驱动类型,默认是 local 本地存储;
  • VOLUME NAME:卷名,能看到刚才创建的 html-data。

所有数据卷统一由 Docker 管理,不用记宿主机具体路径,通过卷名就能调用。

  1. 使用数据卷启动容器
bash 复制代码
docker run -d --name web-nginx -p 8080:80 -v html-data:/usr/share/nginx/html nginx:stable-alpine

注意:前面实验如果没有删除旧的容器的话会报错,删掉就好了docker rm -f web-nginx

然后再次运行上面的命令

语法和 Bind Mount 几乎一样,区别在于冒号前面不是宿主机路径,而是数据卷的名字;Docker 会自动把 html-data 这个卷映射到容器的 /usr/share/nginx/html 目录。

  1. 查看数据卷详细存储位置
bash 复制代码
docker volume inspect html-data

输出一大段 JSON 格式信息,其中 Mountpoint 字段就是卷在宿主机上的实际物理存储路径,一般在 /var/lib/docker/volumes/html-data/_data 下。

这个路径由 Docker 自动管理,普通用户一般不需要手动进去改文件,所有操作通过容器或 docker volume 命令完成即可;这也是 Volume 和 Bind Mount 最大的区别之一 ------ 你不用关心文件具体存在宿主机哪个文件夹。


验证数据持久化

前置条件

  • 提前创建数据卷:docker volume create html-data
  • 启动容器时挂载卷:-v html-data:/usr/share/nginx/html
  1. 进入容器,在网页目录创建文件
bash 复制代码
docker exec -it web-nginx /bin/sh
echo "<h1>Volume持久化测试</h1>" > /usr/share/nginx/html/index.html
exit

/usr/share/nginx/html 是我们 -v 绑定的挂载目录,不是容器普通临时目录:

你在容器里创建、修改这个目录下的文件,不会存到容器临时读写层,而是直接写入独立数据卷 html-data

数据卷是单独存储单元,生命周期和容器完全分离。

直接在宿主机查看数据卷里存了哪些网页文件,验证我们在容器内创建的index.html真实存在宿主机磁盘

  1. 删除容器,数据卷保留
bash 复制代码
docker rm -f web-nginx
  1. 用同一个数据卷重新启动容器
bash 复制代码
docker run -d --name web-nginx2 -p 8081:80 -v html-data:/usr/share/nginx/html nginx:stable-alpine
  1. 验证文件仍然存在
bash 复制代码
docker exec -it web-nginx2 cat /usr/share/nginx/html/index.html

文件内容保留,证明数据卷独立于容器生命周期。

优点 缺点
Docker统一管理,权限自动适配,不会报权限错误 宿主机不能直接编辑文件,需要进容器操作
不依赖宿主机目录结构,方便迁移、备份 不适合需要频繁在宿主机手动修改文件的场景
适合数据库、缓存等业务数据持久化

5.4 渗透场景挂载风险警示

不当的挂载配置会导致严重的安全问题,是渗透测试中容器逃逸的核心手段。

高危挂载场景

挂载方式 风险等级 危害说明
-v /:/host 极高 宿主机根目录全盘挂载进容器,容器内可读写宿主机所有文件,直接实现容器逃逸
-v /etc/passwd:/etc/passwd 可修改宿主机用户密码文件,新增root权限账号
-v /root/.ssh:/root/.ssh 读取宿主机SSH私钥,远程登录宿主机
-v /var/run/docker.sock:/var/run/docker.sock 极高 容器内可控制宿主机整个Docker服务,创建特权容器实现逃逸

渗透测试利用思路

  1. 发现目标容器挂载了宿主机根目录,直接读取 /host/etc/shadow 破解密码;
  2. 挂载了 docker.sock,在容器内执行 docker 命令创建新的特权容器,接管宿主机;
  3. 挂载了 SSH 目录,导出私钥进行横向移动。

防御建议:生产环境严格限制容器挂载权限,禁止挂载宿主机敏感目录和 docker.sock,使用最小权限原则。


6 Docker 信息排查与取证命令

前置环境说明

  • 存在可操作容器(本章示例统一使用前面实验的 web-nginx / web-nginx2);

当前环境中有 web-nginx2 容器正在运行,端口映射 8081→80,挂载了 html-data 数据卷,本章所有排查命令都以这个容器为例演示。

本章常用命令速查

命令 作用
docker inspect 容器名/镜像名 查看容器/镜像/数据卷的完整底层JSON信息
docker logs 容器名 查看容器运行日志、报错、访问记录
docker logs -f 容器名 实时滚动查看容器日志
docker top 容器名 查看容器内部正在运行的所有进程
docker diff 容器名 对比容器文件与镜像差异,检测文件篡改

6.1 inspect 容器/镜像底层信息解析

docker inspect 是万能详情查看命令,支持查看容器、镜像、数据卷完整底层JSON信息,运维/渗透取证核心命令。

bash 复制代码
# 查看容器全部信息
docker inspect 容器名/容器ID
# 查看镜像全部信息
docker inspect 镜像名:标签
# 查看数据卷信息(5.3用过)
docker inspect html-data

常用重点查看场景

  1. 查看容器挂载信息(验证-v挂载目录)
bash 复制代码
docker inspect web-nginx2 | grep Mounts -A 10

能看到绑定挂载/数据卷映射路径、宿主机真实存储位置。

  1. 查看容器端口映射
bash 复制代码
docker inspect web-nginx2 | grep Ports -A 8
  1. 查看容器IP、网关、网络模式
bash 复制代码
docker inspect web-nginx2 | grep NetworkSettings -A 15
  1. 查看镜像创建时间、环境变量、启动命令
bash 复制代码
docker inspect nginx:stable-alpine

取证用途:可导出完整JSON文件留存证据

docker inspect web-nginx > container-info.json


6.2 logs 容器运行日志查看

容器内程序输出的控制台日志,全部由Docker捕获保存,无需进容器查看日志文件。

常用命令

bash 复制代码
# 查看全部日志
docker logs web-nginx2
# 实时滚动日志(持续刷新,类似tail -f)
docker logs -f web-nginx2
# 只看最新10行日志
docker logs --tail 10 web-nginx2
# 带时间戳输出日志
docker logs -t web-nginx2

以下只展示一张运行结果

实操场景

  1. Nginx访问报错、页面打不开,用logs查看404、500错误;
  2. 容器启动失败,无前台输出,通过日志定位崩溃原因;
  3. 渗透取证:留存网站访问、报错日志,作为流量证据。

6.3 top 查看容器内部进程

无需进入容器,直接查看容器里正在运行的所有进程,排查恶意程序、异常后台进程。

bash 复制代码
docker top web-nginx2

输出内容:PID(宿主机PID)、容器内PID、用户、进程命令。

作用

  1. 快速判断容器运行的程序(nginx、mysql、恶意脚本等);
  2. 发现隐藏后台木马、挖矿进程;
  3. 对比正常进程列表,识别篡改新增程序。

补充:交互式查看动态进程

bash 复制代码
docker exec -it web-nginx2 ps aux
  1. 查看容器内部独立进程 PID
    docker top 显示的是宿主机系统 PID;
    这条命令输出的是容器命名空间内 PID,容器内部进程 1 号是 nginx 主进程,容器重启后 PID 会重置,适合容器内部排查。
  2. 完整查看容器内所有后台程序
    能清晰区分:
    PID 1 root:nginx master 主进程(管理所有子工作进程)
    PID30~37 nginx:nginx worker 工作进程(处理网页访问请求)
    PID38 root:你刚执行的 ps aux 临时进程
  3. 安全取证 / 入侵排查
    如果容器被上传木马、挖矿脚本、后门程序,执行 ps aux 能直接看到异常未知进程,对比正常 nginx 进程列表即可快速发现恶意程序。

和 docker top 的区别

  • docker top:宿主机视角,显示宿主机全局 PID;不进入容器也能执行;
  • docker exec -it xx ps aux:容器内部视角,容器独立 PID,信息更细,适合深度排查。

6.4 diff 检测容器文件篡改痕迹

核心取证命令:对比容器当前文件原始镜像文件层的差异,快速找出新增、修改、删除的文件,判断是否被入侵篡改。

bash 复制代码
docker diff web-nginx2

输出三种标记含义

  1. A = Added:新增文件/文件夹(比如你手动创建的index.html、上传木马)
  2. C = Changed:原有文件被修改(nginx配置、系统文件篡改)
  3. D = Deleted:原有文件被删除(删日志、删系统命令掩盖痕迹)

结合前面实验演示

你在web-nginx容器新增了index.html,执行docker diff web-nginx2会输出:

A /usr/share/nginx/html/index.html

代表该文件是容器运行后新增,不是镜像自带。

实战取证价值

容器被入侵后,黑客会上传后门、修改配置、删除日志,docker diff一键定位所有改动文件,是容器安全排查关键命令。


命令 核心用途 适用场景
inspect 底层配置、挂载、网络、端口全量信息 排查挂载异常、端口冲突、取证容器配置
logs 程序运行日志、报错、访问记录 服务故障排查、网站访问日志取证
top 容器内所有运行进程 排查恶意后台程序、异常进程
diff 文件增删改对比,识别篡改 入侵检测、容器文件篡改取证

7 Dockerfile 自定义渗透镜像


本章常用命令速查

命令 作用
docker build -t 镜像名:标签 . 根据当前目录 Dockerfile 构建自定义镜像
docker build -f 文件路径 -t 镜像名 . 指定 Dockerfile 文件路径构建镜像
docker images 查看本地所有镜像,确认构建结果
docker run -it 自定义镜像名 启动自定义镜像并进入交互模式
docker history 镜像名 查看镜像分层构建历史,验证分层原理

7.1 镜像分层构建原理

Docker 镜像采用分层存储 + 联合文件系统(UnionFS) 机制,每一条 Dockerfile 指令都会生成一个新的镜像层,所有层堆叠组合成最终可用的镜像。

核心特点

  1. 只读层:除最顶层容器读写层外,所有镜像层都是只读的,构建完成后不可修改;
  2. 分层复用:多个镜像可以共享相同的底层(如都基于 ubuntu 基础镜像),节省磁盘空间;
  3. 构建缓存:某一层未发生变化时,后续构建直接复用缓存,大幅提升构建速度;
  4. 增量更新:修改某一层指令,只重新构建该层及之后的所有层,前面的层保持不变。

查看镜像分层历史

bash 复制代码
docker history nginx:stable-alpine

输出按层从上到下排列,每一行对应一层,显示该层的创建指令、大小、创建时间。

渗透场景理解:黑客可以通过 docker history 逆向分析自定义镜像的构建过程,逐层还原镜像里安装了哪些工具、修改了哪些配置,判断镜像是否被植入后门。


7.2 高频指令:FROM/RUN/COPY/CMD 详解

Dockerfile 是纯文本文件,每行一条指令,按顺序从上到下执行,构建出自定义镜像。

四个最核心高频指令对比

指令 执行时机 作用 常见用法
FROM 构建时 指定基础镜像,所有镜像必须以 FROM 开头 FROM ubuntu:22.04
RUN 构建时 在镜像内执行 Shell 命令(安装软件、创建目录等) RUN apt update && apt install -y curl
COPY 构建时 将宿主机文件复制到镜像内部 COPY ./src /app
CMD 运行时 容器启动后默认执行的命令,可被 docker run 覆盖 CMD "/bin/bash"

FROM 指令

必须是 Dockerfile 的第一条指令,指定基于哪个基础镜像构建。

bash 复制代码
FROM kalilinux/kali-rolling

基础镜像选择技巧:做渗透测试镜像优先选 Kali 官方基础镜像,预装大量安全工具;追求体积小选 alpine,只有几 MB。

RUN 指令

构建镜像时执行命令,每一条 RUN 都会生成一个新的镜像层。

bash 复制代码
RUN apt update && apt install -y nmap sqlmap

优化技巧:多条命令用 && 连接写在同一条 RUN 里,减少镜像层数,减小最终镜像体积;

例如:RUN apt update && apt install -y nmap && apt clean

COPY 指令

将宿主机当前目录的文件复制到镜像内部指定路径。

bash 复制代码
COPY ./wordlist.txt /usr/share/wordlists/

冒号前是宿主机相对路径(相对于构建上下文目录),冒号后是镜像内绝对路径。

渗透场景:可以把自己的字典、脚本、EXP 直接打包进镜像,启动容器就能直接用,不用每次重新下载。

CMD 指令

容器启动后默认执行的命令,一个 Dockerfile 只有最后一条 CMD 生效。

bash 复制代码
CMD ["/bin/bash"]

CMD 和 RUN 的区别:

RUN 是构建镜像时 执行,结果固化在镜像里;

CMD 是启动容器时执行,每次 docker run 都会运行,可被命令行参数覆盖。


7.3 build 构建自定义镜像

编写好 Dockerfile 后,使用 docker build 命令执行构建,生成自定义镜像。

基础语法

bash 复制代码
docker build -t 自定义镜像名:标签 .

参数说明

参数 含义
-t 给构建好的镜像打标签(名字:版本号)
. 构建上下文路径,代表当前目录,Docker 会从这个目录找 Dockerfile 和要复制的文件
-f 指定 Dockerfile 文件路径,文件名不叫 Dockerfile 时用

完整流程

新建文件夹,进入目录

bash 复制代码
mkdir kali-build
cd kali-build

创建 Dockerfile 文件,把 FROM/RUN/CMD 全部写进文件

bash 复制代码
cat > Dockerfile <<EOF
FROM kalilinux/kali-rolling
ENV DEBIAN_FRONTEND=noninteractive
RUN apt update && apt install -y nmap sqlmap
CMD ["/bin/bash"]
EOF

执行构建命令读取 Dockerfile 并生成镜像

bash 复制代码
docker build -t kali-pentest:v1 .

构建过程会逐层输出,每一步对应一条指令,显示 Step 1/4、Step 2/4、Step 3/4、Step 4/4,第一行 + Building 114.2s (6/6) FINISHED

FINISHED 代表整套构建流程全部执行完毕,无报错终止

  1. 查看构建好的镜像
bash 复制代码
docker images | grep kali-pentest

能看到 kali-pentest 镜像,标签为 v1

  1. 启动容器验证工具是否安装成功
bash 复制代码
docker run -it --name pentest-test kali-pentest:v1

此处这样就是进入容器了

进入容器后执行

bash 复制代码
nmap --version
sqlmap --version

两个工具都能正常输出版本号,证明镜像构建成功。

退出容器

bash 复制代码
exit

缓存机制说明:第二次构建时,如果前面的指令没修改,会直接显示 Using cache,跳过重复构建,速度非常快;

只有修改了对应层的指令(比如在 RUN 里加新工具),才会从那一层开始重新构建。

知识点 核心要点
分层原理 每条指令生成一层,只读、复用、缓存、增量更新
FROM 指定基础镜像,必须是第一条指令
RUN 构建时执行命令,安装软件、配置环境
COPY 宿主机文件复制进镜像,打包字典/脚本常用
CMD 容器启动默认命令,运行时执行,可被覆盖
build docker build -t 镜像名 . ,根据 Dockerfile 构建镜像
镜像瘦身 apt clean + 删缓存,一条 RUN 装多工具,减小体积
渗透实战 基于 Kali 基础镜像预装工具+打包自定义资源,打造专属便携渗透环境

8 Docker Compose 靶场编排核心

前置环境搭建
安装 Compose V2 插件

bash 复制代码
apt update
apt install docker-compose-plugin -y

校验安装结果

bash 复制代码
docker compose version

出现版本号即安装成功。

测试验证 Compose 可用

  1. 新建测试目录
bash 复制代码
mkdir compose-test
cd compose-test
  1. 编写最简编排文件
bash 复制代码
cat > docker-compose.yml <<EOF
version: "3.8"
services:
  web:
    image: nginx:stable-alpine
    ports:
      - "8085:80"
EOF
  1. 后台启动服务
bash 复制代码
docker compose up -d
  1. 查看运行状态
bash 复制代码
docker compose ps
  1. 浏览器访问验证
    访问 http://127.0.0.1:8085,出现 Nginx 页面代表编排环境搭建完成。

销毁测试环境

场景 1:还要继续用这个靶场,下次接着测(推荐 stop)

docker compose stop

  • 仅停止容器,镜像、容器、数据全部保留
  • 下次直接 docker compose start 启动,数据不变,不用重新拉取镜像

场景 2:测完这个漏洞,要换另一个漏洞(推荐 down,不加 - v)

docker compose down

  • 删除容器 + 专属网络,释放端口
  • 数据库数据卷保留,下次重开数据还在
  • 镜像全程不动,无需重下载

场景 3:漏洞复现失败,需要全新干净环境(down -v)

docker compose down -v

  • 容器、网络、数据库卷全部清空,完全重置环境
  • 镜像依旧本地存在,再次 up 秒启动,不用重新下载
    安装完成后,才可进行后续 yaml 语法、靶场编排实操。

本章常用命令速查表

命令 核心作用
docker compose up -d 后台启动 yml 内全部容器服务
docker compose down 停止并删除容器、网络(保留镜像/数据卷)
docker compose down -v 彻底销毁,连带数据卷一并删除
docker compose logs -f 服务名 实时查看指定靶场服务运行日志
docker compose ps 查看当前编排内所有容器运行状态
docker compose restart 服务名 单独重启某一个靶场服务
docker compose build 重新构建 yml 内自定义镜像

8.1 Compose 适用场景(多服务靶场)

Docker Compose 用于一次性编排、管理一组关联容器,核心解决单条 docker run 无法批量管理多组件靶场的痛点。

核心适用场景(渗透靶场专属)
  1. 多组件漏洞靶场

    绝大多数开源漏洞平台由多服务组成:Web 前端 + MySQL 数据库 + Redis 缓存 + 漏洞应用,单独启动每个容器需要手动配置端口、网络、依赖,Compose 一键启停。

    示例:DVWA、WebGoat、Sqli-Labs、Fastjson 靶场、Vulhub 系列。

  2. 隔离完整渗透环境

    一套 yml 文件定义整套靶场,销毁仅需 down 命令,不会污染本机环境,复现漏洞无残留。

  3. 团队统一靶场环境

    仅需分发 docker-compose.yml 配置文件,所有人一键启动完全一致的漏洞环境,避免环境差异导致漏洞复现失败。

  4. 批量启停、日志统一查看

    无需逐个执行 docker start/stop,一条命令管理全部靶场服务,统一查看所有服务运行日志定位漏洞报错。

不适用场景

单容器独立工具(如之前单 Kali 渗透镜像、单 Nginx 容器),直接使用 docker run 更简洁,无需 Compose。


8.2 yaml 配置文件核心字段解析

编排配置固定命名为 docker-compose.yml,采用 YAML 语法,缩进严格(仅用空格,禁止 Tab)。

基础完整模板

bash 复制代码
cat > docker-compose.yml <<EOF
services:
  mysql:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: target_db
    volumes:
      - mysql-data:/var/lib/mysql
  web:
    image: php:apache
    ports:
      - "8080:80"
    environment:
      DB_HOST: mysql
      DB_USER: root
      DB_PASSWORD: root123
      DB_NAME: target_db
    depends_on:
      - mysql
volumes:
  mysql-data:
EOF
字段 层级 作用(靶场场景)
version 最顶层 声明 compose 语法兼容版本,固定 3.8 通用
services 顶层 所有靶场容器统一入口,子项为单个服务名
image 服务下 指定该服务使用的镜像名:标签
build 服务下 本地 Dockerfile 构建自定义镜像(替代 image)
ports 服务下 端口映射,对外开放靶场访问端口
environment 服务下 注入数据库账号、密钥、配置参数
volumes 服务下 挂载数据卷/本地目录,持久化靶场数据、字典
depends_on 服务下 定义服务启动顺序,先启动数据库再启动 Web
restart 服务下 容器异常自动重启,靶场崩溃自动恢复
volumes 顶层 全局声明持久化存储卷

8.3 up/down/logs 核心编排命令

8.3.1. 启动靶场:docker compose up

前台启动,打印实时日志(调试用,关闭终端容器销毁)

bash 复制代码
docker compose up

后台静默启动(实战靶场必用)

bash 复制代码
docker compose up -d

执行逻辑:自动创建专属网桥网络、拉取镜像、按 depends_on 顺序启动全部容器,端口、环境变量自动绑定。

8.3.2. 销毁靶场:docker compose down

停止容器,删除容器、专属网络;保留镜像、数据卷

bash 复制代码
docker compose down

彻底销毁(连带数据卷一并删除,靶场数据清空)

bash 复制代码
docker compose down -v

渗透测试推荐:漏洞复现完成后执行 down -v,彻底清空靶场残留数据,避免下次复现环境被污染。

8.3.3. 查看日志:docker compose logs

查看全部服务历史日志

bash 复制代码
docker compose logs

实时滚动查看全部服务日志

bash 复制代码
docker compose logs -f

只看指定服务日志(如只看数据库报错)

bash 复制代码
docker compose logs -f mysql

只看最新 20 行日志

bash 复制代码
docker compose logs --tail 20

靶场报错排查:页面打不开、数据库连不上,优先用 logs 查看对应服务报错信息。

8.3.4. 其他常用编排命令
bash 复制代码
查看当前编排所有容器状态
docker compose ps

单独重启某一个服务(如修改配置后只重启 Web)
docker compose restart web

重新构建 yml 内自定义镜像(修改 Dockerfile 后用)
docker compose build

进入指定服务容器交互终端
docker compose exec web /bin/bash

8.4 一键部署开源漏洞靶场实操(Vulhub)

Vulhub 是面向渗透测试人员的开源漏洞靶场集合,全部基于 Docker Compose 编排,包含几百个常见漏洞环境,一键启动、一键销毁,是安全从业者必备工具。

步骤 1:安装 git 工具
bash 复制代码
apt update && apt install git -y
步骤 2:克隆 Vulhub 仓库
bash 复制代码
git clone https://github.com/vulhub/vulhub.git
cd vulhub

仓库包含大量漏洞环境,按漏洞类型分目录存放,每个目录下都有独立的 docker-compose.yml

步骤 3:选择漏洞环境并进入目录

以 ThinkPHP 5 远程代码执行漏洞为例(经典 Web 漏洞):

bash 复制代码
cd thinkphp/5-rce
步骤 4:查看编排配置文件
bash 复制代码
cat docker-compose.yml

可以看到配置文件中包含 version、services、image、ports 等字段,和 8.2 学过的核心字段完全对应,每个漏洞环境都是一个独立的多服务编排。

步骤 5:一键启动漏洞环境
bash 复制代码
docker compose up -d

首次启动会自动拉取漏洞镜像,等待拉取完成。

步骤 6:查看服务运行状态
bash 复制代码
docker compose ps

服务 STATE 显示 Up,代表漏洞环境启动成功。

步骤 7:访问漏洞页面验证

浏览器打开 http://127.0.0.1:8080

出现 ThinkPHP 默认页面代表靶场启动成功,可以开始漏洞复现练习。

步骤 8:销毁漏洞环境
bash 复制代码
docker compose down -v

使用技巧:

  1. 每个漏洞目录独立,切换漏洞只需进入新目录执行 up -d
  2. 复现完成后务必执行 down -v 彻底清理,避免端口冲突和资源占用;
  3. Vulhub 覆盖 Web、PWN、中间件、数据库等各类漏洞,后续渗透学习可直接按需启动对应环境。

本章核心总结

知识点 核心要点
Compose 作用 一键编排管理多容器服务,解决多组件靶场部署痛点
yaml 语法 缩进严格、空格替代 Tab,version/services/volumes 三大顶层
核心字段 image/ports/environment/volumes/depends_on/restart
up 命令 启动全部服务,-d 后台运行
down 命令 停止销毁,-v 连带删除数据卷彻底清空
logs 命令 统一查看服务日志,-f 实时滚动,排查靶场报错
靶场实战 Vulhub 仓库 → 进入漏洞目录 → docker compose up -d,三步部署任意漏洞环境

9 Docker 安全风险与渗透攻防要点

9.1 docker组权限逃逸原理与防御

  1. 用户加入 docker 用户组后,无需 sudo 即可执行 docker run、docker exec 等全部容器操作;
  2. Docker Daemon 以 root 权限运行,通过挂载宿主机目录可直接读写宿主机任意文件;
  3. 逃逸核心 payload:
bash 复制代码
docker run -v /:/mnt --rm -it alpine chroot /mnt bash

进入容器后等价拿到宿主机最高权限,可读取密码哈希、写入 ssh 公钥、篡改 sudoers。

防御方案

  1. 非运维用户禁止加入 docker 组,执行 docker 必须 sudo;
  2. 开启 Docker 授权认证,限制普通用户访问 daemon 套接字 /var/run/docker.sock;
  3. 生产环境禁用无限制目录挂载,使用只读挂载 -v xxx:/data:ro;
  4. 审计容器启动命令,监控 -v /:/mnt 类高危挂载行为。

9.2 挂载宿主机目录高危漏洞

风险场景

  1. 高危挂载 1:挂载 docker.sock,容器内可创建、篡改容器,完全接管宿主机 Docker 服务;
bash 复制代码
-v /var/run/docker.sock:/var/run/docker.sock
  1. 高危挂载 2:挂载宿主机根目录、/etc、/root、ssh 密钥目录;
  2. 高危挂载 3:挂载 sudoers、crontab 定时任务目录,提权持久化;
  3. 业务漏洞延伸:Web 容器挂载网站源码目录,文件上传 / 路径穿越可写入宿主机后门。

防御

  1. 禁止挂载 docker.sock,必须使用则配置容器细粒度权限隔离;
  2. 业务目录统一只读挂载 :ro,拒绝读写系统敏感路径;
  3. 使用容器运行时限制:AppArmor / Seccomp,阻断危险挂载参数;
  4. CI/CD 镜像构建阶段校验 compose 配置,拦截高危挂载字段。

9.3 容器内信息搜集与环境探测

  1. 基础环境探测
bash 复制代码
# 查看容器内部用户、权限
id; cat /etc/passwd

# 查看挂载(重点寻找宿主机敏感目录挂载)
mount

# 查看环境变量(数据库密码、密钥、宿主机IP常泄露)
env

# 查看网络,探测宿主机、内网其他容器IP
ip a; netstat -antp
  1. Docker 专属特征探测
  • 判断是否在容器:存在 /.dockerenv 文件;
  • 读取容器元数据:/proc/1/cgroup,识别容器 ID、镜像名;
  • 读取宿主机文件(若存在挂载):/mnt/etc/shadow、ssh 私钥;
  • 查看容器启动命令,寻找明文密钥、代理地址。
  1. 内网横向探测
    容器共享宿主机网卡或 docker 网桥,可扫描同网段容器、宿主机端口,攻击数据库、Redis、内网 Web 服务。

9.4 容器逃逸基础前置认知

逃逸核心前置条件(至少满足其一)

  1. 危险挂载:挂载宿主机根目录、docker.sock、定时任务目录;
  2. 内核漏洞:宿主机 Linux 内核存在 Dirty Cow、CVE-2022-0811 等容器逃逸内核漏洞;
  3. 容器权限过高:启动参数添加 --privileged 特权模式,拥有设备读写权限;
  4. 配置缺陷:未限制 capabilities,保留 CAP_SYS_ADMIN 等高危权限;
  5. 镜像漏洞:容器内存在可提权 SUID 程序、可控挂载点、恶意插件。

前置探测清单(渗透时优先验证)

  1. 是否特权容器:capsh --print 查看权限集;
  2. 是否挂载宿主机敏感路径;
  3. 宿主机内核版本,匹配对应逃逸 CVE;
  4. 是否可读写 /dev 下设备文件;
  5. 是否存在可控 mount 操作、用户自定义挂载。

基础防御前置规范

  1. 生产容器禁止 --privileged;
  2. 清理多余 Linux Capability,仅保留业务必需权限;
  3. 定期更新宿主机内核,修复容器逃逸类内核漏洞;
  4. 禁用容器内动态挂载设备,限制 mount 系统调用。

总结

Docker 是基于 Linux Namespace 和 Cgroups 的轻量容器技术,共享宿主机内核、启动秒级、开销极低,在渗透场景中既是快速搭建 Vulhub 等漏洞靶场、容器化运行 Kali/MSF/SQLMap 等工具的基础设施,也是红蓝对抗中容器逃逸、挂载漏洞、docker 组权限提升等攻防手法的重要战场,核心围绕镜像、容器、仓库三要素展开,配合数据卷持久化和 Docker Compose 多服务编排,就能完成从环境部署到漏洞复现的全流程,而安全防御的关键在于遵循权限最小、挂载最小、能力最小三原则,禁用特权模式、严控敏感目录挂载、限制普通用户操作 Docker。

相关推荐
孟郎郎2 小时前
AI 辅助开发编程敏感信息保护安全规范
人工智能·安全·ai·风险·隐患
iDao技术魔方2 小时前
Node.js v26.5.0 深度解读:import Text、流式 ReadableStreamTee、以及隐藏的安全加固浪潮
安全·node.js
阿米亚波3 小时前
【EVE-NG 实战】防火墙基础(VLAN · VRRP · NAT · ACL · 静态路由)
运维·网络·笔记·网络协议·计算机网络·网络安全·运维开发
SizeTheMoment3 小时前
Spring Cloud 微服务认证体系深度解析:从架构设计到安全实践
安全·spring cloud·微服务
日取其半万世不竭3 小时前
云服务器迁移怎么少停机?DNS 切换前后的完整清单
运维·服务器
FREEDOM_X3 小时前
Linux 多线程编程——总结
java·linux·运维·ubuntu
名字还没想好☜4 小时前
Docker 多阶段构建:把镜像从 1.2GB 砍到 15MB
运维·docker·容器·多阶段构建·镜像优化
祸心依旧4 小时前
Visual Studio 五月更新 —— 计划、评审、优化
运维·人工智能·visual studio
Web4Browser4 小时前
Headless 浏览器自动化适合哪些任务?巡检、截图和提交动作要分级
运维·前端·自动化