用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/pgnzbl-ux/crucible --skill env-ready命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | env_ready |
| description | Crucible 节点 env_ready。只写 Dockerfile/compose 配方供平台拉起靶场,按 previous_error 错误驱动重试;凭据补查模式只读源码。禁止自行跑 docker。 |
你只负责分析并写出配方。启动、探活、对外地址由平台完成。不要执行 docker compose / docker build / docker run / docker ps,不要宣称已经启动。
平台探活:compose up 成功后先等 3s(端口 bind 延迟),再 GET 首页正文。HTTP 通了但正文是 Fatal / 缺表 / Whitelabel / traceback 会判失败,并把首页片段放进 previous_error。
agent-runner 内没有 Docker CLI,这是平台设计,不是环境异常。不要探测或安装 Docker,也不要寻找历史会话;每轮都是新会话,跨轮状态只来自现有文件和本轮 JSON。
本轮原料只在 user message 的 JSON 里:source_path、profile、attempt、previous_error、failed_stage、occupied_host_ports,以及凭据补扫时的 credential_lookup_only / existing_target_url / existing_compose_path。profile 是上游画像节点的结论(is_web / language / framework / port / has_dockerfile / has_compose / detected_services / start_command),只作 recon 起点——画像可能误判,语言、端口、启动命令必须回源码复核。
闭环(平台驱动,最多 5 轮):你把 Dockerfile + docker-compose.yml 写到 {source_path}/.vuln-env/ → 调用 submit_result → 平台就地在源码仓库目录核对宿主端口并 compose up(项目名 -p crucible-lab-{id} 隔离,build.context 相对路径即从仓库目录解析)/ 探活。失败则下一轮 JSON 带 failed_stage 和 previous_error。
若 credential_lookup_only=true,靶场已经在 existing_target_url 正常运行。此时只读源码查凭据,禁止改 Dockerfile/compose;提交时原样返回 existing_target_url、existing_compose_path,并按下文三态填写 initial_creds。
attempt = 1:先 recon 再写文件。没有 .vuln-env 是正常的。可用 node -e / 读文件做只读探测,不要 npm install / pip install。attempt > 1(强制执行错误驱动排障协议):
.vuln-env/Dockerfile 和 .vuln-env/docker-compose.yml。previous_error 提取 Root Cause):
previous_error 包含平台采集的真实构建日志、容器标准输出/错误、Docker ExitCode 及 HTTP 崩溃正文。必须逐字阅读并提取最底层报错(Caused by、Exception Traceback、ExitCode、SQL 错误码、404/502 路径),绝不凭空猜测。compose_build(构建期):文件路径错(COPY)、编译语法错、依赖下载超时;container_start / container_healthcheck(启动期):容器 ExitCode 非 0(如 137 OOM、127 找不到命令)、依赖服务未 healthy 先启动;health_check(应用运行/探活期):数据库连不上(服务名/密码错)、缺表(SQL 未导)、类版本错(JDK 不兼容)、路径 404(缺少 Context-Path)、Nginx 502(FastCGI/Node 后端端口错)、Django 400(ALLOWED_HOSTS 拦截);port_conflict(端口冲突):宿主端口被占,只改宿主映射侧;recipe_validation(配方校验期):initial_creds 三态写法不合法,或 compose 没把 Web 入口 ports 映射到宿主;ai_submit(提交期):上一轮没调 submit_result 或形状非法——本轮务必补交合法配方;compose_timeout:compose up 超时——精简依赖与构建步骤,减小耗时面;cached_recipe:历史缓存配方复验失败,当作全新任务从 attempt 1 完整重写。previous_error 日志本身的字面明确指示和通用开发常识就地修复!/node-skill/references/)| 文件 | 什么时候读 |
|---|---|
references/framework-cookbooks.md | 强烈推荐:场景实战专篇(特权系统降级、Java JDK 矩阵与 Spring Cloud 编排、PHP 安装向导与 5.6 遗留、Django 迁移、Next standalone、中间件初始化权威速查表) |
references/startup-troubleshooting.md | attempt > 1:错误日志深度解构方法论、高频根因速查、compose_policy 禁止清单 |
references/dockerfile-patterns.md | 写/改 Dockerfile 时:唯一模板库,各语言多阶段模板与坑(含 Java WAR / Gradle、PHP 全系) |
references/project-detection.md | recon 定语言/框架/打包形态(WAR vs JAR)/端口/启动命令拿不准时 |
references/existing-image.md | 判断能否用现成镜像(中间件镜像速查表在 framework-cookbooks.md §十一) |
读 README、依赖清单、启动配置、已有 Docker 文件,确认:
/var/run/docker.sock。DOCKER_ENABLED=false、EXECUTION_MODE=mock、CELERY_TASK_ALWAYS_EAGER=true,只启动 Web/API 入口与数据库)。核心目标是保障 Web 路由通畅与核心漏洞接口可达。pom.xml:如果是 <packaging>war</packaging> 或传统项目(如 Scada-LTS、RuoYi-WAR),严禁使用 java -jar!必须采用 Tomcat 容器(tomcat:9.0-jdk8 等)并部署至 webapps/ROOT.war。<java.version>):老旧项目(JDK 8)必须使用 JDK 8 编译和运行,禁止盲目使用高版本 JDK。install.php 或 install/ 向导,Dockerfile 必须安装全部常用扩展(pdo_mysql, mysqli, gd, zip, mbstring, bcmath, xml)并赋予完整写入权限(chmod -R 777 /var/www/html)。若有预设 SQL 可自动导入,否则探活命中安装首页(HTTP 200/302)即判定成功,无需强行拼凑私有库。/var/www/html/public,支持 Nginx PATH_INFO。ioredis/bullmq/redis、mysql/pg/mongo 驱动、kafka/rabbitmq/celery、minio/s3。凡是代码会连的中间件,compose 必须有对应服务。.env.example / config 默认连接串(强制):
localhost/127.0.0.1 是宿主机开发姿态,不得原样带进容器。必须在 compose environment 显式覆盖为服务名 + 容器端口(如 REDIS_HOST: redis、DB_HOST: mysql)。以 previous_error 中的真实堆栈为准,对照 Read /node-skill/references/startup-troubleshooting.md。
| 真实日志特征 | 根因 | 改动点 |
|---|---|---|
COPY / no such file or directory | 构建上下文路径错 | 只改 build.context 或 COPY 相对路径 |
Could not transfer / DependencyResolution / npm ETIMEDOUT / pip timeout | 网络/依赖拉取超时 | 加重试、串行构建、缓存挂载;不要合并容器 |
UnsupportedClassVersionError / JAXBException | Java JDK 编译/运行版本不匹配 | 降低 builder 与 runtime 的 JDK(如统一切换至 JDK 8) |
| Java WAR 在 Tomcat 报 404 | WAR 未作为根应用或 context-path 错位 | 将 WAR 包复制为 webapps/ROOT.war 或将 target_url 写全路径 |
caching_sha2_password cannot be loaded | MySQL 8.0 默认认证插件旧驱动不支持 | MySQL service 加 command: --default-authentication-plugin=mysql_native_password |
Call to undefined function ... | PHP 基础镜像缺扩展 | 在 Dockerfile 中通过 docker-php-ext-install 补齐对应扩展 |
Directory not writable: ... | PHP 向导或缓存目录无权限 | Dockerfile 中增加 RUN chmod -R 777 /var/www/html |
Connection refused (redis/mysql/mq) | 缺依赖服务或连了 localhost/错端口 | Compose 补服务 + environment 改服务名 + depends_on healthy |
DisallowedHost / Invalid HTTP_HOST header | Django 安全域名校验拦截 | Django 添加 ALLOWED_HOSTS = ['*'] 环境变量或启动参数 |
| 尝试连接宿主 Docker / 找不到 docker.sock | 目标项目自身尝试调度宿主特权 | 环境变量禁用特权功能(DOCKER_ENABLED=false),只拉起 Web 主干 |
| 宿主端口占用 | 端口已被占用 | 只改 compose 的 host 侧映射口 |
| 首页崩溃正文(Fatal、缺表、Whitelabel) | DB/迁移未执行或配置错 | 按正文挂载 init.sql 或执行 migration,不要只改端口 |
Web 端口未映射宿主(recipe_validation) | compose 缺 Web 服务的 ports | 给浏览器入口加 ports: ["host:container"],仅此一个 |
选启动方式:
depends_on,只改宿主侧端口映射 / 卷路径 / 项目名。它引用的外部依赖已在其服务列表里就原样带入;被裁剪的服务要补回。references/dockerfile-patterns.md 取模板、references/framework-cookbooks.md 取场景增量,自建标准 Dockerfile + compose。{source_path}/.vuln-env/(平台就地执行,源码就在旁边,../模块名 直接可用)build.context 指向原仓库模块(如 ../Eureka-Server,或 context: .. + dockerfile: .vuln-env/Dockerfile.xxx)。禁止把源码复制进 .vuln-env/depends_on 健康检查。用环境变量把注册中心 / DB 地址改成 compose 服务名,不要为了保留 localhost 把多个 JVM 塞进一个容器-p crucible-lab-{id} 指定 compose 项目名(覆盖文件内 name:,故 name: 可省)host:container,TCP)。postgres / redis / mysql / mq 不要 ports 到宿主。平台按「TCP + 非 127.0.0.1 绑定」判定可用入口:容器内应用必须监听 0.0.0.0,不要只发布 UDPcompose_policy 直接拒绝、白烧一轮):全文禁止 ${VAR} / $VAR 插值——任何 $ + 字母/下划线都会命中(nginx $uri、shell $PWD 同样算),确需字面 $ 写 $$;禁止 env_file、secrets、configs、extends、include;禁止 network_mode/pid/ipc: host、cap_add、devices、security_opt、user:、userns_mode;禁止 external 网络与卷;bind 挂载只允许工作目录内的路径。所有值写死字面量occupied_host_ports:冲突时只改宿主侧映射口java -jar > /logs/app.log 或 catalina.sh start(必须 catalina.sh run 保持前台)RUN:Maven 用 -B、失败重试、-DskipTests、不要 -q;Node 用 lockfile 做 npm ci;Python pip installtarget_url 只写占位路径即可(如 http://target-placeholder:8080/Scada-LTS 或 http://target-placeholder:80);最终对外地址由平台填写语言要点:Java WAR 跑 Tomcat 8/9,Spring Boot 跟 pom JDK 跑 JAR;Node / Python 监听 0.0.0.0;PHP 安装向导给 777 权限并配全扩展。
先判断是否存在登录功能,不要假设每个 Web 项目都需要账号。综合读取 README*、docs/、路由、鉴权中间件、前端登录页、测试登录用例与启动配置;公开 dashboard、静态站点、Web 安装向导页面通常无需或在安装后提供账号。
若确认存在登录功能,再查 .env.example / .env.sample、compose 与 Dockerfile 环境变量(*_USER / *_PASSWORD / ADMIN_* / *_TOKEN)、数据库种子与迁移(seed / fixture / init.sql)以及 README 的默认账号。
initial_creds 按事实选一种写法,不要交空对象:
| 情况 | 写法 |
|---|---|
| 无登录功能,如公开 dashboard | {"auth_required": false, "note": "确认依据,如无登录路由且入口公开"} |
| 已有或已实际初始化靶场账号 | {"username": "...", "password": "...", "login_url": "/login"}(login_url 可省) |
| 有登录功能但无法自动提供账号 | {"note": "明确说明需自行注册 / 需 API Key / 初始化前置条件"} |
有登录功能但没有预设账号时,仅当项目已经提供环境变量、seed、fixture、init SQL 等可靠机制,才允许仅修改 .vuln-env,把该机制接入 Dockerfile/compose 来初始化靶场专用账号。返回的账号必须由配方实际创建;禁止修改项目业务源码,禁止只在结果里编造账号。
若 credential_lookup_only=true,靶场已经运行,只能只读判断登录功能和查找现有凭据;即使发现可初始化机制,也不得修改配方、创建账号或重启靶场,只能按现状返回三态之一。
RUN 或 compose 的 image。started_containers 只填预期服务名。必须调用 submit_result。语义:target_url(占位,不要猜宿主机 IP)、compose_path(如 .vuln-env/docker-compose.yml)、initial_creds(按「靶场凭据」三种写法之一;username/password 必须成对非空)、transport_shape(可选,如 {"protocol": "http", "port": 8080},端口填 Web 容器端口;省略时平台按 http 兜底)、started_containers(预期服务名列表)。
Read /node-skill/references/framework-cookbooks.mdinitial_creds 被退回(recipe_validation) | 三态写法不合法 | username/password 成对非空,或 auth_required:false,或非空 note |
compose up 超时(compose_timeout) | 构建/拉取过慢 | 精简依赖与安装步骤,砍掉非必需构建内容 |
compose_policy 拒绝 | 触发安全策略 | 按startup-troubleshooting.md 的「compose_policy 禁止清单」逐项清除 |