在 Proxmox VE 上部署 Vulhub 时,遇到“启动失败”,多数应先查 Ubuntu 客户机内的 Docker 与 Compose。排查时重点看 Docker 服务状态、Compose V2 插件、当前目录和启动日志;容器正常后仍打不开,再检查端口发布和隔离网络路径。按这个顺序逐层排查,通常比重装 PVE 或虚拟机更快。最短的判断链是在 Ubuntu 客户机内依次执行 systemctl status docker --no-pager 与 docker compose version,随后进入目标环境目录,依次运行 docker compose config、docker compose up -d、docker compose ps 和 docker compose logs --tail=100 以定位异常。
systemctl status docker 用来确认守护进程是否正常,docker compose version 用于确认 Compose V2 插件可用,docker compose config 用于检查当前目录中的 Compose 配置。命令执行后,若守护进程未运行应先启动 Docker,普通用户连接 socket 被拒绝则需处理用户组权限,提示找不到 Compose 配置意味着目录不对。容器显示 Running 但网页打不开时,再检查端口发布和隔离网络。新部署统一使用 docker compose,不再与旧文章里的 docker-compose 写法混用。
Proxmox VE 官方说明,其 Web 界面可以统一管理虚拟机、容器、存储和网络。本文沿用“Proxmox VE + Ubuntu + Docker”的部署组合,但把 PVE 隔离边界、Ubuntu 内部故障和靶场访问路径分开处理。
准备 Ubuntu 客户机并验证 Docker Compose
先在 Proxmox VE Web 界面中创建一台 Ubuntu 客户机,不要把 Vulhub 直接部署到 PVE 宿主机。具体菜单路径、网卡类型、网桥、VLAN 和集群网络配置会随 PVE 版本及现有网络结构变化,不能照搬固定路径或网络参数。部署时应让客户机与生产网络隔离,只为管理终端保留必要的访问路径,同时为 Docker 拉取镜像保留相应的出站能力。
本文以 Ubuntu 22.04 为参考环境。参考资料中的 1GB 内存只是搭建单个环境的建议,不是所有 Vulhub 场景的统一门槛;资源需求仍要根据目标环境说明和实际日志判断。使用其他 Ubuntu 版本时,应先核对当前 Docker 对该版本的支持情况。
在客户机内安装基础工具和 Docker Engine:
sudo apt update
sudo apt install -y curl git
curl -fsSL https://get.docker.com -o get-docker.sh
less get-docker.sh
sudo sh get-docker.sh
这里采用参考资料中的 Ubuntu 安装步骤,但脚本会联网下载并执行安装逻辑,下载后应先查看内容;正式操作时仍以 Docker 当前官方安装说明为准。安装完成后启用服务并验收:
sudo systemctl enable --now docker
docker version
docker info
docker run --rm hello-world
docker compose version
docker version 和 docker info 用于确认客户端能正常获取服务端信息,hello-world 则进一步验证镜像拉取、容器创建和运行链路。docker compose version 只说明 Compose V2 插件已经安装,不代表 Docker 服务一定正常,因此前面的服务状态检查不能省略。
如果当前 Docker 安装没有附带 Compose V2 插件,应补装插件,而不是先走旧版 Python docker-compose 路线:
sudo apt update
sudo apt install docker-compose-plugin
docker compose version
该命令以 Docker 的 Ubuntu 软件源已经正确配置为前提;如果提示找不到软件包,应回到当前官方安装说明补齐软件源及插件。参考资料也指出,Compose V2 已作为 Docker 子命令提供,旧 Python 版 docker-compose 已进入弃用阶段。
接着获取 Vulhub,并进入一个具体漏洞环境:
git clone https://github.com/vulhub/vulhub.git
cd vulhub
find . -maxdepth 2 -type f \( -name 'compose.yaml' -o -name 'compose.yml' -o -name 'docker-compose.yaml' -o -name 'docker-compose.yml' \)
cd <environment>
ls -la
less README.md
docker compose config
先阅读目标目录里的说明文件和 Compose 配置,再决定是否改端口、账号或其他参数。不要把别的环境配置直接复制到仓库根目录,因为相对路径、服务名称和项目名称都可能随目录变化而改变。仓库根目录通常也不是可以直接启动的漏洞环境。
不同环境可能直接拉取已经构建好的镜像,也可能要求先在本地构建。只有目标环境说明明确需要构建,并且 Compose 配置中确有对应 build 定义时,再执行:
docker compose build
随后启动并查看状态:
docker compose up -d
docker compose ps
docker compose up -d 失败,按服务、权限和目录逐层排查
最常见的“无法连接 Docker daemon”通常与 Compose 文件无关,先检查服务:
systemctl is-active docker
systemctl status docker --no-pager
sudo systemctl start docker
sudo journalctl -u docker -n 100 --no-pager
如果服务不是 active,先启动 Docker,再看 journalctl 中的初始化错误。PVE 中的 Ubuntu 客户机是普通 Linux 虚拟机,应优先使用 systemd 管理 Docker。参考资料中的 sudo service docker start 主要针对 WSL2 无法正常连接 Docker 守护进程的场景,不适合当作 PVE 客户机的通用首选方案。
如果错误信息包含 permission denied 或提示无法连接 Docker socket,可以用两条命令对比:
sudo docker ps
docker ps
带 sudo 正常而不带 sudo 失败,说明问题在当前用户访问 Docker socket 的权限,而不是容器本身。此时处理用户组和登录会话:
sudo usermod -aG docker "$USER"
newgrp docker
usermod 不会立即刷新已经存在的登录会话。newgrp docker 只对当前启动的子 Shell 生效,重新登录后才会稳定生效。
如果提示 docker compose 不是可用命令,先确认插件是否存在:
docker compose version
docker compose config
docker-compose version
即使机器上还保留着旧版 docker-compose,也应统一使用 docker compose。两套命令并存时,最容易出现的问题是参数、项目目录和项目名称解析行为不一致,而不是简单地“哪个命令能运行就用哪个”。
如果提示找不到 Compose 配置,检查当前工作目录和文件:
pwd
ls -la
Vulhub 的启动文件通常位于具体漏洞环境目录。先 cd 到包含 Compose 文件和说明文件的目标目录,再运行 docker compose config。如果配置已经找到,但 config 仍然报变量缺失或 YAML 无效,则继续根据报错检查目标环境要求的环境变量和配置格式,不要通过删除配置来绕过检查。
镜像拉取或构建失败时,应把网络、DNS、镜像仓库和 CPU 架构分开排查。可以先单独执行拉取操作:
docker compose pull
如果目标环境需要本地构建,再单独执行:
docker compose build
拉取超时时,先确认 Ubuntu 客户机能够解析镜像仓库域名并建立 HTTPS 连接:
getent ahosts registry-1.docker.io
curl -v --connect-timeout 5 https://registry-1.docker.io/v2/
判断重点是域名解析、TLS 连接和 HTTP 响应是否建立,不要把仓库返回的认证或限流状态误判为网络完全不可达。确实受网络限制时,可以在 /etc/docker/daemon.json 中配置可信的镜像加速地址:
sudo mkdir -p /etc/docker
sudo nano /etc/docker/daemon.json
{
"registry-mirrors": [
"https://<可信镜像加速地址>"
]
}
如果该文件已经存在,应合并配置而不是覆盖原有内容,同时保证 JSON 格式有效。修改后重启并检查:
sudo systemctl restart docker
docker info
日志明确提示架构不匹配时,再比较客户机和 Docker 服务端架构:
uname -m
docker info --format '{{.Architecture}}'
此时需要核对目标镜像支持的架构以及 PVE 客户机实际提供的 CPU 架构。不要在不清楚镜像支持范围时直接增加模拟选项,因为模拟是否可用还取决于客户机 CPU 和虚拟化配置。
如果启动时提示宿主端口已被占用,先查监听端口和进程:
sudo ss -lntp
docker compose config
在 Compose 配置中找到对应的 ports 映射,把发布到宿主机的端口改为当前未被占用的端口,然后重新启动。反复删除容器不会释放一个仍被其他进程占用的端口。端口调整也应尽量遵循目标环境说明,避免把容器内部端口误当成 Ubuntu 客户机的发布端口。
容器显示 Running 仍打不开,分开检查应用和隔离网络
Running 只说明容器主进程仍在运行,不等于应用已经完成初始化,也不等于外部访问路径已经打通。先把容器状态、日志和监听端口放在一起看:
docker compose ps -a
docker compose logs --tail=200
sudo ss -lntp
如果日志中已经出现应用启动错误、依赖服务连接失败或进程反复退出,应先解决应用层问题。端口没有监听时,也需要回到日志确认是应用尚未启动,还是启动后立即退出。
目标环境提供 HTTP 服务时,先在 Ubuntu 客户机本机访问发布端口:
curl -v --connect-timeout 5 http://127.0.0.1:<published-port>/
这里应使用 Compose 文件发布到 Ubuntu 客户机上的端口,而不是容器内部端口。协议、路径和账号也应以该环境的 README 为准。
本机测试结果可以继续缩小排查范围。若返回 HTTP 状态码,即使状态不是成功,也说明 TCP 连接和 HTTP 服务已经能够响应,接下来应检查访问路径、认证和页面行为。若连接被拒绝,通常说明该地址上没有监听进程,或者端口只绑定在其他地址。若连接超时,暂时不能仅凭这一项判断是应用卡住还是网络路径被过滤,还要结合日志、监听地址和防火墙配置继续确认。
如果本机访问成功,再从允许访问该网络的管理终端测试:
curl -v --connect-timeout 5 http://<ubuntu-vm-ip>:<published-port>/
这里应填写 Ubuntu 虚拟机 IP。参考资料特别提醒,Vulhub 说明里的 your-ip 在虚拟机环境中指虚拟机地址,而不是 Docker 容器内部 IP。
“本机成功、远程失败”时,在 Ubuntu 客户机检查地址和路由:
ip -brief addr
ip route
随后核对四类条件。首先确认管理终端访问的是客户机当前实际使用的 IP。其次检查 Compose 端口是否发布到了客户机,以及是否只绑定在 127.0.0.1。第三,确认管理终端到隔离网段是否存在路由或允许的访问路径。最后,检查客户机自身防火墙是否拦截了管理网来源。
如果启用了 UFW,可以再检查其状态:
sudo ufw status verbose
PVE 侧则要回到该客户机实际接入的网络和管理策略,确认隔离边界与预期一致。不要仅凭某个桥接或 NAT 名称就认定隔离已经完成,因为具体网络对象和访问路径取决于 PVE 版本、集群配置及上层网络设计。
实验结束,或者修复配置后需要重新创建环境时:
docker compose down
docker compose up -d
down 会停止并移除当前 Compose 环境;确认不需要保留项目卷后,才执行:
docker compose down -v
带 -v 的清理会继续移除项目卷,适合重置实验数据,不能当成日常重启命令。即使清理了容器和卷,Ubuntu 客户机及 Vulhub 源码仍然存在。
Vulhub 故意包含脆弱服务,只能用于隔离测试环境,不能作为生产服务使用,也不应直接暴露到公网。











暂无评论内容