使用
juiceshop-stack.yaml部署测试环境 部署前需要完成三个手动步骤:创建 ECR + 推镜像、创建 ACM 证书 + DNS 验证、查询 Prefix List ID
第 1 步:设置部署参数(1 分钟)
第 2 步:创建 ECR 仓库并推送镜像(5 分钟)
第 3 步:创建 ACM 证书并完成 DNS 验证(5-10 分钟)
第 4 步:查询 CloudFront Prefix List ID(1 分钟)
第 5 步:部署 CloudFormation Stack(10-15 分钟)
第 6 步:在 Cloudflare 添加 CNAME 指向 CloudFront(2 分钟)
第 7 步:验证部署(1 分钟)
第 8 步:在 Security Agent 中验证域名(5 分钟)
ECR 仓库和 ACM 证书在 Stack 外部管理,避免部署时阻塞或冲突。
⚠️ 以下所有步骤必须在同一个终端 session 中执行。如果终端断开,需要重新执行第 1 步设置变量。
# 部署 Region(ECR、Stack、ACM 必须在同一个 Region)
DEPLOY_REGION="us-east-1"
# 域名(替换为你自己的域名)
DOMAIN_NAME="security-test.example.com"
# ECR 仓库名
ECR_REPO_NAME="juiceshop"
# 账户 ID(自动获取)
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
ECR_URI="${ACCOUNT_ID}.dkr.ecr.${DEPLOY_REGION}.amazonaws.com/${ECR_REPO_NAME}"
echo "Region: ${DEPLOY_REGION}"
echo "Account: ${ACCOUNT_ID}"
echo "ECR URI: ${ECR_URI}"# 创建 ECR 仓库
aws ecr create-repository --repository-name ${ECR_REPO_NAME} \
--tags Key=Project,Value=juiceshop-security-test Key=Environment,Value=test \
--region ${DEPLOY_REGION}推送镜像有两种方式,选一种即可:
方式 A:本地 Docker 推送(需要本地安装 Docker,且能访问 Docker Hub)
docker pull bkimminich/juice-shop:latest
aws ecr get-login-password --region ${DEPLOY_REGION} | \
docker login --username AWS --password-stdin ${ECR_URI%%/*}
docker tag bkimminich/juice-shop:latest ${ECR_URI}:latest
docker push ${ECR_URI}:latest方式 B:使用 AWS CloudShell 推送(推荐,无需本地 Docker,不受网络限制)
如果本地拉取 Docker Hub 镜像超时(国内网络常见),可以用 AWS CloudShell 操作:
- 打开 AWS Console → 右上角点击 CloudShell 图标(
>_) - 等待 CloudShell 启动后,执行以下命令:
# 在 CloudShell 中执行(CloudShell 自带 Docker 和 AWS CLI)
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
ECR_URI="${ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/juiceshop"
docker pull bkimminich/juice-shop:latest
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${ECR_URI%%/*}
docker tag bkimminich/juice-shop:latest ${ECR_URI}:latest
docker push ${ECR_URI}:latestCloudShell 在 AWS 内部网络,拉取 Docker Hub 镜像和推送 ECR 都很快。如果部署到其他 Region,把命令中的
us-east-1替换为对应 Region。
验证镜像推送成功:
aws ecr describe-images --repository-name ${ECR_REPO_NAME} --region ${DEPLOY_REGION} \
--query 'imageDetails[0].{PushedAt:imagePushedAt,SizeBytes:imageSizeInBytes,Tags:imageTags}'预期输出包含 "Tags": ["latest"] 和推送时间,说明镜像已就绪。
# 创建证书
CERT_ARN=$(aws acm request-certificate \
--domain-name ${DOMAIN_NAME} \
--validation-method DNS \
--tags Key=Project,Value=juiceshop-security-test \
--region ${DEPLOY_REGION} \
--query 'CertificateArn' --output text)
echo "Certificate ARN: ${CERT_ARN}"
# 等几秒让 ACM 生成验证信息
sleep 10
# 查看需要添加的 DNS 记录
aws acm describe-certificate --certificate-arn ${CERT_ARN} --region ${DEPLOY_REGION} \
--query 'Certificate.DomainValidationOptions[0].ResourceRecord'在 DNS 提供商中添加验证记录:
- 进入你的 DNS 管理面板 → Add Record
- Type: CNAME
- Name: 从上面输出的 Name 字段中取子域名部分(如
_abc123.security-test) - Target: 上面输出的 Value 字段
- 如果使用 Cloudflare,Proxy status 设为 DNS only(灰色云朵)
# 等待证书验证通过
aws acm wait certificate-validated --certificate-arn ${CERT_ARN} --region ${DEPLOY_REGION}
echo "证书验证通过: ${CERT_ARN}"CF_PL=$(aws ec2 describe-managed-prefix-lists \
--filters Name=prefix-list-name,Values=com.amazonaws.global.cloudfront.origin-facing \
--query 'PrefixLists[0].PrefixListId' --output text --region ${DEPLOY_REGION})
echo "CloudFront Prefix List ID: ${CF_PL}"# 生成 Origin 验证密钥
ORIGIN_SECRET=$(openssl rand -hex 16)
# 部署(注意:--template-body 的路径是相对于当前目录的,确保在项目根目录执行)
aws cloudformation create-stack \
--stack-name juiceshop \
--template-body file://juiceshop-stack.yaml \
--capabilities CAPABILITY_NAMED_IAM \
--parameters \
ParameterKey=OriginVerifySecret,ParameterValue=${ORIGIN_SECRET} \
ParameterKey=CloudFrontPrefixListId,ParameterValue=${CF_PL} \
ParameterKey=CertificateArn,ParameterValue=${CERT_ARN} \
ParameterKey=EcrRepositoryName,ParameterValue=${ECR_REPO_NAME} \
--region ${DEPLOY_REGION}
echo "Stack 创建中...(约 10-15 分钟)"
# 等待完成
aws cloudformation wait stack-create-complete --stack-name juiceshop --region ${DEPLOY_REGION}
echo "Stack 创建完成"如果失败:
aws cloudformation describe-stack-events --stack-name juiceshop --region ${DEPLOY_REGION} \
--query 'StackEvents[?ResourceStatus==`CREATE_FAILED`].[LogicalResourceId,ResourceStatusReason]' --output table# 查看 Stack 输出
aws cloudformation describe-stacks --stack-name juiceshop --region ${DEPLOY_REGION} \
--query 'Stacks[0].Outputs' --output table找到 CloudFrontDomainName 的值(如 d1234abcd.cloudfront.net)。
在 DNS 提供商中操作:
- Add Record
- Type: CNAME
- Name:
security-test(即域名的子域名部分) - Target:
d1234abcd.cloudfront.net(替换为实际值) - 如果使用 Cloudflare,Proxy status 设为 DNS only(灰色云朵)
⚠️ 如果使用 Cloudflare,必须关闭代理(灰色云朵),否则 CloudFront SSL 证书会冲突。
# 通过 CloudFront 访问(预期 200)
curl -I https://${DOMAIN_NAME}
# 直接访问 ALB(预期超时,因为安全组只允许 CloudFront IP 访问,你的 IP 会被静默丢弃)
# 等几秒没响应就 Ctrl+C 中断,说明安全组配置正确
ALB_DNS=$(aws cloudformation describe-stacks --stack-name juiceshop --region ${DEPLOY_REGION} \
--query 'Stacks[0].Outputs[?OutputKey==`ALBDnsName`].OutputValue' --output text)
curl -I --connect-timeout 5 http://${ALB_DNS}
# 预期输出:curl: (28) Connection timed outJuice Shop 测试账号:
| 账号 | 密码 | 角色 |
|---|---|---|
| admin@juice-sh.op | admin123 | 管理员 |
| jim@juice-sh.op | ncc-1701 | 普通用户 |
如果你的账号已经有 Agent Space,跳过这一步。
- AWS Console → 搜索 Security Agent
- 点击 Set up Security Agent
- 输入 Agent Space 名称,如
pentest-lab - 选择访问方式:
- IAM Identity Center(SSO):适合团队使用,支持精细权限管理
- IAM-only:适合个人测试,通过管理员链接访问 Web App
-
⚠️ 此选择不可逆。选了 IAM-only 后无法再切换为 IAM Identity Center。如果未来可能需要 SSO,建议一开始就选 IAM Identity Center。
- 完成设置,等待 Agent Space 状态变为 Active(约 1-2 分钟)
创建完成后,Security Agent Web Application 会自动生成。
域名验证在 Agent Space 内进行。进入第 8 步创建的 Agent Space 后操作。
- AWS Console → Security Agent → 选择你的 Agent Space
- Add domain → 输入你的域名
- 选择 DNS TXT 验证,获取验证值
在 DNS 提供商中添加 TXT 记录:
- Type: TXT
- Name: 从 Security Agent Console Target domains 表格中 DNS Record Name / Route Path 列复制(不要自己拼,以 Console 显示的为准)
- Content: 从 Security Agent Console 复制的 Verification token 值
- Proxy status: DNS only
- Save
回到 Console 点击 Verify。通过后即可创建渗透测试。
分两步:先删 Stack,再删 Stack 外部的资源。
# 1. 先删 DNS 记录(避免悬空 DNS)
# 手动删除:CloudFront CNAME、Security Agent TXT、ACM 验证 CNAME
# 2. 删除 Stack(一键删除所有 Stack 内资源)
aws cloudformation delete-stack --stack-name juiceshop --region ${DEPLOY_REGION}
aws cloudformation wait stack-delete-complete --stack-name juiceshop --region ${DEPLOY_REGION}
echo "Stack 已删除"
# 3. 删除 Stack 外部资源
# 如果终端变量已丢失,先查找 ARN:
# aws acm list-certificates --region ${DEPLOY_REGION}
aws ecr delete-repository --repository-name ${ECR_REPO_NAME} --force --region ${DEPLOY_REGION}
aws acm delete-certificate --certificate-arn ${CERT_ARN} --region ${DEPLOY_REGION}| 问题 | 原因 | 解决 |
|---|---|---|
| ECS Service 创建失败 | ECR 里没有镜像 | 确认第 2 步镜像推送成功,且 Region 一致 |
| Stack 回滚 | 查看 Events 里的失败原因 | describe-stack-events 查看详情 |
| CloudFront 访问 502 | ECS Task 还没启动完成 | 等几分钟,检查 Target Group 健康状态 |
| 直接访问 ALB 没有超时 | 安全组可能配置错误 | 检查 ALB 安全组是否只允许 CloudFront Prefix List |
| 部署到其他 Region 拉不到镜像 | ECR 和 Stack 不在同一 Region | ECR 创建和推镜像的 Region 必须和 Stack 一致 |