osmedeus 云编排引擎 Hetzner 提供商实战指南:低成本分布式安全扫描
【免费下载链接】osmedeusA Modern Orchestration Engine for Security项目地址: https://gitcode.com/GitHub_Trending/os/osmedeus
本指南以 osmedeus 开源仓库的 Hetzner Provider Guide 为主体,结合仓库内 Hetzner 提供商源码与云端配置实现,系统讲解如何在 Hetzner Cloud 上运行 osmedeus 分布式扫描集群。读完本文,你将掌握 API Token 获取、云端配置项逐字段含义、服务器类型与机房选择、osmedeus cloud run全套实战命令(含自定义命令管道、批量目标分发、结果回传、自动销毁),并能理解其底层 Pulumi 资源编排、成本限额与生命周期管理的实现原理。
为什么选择 Hetzner 作为扫描集群
Hetzner 是所有 osmedeus 支持的云厂商中单实例成本最低的,非常适合大批量、高频次的扫描场景。官方文档给出的对比结论是:同等规格下 Hetzner 约为 DigitalOcean 的 1/3 价格、AWS 的 1/6 价格。由于扫描任务天然可横向拆分(把目标列表分给多个 worker 并行处理),Hetzner 的廉价实例能显著压低"跑一批目标"的总账单——例如在 cx22 上单实例单小时仅约 $0.007,一次快速域名侦察往往不足 1 美分。
从仓库源码看,osmedeus 通过统一的 Provider 接口 抽象所有云厂商,Hetzner 是其中完整实现的一员(registry.go 中将其注册为ProviderHetzner)。整个云端功能由 cloud CLI 驱动,底层依赖 Pulumi 的 Go SDK 进行资源编排(详见 云端实现说明)。
前置条件与 API Token 获取
使用 Hetzner 提供商前,需要准备以下三样东西:
- 一个 Hetzner Cloud 账户(登录 https://console.hetzner.cloud)
- 一个 API Token(Read & Write 权限)
- 一对本地 SSH 密钥(默认路径
~/.ssh/id_rsa与~/.ssh/id_rsa.pub)
获取 API Token
在 Hetzner Cloud Console 中按以下步骤创建 Token:
- 进入Hetzner Cloud Console,选择(或新建)你的 Project
- 进入Security>API Tokens>Generate API Token
- 权限选择Read & Write
- 复制 Token(仅显示一次,请立即保存)
建议把 Token 存入环境变量,便于后续配置命令引用,也避免明文出现在 shell 历史中:
export HETZNER_API_TOKEN="your-token-here"从源码看,osmedeus 的云端配置文件支持${ENV_VAR}语法,加载配置时会把环境变量自动展开(config.go),所以你也可以在配置文件中直接写${HETZNER_TOKEN}来引用。
云端配置:从最小可用到逐项精调
最小可用配置
osmedeus cloud config set命令使用点号(dot notation)定位配置项,以下是官方文档给出的最小配置序列,逐条写入cloud-settings.yaml:
# 启用云端功能 osmedeus config set cloud.enabled true # 凭据与默认参数 osmedeus cloud config set providers.hetzner.token ${HETZNER_API_TOKEN} osmedeus cloud config set providers.hetzner.location hel1 osmedeus cloud config set providers.hetzner.server_type "cx23" # 2 vCPU, 4GB RAM(当前代) osmedeus cloud config set defaults.provider hetzner # SSH osmedeus cloud config set ssh.private_key_path ~/.ssh/id_rsa osmedeus cloud config set ssh.public_key_path ~/.ssh/id_rsa.pub osmedeus cloud config set ssh.user root # 先清空预置的 setup 脚本 osmedeus cloud config set setup.commands.clear "" # Worker 初始化脚本(按顺序执行) osmedeus cloud config set setup.commands.add "sudo apt-get update" osmedeus cloud config set setup.commands.add "sudo apt-get install -y -qq curl git tmux unzip jq rsync" osmedeus cloud config set setup.commands.add "curl -fsSL https://www.osmedeus.org/install.sh | bash" osmedeus cloud config set setup.commands.add "osmedeus install base --preset"几点说明:
setup.commands.clear ""用于先清空配置模板里预置的示例命令(模板中以#注释的占位行),随后用setup.commands.add追加真实命令。CLI 支持从文件或标准输入批量写入:osmedeus cloud config set --from-file cloud-config.txt或cat cloud-config.txt | osmedeus cloud config set --from-file -(cloud.go)。- 这些 setup 命令会在每台 worker 通过 SSH 可连后逐条执行(先等待 SSH 端口就绪,最多 3 分钟),每条命令都带
DEBIAN_FRONTEND=noninteractive与 PATH 前缀,确保非交互 shell 能找到 osmedeus 与各类工具(cloud.go)。 - 云端配置文件结构由 CloudConfigs 定义,Hetzner 相关字段集中在 HetznerConfig:
token、location、server_type、image、ssh_key_name。 - 若配置文件的 Token 为空,
osmedeus cloud create/run会直接报错(hetzner token not configured),ValidateCloudConfig 在任务开始前即完成校验。
服务器类型选择
官方文档给出的常用型号对照表如下(价格为文档估算值,实际以 Hetzner 账单为准):
| 服务器类型 | vCPU | 内存 | 磁盘 | $/小时 | $/月 | 适用场景 |
|---|---|---|---|---|---|---|
| cx22 | 2 | 4 GB | 40 GB | ~$0.007 | ~$4.50 | 轻量扫描、单目标 |
| cx32 | 4 | 8 GB | 80 GB | ~$0.013 | ~$8.50 | 常规扫描 |
| cx42 | 8 | 16 GB | 160 GB | ~$0.025 | ~$16.50 | 重负载、多工具并行 |
| cx52 | 16 | 32 GB | 320 GB | ~$0.050 | ~$33.00 | 大规模作战 |
| cpx21 | 3 | 4 GB | 80 GB | ~$0.008 | ~$5.50 | CPU 优化扫描 |
| cpx31 | 4 | 8 GB | 160 GB | ~$0.015 | ~$10.00 | CPU 优化、内存更大 |
切换型号的命令:
osmedeus cloud config set providers.hetzner.server_type cx32从源码看,osmedeus 内置了一张近似美元价目表用于成本估算与限额控制(hetzner.go),覆盖当前代(cx23/cx33/cx43/cx53、cax11–cax41)、上一代(cx11–cx52、cpx11–cpx51)等常见型号,未知型号默认回退到 cx23 的 $0.005/hr。需要提醒的是:Hetzner 以欧元计费,表中的美元价格为近似换算,文档表格与源码估算值存在细微差异属于正常现象。
官方云配置示例(cloud-settings.example.yaml)还给出了更完整的型号族参考:
- 成本优化共享 x86:
cx23、cx33、cx43、cx53 - 成本优化共享 ARM:
cax11、cax21、cax31、cax41 - 共享 AMD:
cpx11、cpx21、cpx31、cpx41、cpx51 - 独享 CPU:
ccx13、ccx23、ccx33、ccx43、ccx53、ccx63
还可以通过 API 实时查询可用型号:
curl -s -H "Authorization: Bearer $HETZNER_TOKEN" \ https://api.hetzner.cloud/v1/server_types | jq '.server_types[].name'机房位置
| 位置 | 代码 | 区域 |
|---|---|---|
| Falkenstein | fsn1 | 德国 |
| Nuremberg | nbg1 | 德国 |
| Helsinki | hel1 | 芬兰 |
| Ashburn | ash | 美东 |
| Hillsboro | hil | 美西 |
| Singapore | sin | 亚洲 |
切换位置:
osmedeus cloud config set providers.hetzner.location fsn1注意:并非所有型号在所有机房都可用(这是官方文档明确提示的坑),如果某个机房创建失败,换一个机房即可。
自定义镜像(加速启动)
每次创建 worker 都要跑一遍 setup 命令安装工具,比较耗时。可以手动配置一台装好全部工具的服务器,拍成快照(Snapshot),之后直接用快照 ID 作为启动镜像:
# 手动配好一台服务器并装完所有工具后: # Hetzner Console > Servers > 你的服务器 > Snapshots > Create Snapshot # 记下快照 ID osmedeus cloud config set providers.hetzner.image 12345678源码中,未配置镜像时默认使用ubuntu-22.04(hetzner.go);CreateInfrastructure里如果通过运行参数显式传入ImageID,会优先于配置值(hetzner.go)。
SSH Key(可选)
如果已在 Hetzner Cloud 中注册过 SSH Key,可以直接复用:
# Hetzner Console > Security > SSH Keys > 记下 key 名称 osmedeus cloud config set providers.hetzner.ssh_key_name my-key-name源码层面有一个更智能的机制:创建资源前,osmedeus 会先计算本地公钥的 MD5 指纹,通过GetByFingerprint查询 Hetzner 是否已存在同名公钥;存在则直接复用,否则自动创建osmedeus-key-<suffix>并注入服务器(hetzner.go),因此即使不手动配置ssh_key_name也能完成密钥注入。
成本限额(安全护栏)
osmedeus cloud config set limits.max_hourly_spend 0.50 osmedeus cloud config set limits.max_total_spend 5.00 osmedeus cloud config set limits.max_instances 20成本控制是 osmedeus 云端功能的内置设计(cost.go):
- 创建基础设施之前会先调用
EstimateCost估算费用,超过max_hourly_spend直接拒绝创建(lifecycle.go); - 运行期间由 CostTracker 按"小时单价 × 已运行时长"实时累计成本,一旦超过
max_total_spend即报错(CheckLimits); limits.max_instances与defaults.max_instances均会拦截超量创建(cloud.go)。
实战示例
以下示例均来自官方文档并保持完整可运行。前提是已完成上述最小配置,并把defaults.provider设为hetzner。
快速域名侦察
osmedeus cloud run -f fast -t example.com --auto-destroy成本:约 $0.007(1 × cx22 × 1 小时),不到 1 美分。
预算批量扫描
Hetzner 的低价特别适合"扫很多目标"的场景:
# 20 个 worker 扫 200 个目标,约 $0.28 osmedeus cloud run \ -f fast -T targets.txt --instances 20 \ --sync-back --auto-destroy成本:20 × $0.007 × 2 小时 =$0.28。
补充说明:-T targets.txt模式下,osmedeus 会在本地把目标列表按 worker 数量切成连续分块,通过 SFTP 上传到各 worker 的/tmp/osm-targets-<i>.txt,然后并行执行osmedeus run -f <flow> -T <remote-file>(cloud.go)。你还可以用--chunk-size <N>或--chunk-count <N>精细控制分块(两者互斥)。--sync-back会在扫描结束后把每个目标的 workspace 结果回传到本地工作区。
自定义命令管道
不跑 osmedeus 工作流,直接在 worker 上执行任意命令管道:
osmedeus cloud run \ --custom-cmd "subfinder -d {{Target}} -o /tmp/osm-custom/subs.txt" \ --custom-cmd "cat /tmp/osm-custom/subs.txt | httpx -o /tmp/osm-custom/live.txt" \ --custom-cmd "cat /tmp/osm-custom/live.txt | nuclei -o /tmp/osm-custom/nuclei.txt" \ --sync-path "/tmp/osm-custom/" \ -t example.com --auto-destroy成本:约 $0.007。
要点:
{{Target}}是模板变量,单目标(-t)时为目标字符串本身;批量目标(-T)时为上传到该 worker 的远程目标文件路径(cloud.go);- 每个 worker 会先
mkdir -p /tmp/osm-custom && cd /tmp/osm-custom再执行命令,多个--custom-cmd按顺序执行、遇错即停;可选的--custom-post-cmd仅在前置命令全部成功后才运行; --sync-path把指定远程路径(文件或目录)回传本地,本地布局为<sync-dest>/<worker名>-<IP>/<相对路径>,默认--sync-dest为./osm-sync-back(cloud.go);--custom-cmd与--flow/-f、--module/-m互斥,必须二选一。
分布式 Nuclei 大规模扫描
# 把 10,000 个 URL 拆分到 10 台 Hetzner worker osmedeus cloud run \ --custom-cmd "cat {{Target}} | nuclei -o /tmp/osm-custom/results.txt" \ --sync-path "/tmp/osm-custom/results.txt" \ --sync-dest "./nuclei-hetzner" \ -T urls.txt --instances 10 --auto-destroy成本:10 × $0.007 × 1 小时 =$0.07。
这里-T urls.txt会把 10,000 个 URL 自动切分成 10 份,每台 worker 拿到一份远程文件路径作为{{Target}},cat后管道给 nuclei,最后把各自的结果文件回传到本地的./nuclei-hetzner目录。
端口扫描
# masscan 需要更多资源,换更大的实例 osmedeus cloud config set providers.hetzner.server_type cx32 osmedeus cloud run \ --custom-cmd "masscan {{Target}} -p1-65535 --rate 10000 -oG /tmp/osm-custom/masscan.txt" \ --custom-cmd "cat /tmp/osm-custom/masscan.txt | grep 'Host:' | awk '{print \$2\":\" \$5}' | sed 's|/.*||' > /tmp/osm-custom/open-ports.txt" \ --sync-path "/tmp/osm-custom/" \ -t 203.0.113.0/24 --auto-destroy注意:目标为 CIDR(203.0.113.0/24)时可直接用-t传入。shell 内对$的转义(\$2、\$5)是为了避免本地 shell 提前展开。
常驻低成本实验环境
# 创建 5 台 worker 并保持全天运行 osmedeus cloud create --provider hetzner -n 5 # 一天内反复执行多个扫描 osmedeus cloud run -f fast -t target1.com --reuse osmedeus cloud run --custom-cmd "nmap -sV {{Target}}" -t target2.com --reuse osmedeus cloud run -f general -T targets.txt --reuse # 一天结束后销毁 osmedeus cloud destroy all --force成本:5 × $0.007 × 8 小时 =$0.28,5 台机器扫一整天。
--reuse的机制值得说明:它会读取本地保存的全部基础设施状态(JSON 持久化于{{base_folder}}/cloud-state),并行探测各实例的 SSH 可达性与忙碌状态(是否有 osmedeus 进程在跑),优先把任务分配给空闲实例(cloud.go)。若想精确指定复用某几台,用--reuse-with '1.2.3.4,5.6.7.8'(按 IP 或资源名匹配,未匹配到的按 ad-hoc IP 处理)。
欧盟 IP 空间扫描
某些场景要求扫描流量从欧盟 IP 段发起,Hetzner 的欧洲机房正好适用:
# 使用德国机房 osmedeus cloud config set providers.hetzner.location fsn1 osmedeus cloud run -f fast -t eu-target.com --auto-destroy # 使用芬兰机房 osmedeus cloud config set providers.hetzner.location hel1 osmedeus cloud run -f fast -t nordic-target.com --auto-destroycx42 高性能并行
# 8 vCPU / 16 GB 实例,适合重负载并行扫描 osmedeus cloud config set providers.hetzner.server_type cx42 osmedeus cloud run \ --custom-cmd "subfinder -d {{Target}} -all -o /tmp/osm-custom/subs.txt" \ --custom-cmd "cat /tmp/osm-custom/subs.txt | httpx -td -threads 200 -o /tmp/osm-custom/live.txt" \ --custom-cmd "cat /tmp/osm-custom/live.txt | nuclei -c 100 -o /tmp/osm-custom/nuclei.txt" \ --custom-cmd "cat /tmp/osm-custom/live.txt | katana -d 3 -jc -o /tmp/osm-custom/crawl.txt" \ --sync-path "/tmp/osm-custom/" \ -t example.com --auto-destroy成本:约 $0.025/小时。子域名枚举 → 存活探测(200 线程)→ 漏洞扫描(100 并发)→ 爬虫(深度 3、JS 抓取)一条流水线跑完。
成本对比:为什么批量扫描选 Hetzner
官方文档给出的参考对比(Hetzner cx22 vs DigitalOcean s-2vcpu-4gb vs AWS t3.medium):
| 场景 | Hetzner (cx22) | DigitalOcean (s-2vcpu-4gb) | AWS (t3.medium) |
|---|---|---|---|
| 1 实例 × 1 小时 | $0.007 | $0.022 | $0.042 |
| 5 实例 × 2 小时 | $0.07 | $0.22 | $0.42 |
| 10 实例 × 4 小时 | $0.28 | $0.89 | $1.66 |
| 20 实例 × 8 小时 | $1.12 | $3.57 | $6.66 |
结论:同等规格下 Hetzner 约比 DigitalOcean 便宜 3 倍、比 AWS 便宜 6 倍(以上均为文档给出的估算值,实际账单以云厂商计费为准)。
故障排查
"Unauthorized" 错误
API Token 无效或已过期,在 Hetzner Cloud Console 重新生成一个:
osmedeus cloud config set providers.hetzner.token <new-token>服务器类型不可用
部分型号并非在所有机房提供,换一个机房重试:
osmedeus cloud config set providers.hetzner.location nbg1SSH 连接问题
Hetzner 服务器默认使用root用户:
osmedeus cloud config set ssh.user root用--verbose-setup观察 setup 命令的完整输出以定位问题:
osmedeus cloud run --custom-cmd "whoami" -t test --verbose-setup速率限制
Hetzner API 存在速率限制,一次性创建大量实例可能触发。可适当错开创建时间,或联系 Hetzner 支持提升限额。
清理资源
# 列出全部基础设施 osmedeus cloud list # 销毁指定基础设施 osmedeus cloud destroy <infra-id> # 销毁全部(需 --force) osmedeus cloud destroy all --force # 若状态不同步,直接去 Hetzner Console 核对: # Console > Servers > 查找 osmedeus 前缀的服务器从源码看,worker 服务器统一命名为osmw-<时间戳>-<序号>(如osmw-1775231420-0),并带有osmedeus=true标签,方便在控制台识别(hetzner.go)。另外,osmedeus 会自动为每套基础设施创建一条放行 TCP 22 端口的防火墙规则(入站0.0.0.0/0与::/0,hetzner.go),并在创建失败时依据defaults.cleanup_on_failure自动销毁残留资源(lifecycle.go)。
最佳实践清单
- 默认使用 cx22—— 2 vCPU / 4 GB 对大多数扫描已够用,$0.007/hr 的单价几乎可忽略;
- 横向扩展优先—— 可并行化的任务用 10 × cx22 比 1 × cx52 更便宜更快;
- 始终加
--auto-destroy—— 即使单价只有 $0.007/hr,遗忘的实例也会悄悄累计账单; - 优先欧洲机房(fsn1、nbg1)—— 对 Hetzner 网络延迟最低;
- 预构建快照—— 常用工具配置拍成快照,跳过每次的 setup 等待;
- 设置克制的成本限额—— 以 Hetzner 的价格,
max_total_spend设为 $5.00 已经能跑很多轮扫描。
相关资源
继续深入阅读与验证:
- 官方指南:Hetzner Provider Guide、云端快速参考、云端使用指南
- 云端配置示例与注释:cloud-settings.example.yaml
- Hetzner 提供商实现:hetzner.go
- 云端配置结构与默认值:cloud_config.go
- Provider 接口与核心类型:provider.go
- 配置加载/校验/环境变量展开:config.go
- 生命周期编排与成本校验:lifecycle.go、cost.go
- 云 CLI 命令实现(config/create/list/destroy/run):cloud.go
【免费下载链接】osmedeusA Modern Orchestration Engine for Security项目地址: https://gitcode.com/GitHub_Trending/os/osmedeus
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考