trailofbits/dropkit

GitHub: trailofbits/dropkit

一款面向安全研究者和运维人员的 DigitalOcean droplet 命令行管理工具,将创建、SSH 配置、Tailscale 组网和休眠省钱等全生命周期操作自动化为简洁的命令行体验。

Stars: 100 | Forks: 13

# dropkit 一个用于管理 DigitalOcean droplet 的命令行工具,支持自动设置、SSH 配置和生命周期管理。 ## 功能 - 🚀 **快速创建 droplet**,支持 cloud-init 自动化 - 🔑 **自动 SSH 配置** - 只需运行 `ssh dropkit.` - 🔐 **Tailscale VPN** - 通过 Tailscale 安全访问(默认启用) - 👤 **用户管理** - 自动在 droplet 上创建您的用户账户 - 🏷️ **智能标签** - 按所有者组织 droplet,便于过滤 - 🔒 **安全第一** - SSH 密钥验证,对破坏性操作进行确认提示 - 📊 **精美的 CLI** - 漂亮的表格、进度指示器和有用的错误信息 - 🔄 **完整的生命周期** - 轻松创建、列出、调整大小和销毁 droplet - 💤 **休眠/唤醒** - 通过创建快照并销毁来节省成本,随后可使用一条命令恢复 ## 前置条件 - **Python 3.11+** - 拥有 API token 的 **DigitalOcean 账户**([在此创建](https://cloud.digitalocean.com/account/api/tokens)) - **SSH 密钥对**(通常是 `~/.ssh/id_ed25519.pub` 或 `~/.ssh/id_rsa.pub`) - **uv** 包管理器([安装说明](https://github.com/astral-sh/uv)) - **Tailscale**(可选但推荐)- 从 [tailscale.com/download](https://tailscale.com/download) 安装 ## 安装 ``` # HTTPS 或 SSH,取决于你的 GitHub 设置 uv tool install git+https://github.com/trailofbits/dropkit.git uv tool install git+ssh://git@github.com/trailofbits/dropkit.git # 升级 uv tool upgrade dropkit ``` ## 快速开始 ### 1. 初始化配置 运行初始化向导: ``` dropkit init ``` 这将验证您的 DigitalOcean API token,检测 SSH 密钥并将其注册到 DigitalOcean,并让您选择默认值(输入 `?` 获取帮助以查看可用选项)。 ### 2. 创建您的第一个 Droplet ``` # 交互模式 - 提示输入 name、region、size、image(输入 ? 获取帮助) dropkit create # 或者指定 name 并使用默认值 dropkit create my-first-droplet # 分配给特定的 project(通过 name 或 ID) dropkit create my-droplet --project "My Project" # 不创建 Tailscale VPN 创建 dropkit create my-droplet --no-tailscale ``` 该工具将会: 1. 创建 droplet 并等待其进入活跃状态 2. 自动添加 SSH 配置 3. 等待 cloud-init 完成 4. **Tailscale 设置**(默认启用): - 显示一个认证 URL,供您在浏览器中进行身份验证 - 使用您的 Tailscale IP 更新 SSH 配置 - 锁定防火墙,仅允许 Tailscale 流量 ### 3. 通过 SSH 连接 ``` ssh dropkit.my-first-droplet ``` 您的用户账户已经设置好并配置了您的 SSH 密钥。 ## 可用命令 ``` Usage: dropkit [OPTIONS] COMMAND [ARGS]... Manage DigitalOcean droplets Commands: init Initialize dropkit configuration. create Create a new DigitalOcean droplet with cloud-init configuration. list List droplets and hibernated snapshots tagged with owner:. config-ssh Configure SSH for an existing droplet. info Show detailed information about a droplet. rename Rename a droplet (requires confirmation). destroy Destroy a droplet or hibernated snapshot (DESTRUCTIVE). resize Resize a droplet (causes downtime - requires power off). on Power on a droplet. off Power off a droplet (requires confirmation). hibernate Hibernate a droplet (snapshot and destroy to save costs). wake Wake a hibernated droplet (restore from snapshot). enable-tailscale Enable Tailscale VPN on an existing droplet. list-ssh-keys List SSH keys registered via dropkit. add-ssh-key Add or import an SSH public key to DigitalOcean. delete-ssh-key Delete an SSH key registered via dropkit. version Show the version of dropkit. ``` 使用 `dropkit --help` 获取任何命令的详细帮助。 ## 配置 配置文件存储在 `~/.config/dropkit/` 中: - **`config.yaml`** - 主配置文件(API token、默认值、SSH 密钥) - **`cloud-init.yaml`** - Cloud-init 模板(可自定义) ### 默认标签 所有 droplet 都会自动打上以下标签: - `owner:` - 您的 DigitalOcean 账户用户名(从邮箱派生) - `firewall` - 用于安全组标识 ### 项目 - 在执行 `dropkit init` 期间**设置默认项目**(输入 `?` 查看可用项目) - 在执行 `dropkit create` 时使用 `--project ` **按 droplet 覆盖** - 通过名称或 UUID 指定;支持 Tab 补全 ### SSH 主机名约定 所有 SSH 配置条目均使用前缀 `dropkit.`: - 使用以下命令连接:`ssh dropkit.my-droplet` ### Shell 补全 在您的 shell 中为 droplet 名称启用 Tab 补全: **Zsh(推荐):** ``` dropkit --install-completion zsh ``` **Bash:** ``` dropkit --install-completion bash ``` 安装后,请重启您的 shell。Tab 补全会动态从 DigitalOcean 获取您的 droplet: ``` dropkit info # Shows your droplets dropkit destroy # Shows your droplets dropkit resize # Shows your droplets dropkit on # Shows your droplets dropkit off # Shows your droplets ``` ### 休眠与唤醒(节省成本) DigitalOcean 对已停止的 droplet 仍按完整的每小时费率收费。为避免产生此费用,请使用休眠/唤醒功能: ``` # Hibernate:快照 droplet 并销毁它(停止计费) dropkit hibernate my-droplet # Wake:从 snapshot 恢复 droplet dropkit wake my-droplet # 删除已休眠的 snapshot 而不恢复 dropkit destroy my-droplet ``` **工作原理:** 1. `hibernate` 关闭 droplet,创建一个快照(`dropkit-`),然后销毁该 droplet 2. `wake` 从快照创建一个具有相同区域和规格的新 droplet 3. 快照会被标记为 `owner:` 和 `size:` 以便追踪 4. 唤醒后,系统会提示您删除快照(默认:是) **注意:** 快照按 $0.06/GB/月 计费,这通常比保持 droplet 运行要便宜得多。 ### Cloud-Init 自定义 编辑 `~/.config/dropkit/cloud-init.yaml` 以自定义用户设置、软件包安装、防火墙规则和 shell 配置。该模板使用带有 `{{ username }}` 和 `{{ ssh_keys }}` 变量的 Jinja2 语法。 ## 故障排除 ### “未找到 Config。请先运行 'dropkit init'” 请初始化配置: ``` dropkit init ``` ### Cloud-init 失败或超时 请手动检查 cloud-init 状态: ``` ssh dropkit.my-droplet 'sudo cloud-init status' ssh dropkit.my-droplet 'sudo cat /var/log/cloud-init.log' ``` 使用 `--verbose` 标志查看详细输出: ``` dropkit create my-droplet --verbose ``` ### “未找到带有 tag owner: 的 Droplet” 该 droplet 可能属于其他人。请列出您的 droplet: ``` dropkit list ``` ## 开发 ### 运行单元测试 ``` uv run pytest # All tests uv run pytest -v # Verbose output uv run pytest -k "pattern" # Filter by name ``` ### 运行 E2E 测试 E2E 生命周期测试会创建一个真实的 droplet,验证 SSH 连接, 并将其销毁。它作为 prek 的 `manual` 阶段 hook 注册——请在推送 影响核心工作流的更改之前运行。 ``` ./tests/e2e/test_lifecycle.sh # Run directly prek run --stage manual # Run via prek ``` 需要一个包含 DigitalOcean API token 的有效 dropkit 配置(`~/.config/dropkit/config.yaml`)。 该测试使用硬编码的默认值(nyc3、s-1vcpu-1gb、ubuntu-24-04-x64),因此用户配置的 默认值不会影响测试行为。 可选的环境变量覆盖:`DROPLET_NAME`、`DROPLET_REGION`、 `DROPLET_SIZE`、`DROPLET_IMAGE`、`E2E_SSH_TIMEOUT`。 ## 技术栈 - **CLI 框架**:[Typer](https://typer.tiangolo.com/) - 现代 CLI 框架 - **UI/显示**:[Rich](https://rich.readthedocs.io/) - 终端格式化 - **API 客户端**:[requests](https://requests.readthedocs.io/) - HTTP 库 - **配置**:[Pydantic](https://docs.pydantic.dev/) - 数据验证 - **模板引擎**:[Jinja2](https://jinja.palletsprojects.com/) - Cloud-init 模板 - **包管理器**:[uv](https://github.com/astral-sh/uv) - 快速 Python 包管理器 - **代码质量**:Ruff (linter/formatter) + ty (type checker) ## 附录:API Token 权限 ### 创建您的 Token 1. 前往 [DigitalOcean API Tokens](https://cloud.digitalocean.com/account/api/tokens) 2. 点击 **Generate New Token**,命名为 "dropkit-cli" 3. 选择 **Custom Scopes**(推荐)或 **Full Access**(更简单) 4. 对于自定义范围,请启用下面列出的 23 个范围 ### 必需范围(共 23 个) `account:read`, `actions:read`, `droplet:create`, `droplet:read`, `droplet:update`, `droplet:delete`, `image:create`, `image:read`, `image:update`, `image:delete`, `project:read`, `project:update`, `regions:read`, `sizes:read`, `snapshot:read`, `snapshot:delete`, `ssh_key:create`, `ssh_key:read`, `ssh_key:update`, `ssh_key:delete`, `tag:read`, `tag:create`, `vpc:read` ### 功能范围参考 | 功能 | 必需范围 | |---------|----------------| | **初始化配置** | `account:read`, `regions:read`, `sizes:read`, `image:read`, `ssh_key:read`, `ssh_key:create`, `project:read` | | **创建 droplet** | `droplet:create`, `project:update`, `actions:read`, `tag:create` | | **列出 droplet** | `droplet:read`, `snapshot:read`, `tag:read` | | **显示 droplet 信息** | `droplet:read` | | **销毁 droplet** | `droplet:delete`, `snapshot:delete` | | **重命名 droplet** | `droplet:update` | | **调整 droplet 规格** | `droplet:update`, `sizes:read`, `actions:read` | | **开机/关机** | `droplet:update`, `actions:read` | | **休眠** | `droplet:update`, `droplet:delete`, `snapshot:create`, `actions:read`, `tag:create` | | **唤醒** | `droplet:create`, `snapshot:read`, `snapshot:delete` | | **管理 SSH 密钥** | `ssh_key:read`, `ssh_key:create`, `ssh_key:update`, `ssh_key:delete` | 更多信息,请参阅 [DigitalOcean API Token Scopes 文档](https://docs.digitalocean.com/reference/api/scopes/)。
标签:API管理, cloud-init, DigitalOcean, Python, SSH配置, Tailscale, uv包管理器, VPN, 云基础设施, 云服务器管理, 休眠与唤醒, 字符串匹配, 安全配置, 快照, 无后门, 服务器生命周期, 特权提升, 用户管理, 自动化部署, 虚拟专用网, 运维工具, 逆向工具