一个使用 Terraform 部署在 DigitalOcean droplet 上的 SSH/Telnet 蜜罐栈。攻击由 Cowrie 捕获,存储在 Loki 中,并在 Grafana 中可视化,附带攻击来源的实时世界地图。
honeypot/
├── cowrie/
│ └── etc/
│ ├── cowrie.cfg # Cowrie honeypot configuration
│ └── userdb.txt # Accepted and rejected fake credentials
├── docs/
│ └── ttp-to-runtime-rules.md # Observed attacker TTPs → Falco rules (eks-gitops, platform-engineering-lab)
├── geoip/
│ └── .gitkeep # Placeholder - MMDB files are gitignored
├── grafana/
│ ├── provisioning/
│ │ ├── dashboards/
│ │ │ ├── dashboards.yml # Provisioning: dashboard provider
│ │ │ └── honeypot-dashboard.json # Pre-built Attack Monitor dashboard
│ │ └── datasources/
│ │ └── loki.yml # Auto-provisioned Loki datasource
│ └── grafana.ini # Grafana server settings
├── loki/
│ └── config.yml # Loki single-binary config and retention
├── metrics/
│ ├── runtime-metrics.schema.json # Shared schema — identical across all 4 portfolio projects
│ └── runtime-metrics.json # Generated by scripts/export-honeypot-metrics.sh; gitignored, not committed
├── promtail/
│ └── config.yml # Promtail scrape and GeoIP pipeline
├── scripts/
│ ├── geoip-update.sh # Download or refresh GeoIP database
│ ├── setup-firewall.sh # Host UFW rules for honeypot ports
│ ├── export-honeypot-metrics.sh # Queries Grafana/Loki, writes attacker_telemetry
│ └── emit-runtime-metrics.py # Wraps attacker_telemetry in the shared metrics schema
├── terraform/
│ ├── templates/
│ │ ├── cloud-init.yaml.tftpl # Droplet first-boot script (Terraform-templated)
│ │ └── env.tftpl # .env lines embedded via Terraform
│ ├── backend.tf # Terraform backend config
│ ├── main.tf # Droplet, SSH key, firewall, cloud-init
│ ├── outputs.tf # IPs and helpful post-apply values
│ ├── terraform.tfvars.example # Example variable values (copy to terraform.tfvars)
│ ├── variables.tf # Terraform input variables
│ └── versions.tf # Terraform and provider version constraints
├── .env.example # Example environment file for manual setup
├── .gitignore # Ignored paths and files
├── .gitlab-ci.yml # CI/CD pipeline: fmt, validate, Checkov, metrics schema/export
├── docker-compose.yml # Docker Compose file for the honeypot stack
├── LICENSE # GPLv2 license
├── manual-deployment.sh # Legacy VM bootstrap without Terraform
└── README.md # Project documentation
## 硬件要求
> 注意:这些要求基于截至 2026 年 5 月的 DigitalOcean Basic Droplet 方案,是运行该项目的最低要求。
- 提供商:DigitalOcean
- 方案:Basic Droplet - 1 Intel vCPU
- 内存:1 GB(+2 GB swap)
- 存储:35 GB NVMe SSD
- 操作系统:Ubuntu 24.04 LTS
> **容器版本升级后的内存余量:** `docker-compose.yml` 固定了比该 droplet 规格最初调优时更新的 Grafana(12.0.0)、Loki 和 Promtail(3.6.13)镜像。每个服务的 `mem_limit`/`memswap_limit` 值保持不变——首次部署后请留意 `docker stats`,如果任何容器持续接近其限制,请升级 droplet 方案(或缩减 Loki 的 `retention_period` / Grafana 的缓存)。
## 安装与设置
>注意:安装完成后,建议打开一个新终端,在关闭原始会话之前,验证你仍然可以通过 `ADMIN_SSH_PORT`(默认:2022)进行 SSH 连接。
### Terraform 部署(推荐)
1. 创建一个具有读写权限的 DigitalOcean API 令牌:
- 登录 DigitalOcean 并导航至 Account > API > Tokens > Generate New Token。
- 为你的令牌命名(例如 "Cowrie Honeypot")并选择 "Full Access" 权限。
- 点击 "Generate Token" 并将令牌值复制到安全位置(你将无法再次看到它)。
2. 在本地机器上创建 SSH 密钥对并复制公钥路径。
3. 进入 `terraform` 目录,然后复制并编辑变量文件:
> 注意:在应用之前,至少必须在 `terraform.tfvars` 中配置 `do_token`、`ssh_public_key_path` 和 `grafana_admin_password`。```bash
cd terraform
cp terraform.tfvars.example terraform.tfvars
注意:您的本地机器上必须安装 Terraform。请访问 Terraform 安装指南 获取说明。```bash terraform init # Initialize Terraform and download providers terraform apply
5. 如果测试通过 - 使用替换方式重新部署:```bash
terraform apply -replace="digitalocean_droplet.honeypot"
### 手动部署(旧版)
1. 使用上述硬件要求及您的 SSH 密钥创建一个 DigitalOcean droplet。
2. 通过 SSH 登录到该 droplet,或使用 DigitalOcean 网页控制台,并运行以下命令:```bash
ssh root@<your-droplet-ip> # If using DigitalOcean web console, skip this command
git clone https://gitlab.com/Oseguera12/cowrie-honeypot-digitalocean.git /opt/honeypot
cd /opt/honeypot
cp .env.example .env
nano .env
bash manual-deployment.sh
注意:默认情况下,Terraform 会将状态写入本地机器上的
terraform/terraform.tfstate。该文件包含敏感的输出值(droplet IP、Grafana 密码、SSH 密钥指纹),绝不能提交到版本库。.gitignore已覆盖*.tfstate和*.tfstate.*。
本地状态的风险:
apply 运行可能会损坏该文件对于个人实验环境之外的任何场景,请切换到远程后端。terraform/backend.tf 包含一个已注释掉的 DigitalOcean Spaces 配置(兼容 S3)。
要启用远程后端:
terraform.tfvars): ```bash
export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
terraform/backend.tf 中取消注释 backend "s3" 块,并填入你的存储桶名称和区域端点。terraform init -migrate-state 将现有的本地状态迁移到 Spaces。.gitlab-ci.yml 在每次推送时于 validate 阶段运行四个作业,并在 metrics 阶段运行一个手动作业:
| 作业 | 工具 | 用途 |
|---|---|---|
terraform:fmt | hashicorp/terraform:1.8 | 格式检查:如果有任何文件需要 terraform fmt,则失败 |
terraform:validate | hashicorp/terraform:1.8 | 在不连接 DigitalOcean 的情况下验证配置有效性 |
checkov:scan | bridgecrew/checkov:latest | 检查 Terraform 代码中的 IaC 错误配置 |
validate-metrics-schema | python:3.12-slim | 验证 metrics/runtime-metrics.schema.json 格式正确;如果存在已提交的 metrics/runtime-metrics.json,则根据该 schema 对其进行验证 |
export-metrics(手动) | python:3.12-slim | 参见下方的运行时指标 |
注意:
terraform:fmt和terraform:validate在失败时会阻塞流水线。checkov:scan被设置为allow_failure: true,因为某些发现是有意做出的权衡。请使用内联# checkov:skip=CKXXX注释来抑制特定的可接受发现,而不是完全禁用该作业。
CKV_DIO_4(“确保防火墙入站规则未完全开放”)会针对整个 digitalocean_firewall 资源触发一次。它通过在 terraform/main.tf 中资源块内放置的单条 # checkov:skip=CKV_DIO_4: 注释被抑制。下表记录了每个开放端口为何是有意为之。