Certbot 多发行版集成测试:letstest AWS 测试农场实战指南
2026/9/20 1:38:22 网站建设 项目流程
  • 网络安全
  • CLI
  • 后端

【免费下载链接】certbot

Certbot is EFF's tool to obtain certs from Let's Encrypt and (optionally) auto-enable HTTPS on your server. It can also act as a client for any other CA that uses the ACME protocol.

项目地址:https://gitcode.com/gh_mirrors/ce/certbot
点击查看免费下载

导读

letstest 是 Certbot 项目自带的一套轻量级 AWS 测试农场(test farm)脚本,用于在真实 EC2 云主机上对 Certbot 客户端进行跨发行版集成测试。通过本指南,你将掌握如何用一条命令在 Ubuntu、Debian、CentOS 等多台 EC2 实例上并行克隆 Certbot 仓库、安装依赖、运行测试脚本并回收结果日志,也理解其底层基于 boto3 与 Fabric 的自动化原理,从而在自己的 CI 流程或发布验证中复用它。

什么是 letstest

letstest 是 Certbot 仓库letstest/目录下的一个独立 Python 包,其pyproject.toml中的描述为 "Test Certbot on different AWS images"。它解决的问题非常具体:Certbot 需要兼容多个 Linux 发行版与多种 HTTP 服务器(Apache、Nginx 等),单机单元测试无法覆盖真实的系统差异(包管理器、默认配置文件路径、SELinux 策略等),因此需要一个能在多种真实操作系统镜像上自动跑集成测试的设施。

从 multitester.py 的模块 docstring 可以看出它的四个核心工作步骤:

  1. 拉起实例:根据给定的 AMI 列表,为不同发行版启动 EC2 实例;
  2. 分发仓库:将 Certbot 仓库复制并部署到各实例;
  3. 并行执行:在所有实例上运行 Certbot 测试(bash 脚本);
  4. 收集结果:记录执行过程与成功/失败状态,供排错使用。

整个流程由letstest/letstest/multitester.py(约 520 行)单一入口实现,通过pyproject.toml[project.scripts]声明的letstest = "letstest.multitester:main"暴露为命令行工具。

工作原理与整体流程

四个阶段的工作流

从 multitester.py 的main()函数可以还原出完整流程:

第一阶段:准备本地仓库(git 对象选择)

  • 默认克隆https://github.com/certbot/certbot.git的当前分支;
  • 支持通过--branch指定分支、通过--pull_request指定 PR 进行测试;
  • 克隆完成后打包为le.tar.gz,等待上传到远端实例;
  • 所有动作在一个tempfile.mkdtemp()创建的临时目录中进行,该目录同时也是日志目录。

第二阶段:准备 EC2 资源

  • 读取 YAML 配置文件中的targets列表;
  • 通过 boto3 会话(使用aws_profile指定的 IAM 配置)连接 EC2;
  • 选择一个合适的子网(默认子网或名为certbot-subnet的子网,要求开启自动分配公网 IP);
  • 创建或复用名为certbot-security-group的安全组,放行 TCP 22(SSH)与 UDP 60000-61000(供 mosh 使用),见 make_security_group。

第三阶段:并行执行测试

  • 为每个 target 启动一个独立的多进程 worker(multiprocessing.Process);
  • 每个 worker 通过 Fabric 的Connection建立 SSH 连接;
  • 依次执行:上传le.tar.gz并解压 → 设置环境变量(公网 IP、私网 IP、主机名、PIP 源、OS 类型)→ 上传并运行指定的测试 bash 脚本,见 install_and_launch_certbot;
  • 测试通过Manager.Queue传递任务与结果,避免multiprocessing.Queue的潜在死锁问题。

第四阶段:回收与清理

  • 拉取每台实例上的 Certbot 运行日志(/var/log/letsencrypt/letsencrypt.log./certbot.log),追加到每台机器对应的输出日志;
  • 汇总结果为results文件,格式为序号 目标名 pass/fail
  • 默认情况下终止所有 EC2 实例;--saveinstances可保留实例以便人工登录排错,见 cleanup。

实例自毁保护机制

为防止测试任务卡死导致 AWS 资源泄漏,make_instance在默认(非--saveinstances)模式下会注入两重保险:

  • InstanceInitiatedShutdownBehavior = 'terminate':实例关机即销毁;
  • UserData写入#!/bin/bash\nshutdown -P +60:实例启动 60 分钟后自动关机。

同时_get_block_device_mappings会把所有 EBS 卷的DeleteOnTermination显式设为True,确保实例终止时磁盘一并回收,见 make_instance。

安装与配置

1. 准备开发环境

letstest 随 Certbot 的开发环境一起安装。在按 Certbot 官方贡献文档创建本地开发环境后,此包即可使用。该包依赖如下(见 pyproject.toml):

  • boto3/botocore:AWS SDK,负责 EC2 资源操作;
  • fabric>=2:SSH 执行与文件传输(使用 2.x API);
  • pyyaml:解析 targets 配置文件。

Python 版本要求>=3.10

2. 配置 AWS 凭据

测试使用 AWS SDK for Python(boto3)操作 EC2,需要先配置凭据。README 指向 boto3 快速入门指南,核心步骤是使用 AWS CLI 配置 IAM 角色的密钥。multitester.py的 docstring 给出了完整示例(multitester.py):

aws configure --profile HappyHacker # 交互式输入 IAM 角色的 Access Key / Secret Key / region aws ec2 create-key-pair --profile HappyHacker --key-name MyKeyPair \ --query 'KeyMaterial' --output text > MyKeyPair.pem

注意:

  • 区域:建议在~/.aws/config中为 profile 设置region = us-east-1,因为 targets.yaml 中列出的 AMI 均位于us-east-1
  • 密钥命名约定:代码假定密钥文件名为<keyname>.pem,并据此推断KEYNAME(见 multitester.py),因此MyKeyPair.pem对应密钥名MyKeyPair
  • 若使用环境变量方式提供凭据,可将 aws_profile 参数传为SET_BY_ENV,此时代码会把 PROFILE 置为None,交由 boto3 默认凭据链解析。

3. 准备 SSH 密钥文件

还需要一个包含受信 SSH 私钥的文件(即上一步create-key-pair生成的.pem文件),用于 Fabric 连接实例。multitester.py通过 FabricConfigconnect_kwargs.key_filename传入该密钥,见 main()。

使用方法

激活上述开发环境的虚拟环境后,在letstest/目录下执行:

letstest targets/targets.yaml /path/to/your/key.pem <profile name> scripts/<test to run>

对应官方 README 中的用法。执行后会在本地生成一个临时目录(其路径会打印到终端),包含每台实例的日志文件(命名形如0_ubuntu24.04.log)以及汇总结果文件results。由于要等待实例启动、安装依赖并运行完整测试,整个过程耗时较长。

完整命令行参数

从 multitester.py 的 argparse 定义可以提取出全部参数:

参数必填默认值说明
config_fileAWS 服务器集群的 YAML 配置文件
key_fileAWS 密钥文件(<keyname>.pem
aws_profileAWS profile 名称(对应~/.aws/中的配置)
test_scripttest_apache2.sh要部署并运行的 bash 测试脚本路径
--repohttps://github.com/certbot/certbot.git要测试的 Certbot git 仓库
--branch~要试跑的 git 分支
--pull_request~要试跑的 certbot/certbot PR 编号
--merge_main关闭若设置,将 PR 合并进 certbot/certbot 的 main 分支后再测
--saveinstances关闭运行结束后不销毁 EC2 实例,便于排错
--alt_pip从中拉取候选发布包的 pip 源服务器

测试 PR / 分支 / 主干

main()中的 git 对象选择逻辑(multitester.py)展示了三种测试场景:

  • 测 PRletstest targets.yaml key.pem profile scripts/test_apache2.sh --pull_request 1234,会执行git fetch origin pull/1234/head:lePRtest并 checkout;配合--merge_main会先git merge origin/main再测试,这正是 PR 合入前的冒烟验证;
  • 测分支--branch my-feature,使用git clone --branch <branch> --single-branch
  • 测主干:默认行为,直接克隆仓库当前分支。

自定义测试脚本

test_script参数指向的脚本只是一段普通的 bash 脚本,运行时通过环境变量接收参数。README 指出scripts/test_apache2.sh是最好的参考范例。脚本头部注释明确了注入的环境变量(test_apache2.sh):

  • $OS_TYPE:操作系统类型(如ubuntucentos),来自 targets YAML 中的type字段;
  • $PUBLIC_IP$PRIVATE_IP$PUBLIC_HOSTNAME:实例的公网/私网 IP 与公网主机名;
  • $PIP_EXTRA_INDEX_URL--alt_pip指定的候选发布包源。

这些变量由 install_and_launch_certbot 通过 Fabric 的prefix()export形式注入。源码注释特别说明了两点踩坑经验:Fabric 的runenv参数不可用(见 fabric issue #1744),且prefix()会在命令间插入&&,因此脚本内必须用 export 而非内联变量赋值。

test_apache2.sh本身演示了一个完整的 Apache 集成测试脚本:

  1. 按 OS 类型初始化 Apache:Ubuntu/Debian 系使用 apt 安装apache2并调整000-default.conf的 ServerName;CentOS 系禁用 SELinux、安装httpd mod_ssl、创建站点目录与 VirtualHost 配置;
  2. 引导依赖:调用sudo letstest/scripts/bootstrap_os_packages.sh安装编译与运行依赖;
  3. 安装 Python:通过 pyenv 安装 Python 3.10;
  4. 构建环境tools/venv.py -e acme -e certbot -e certbot-apache -e certbot-ci tox构建开发虚拟环境;
  5. 启动 Pebble:用venv/bin/run_acme_server --http-01-port 80在本地启动 Pebble ACME 测试服务器,并轮询等待其就绪(最多 150 秒);
  6. 运行 Certbot:以 Pebble 为 ACME 服务器,对$PUBLIC_HOSTNAME执行完整签发流程(--register-unsafely-without-email--redirect--no-verify-ssl等);
  7. 断言与回归:检查生成的options-ssl-apache.conf是否包含SSLSessionTickets(验证现代 TLS 配置生效),Ubuntu 上还会额外运行venv/bin/tox -e apacheconftest做 Apache 配置回归。

此外,脚本通过trap DumpPebbleLogsOnFailure EXIT在失败时自动倾倒 Pebble 日志,方便在 CI 日志中直接定位 ACME 交互层面的问题。

targets 配置文件格式

targets/targets.yaml 是默认的集群定义,核心结构为targets:下的列表,每个 target 包含四个字段:

字段含义示例
ami位于 us-east-1 的 AMI IDami-045a47a3b15302634
name目标名(用于日志命名与展示)ubuntu24.04
type操作系统类型(传给测试脚本的$OS_TYPEubuntu/centos
virt虚拟化类型(hvm或 32 位系统的paravirtual,决定默认机型)hvm
userSSH 登录用户名ubuntu/admin/ec2-user

默认文件覆盖了 4 个目标:Ubuntu 24.04、Ubuntu 22.04、Debian 12、CentOS Stream 9,注释中明确说明所有机器必须使用 x86_64 架构,因为 Pebble 目前不发布其他架构的镜像。

机型选择逻辑在 create_client_instance:target 中可指定machine_type覆盖;否则hvm虚拟化默认使用t2.medium,32 位系统默认使用c1.medium

关键实现细节与排错指引

子网与安全组的自动化

should_use_subnet(multitester.py)要求子网满足:map_public_ip_on_launch为真,且要么是可用区默认子网,要么名为certbot-subnet。若找不到可用子网,程序会打印提示并退出——这也是自建 VPC 时最容易踩的坑:需要创建开启"自动分配公网 IPv4"且命名为certbot-subnet的子网。

安全组certbot-security-group若不存在则自动创建(TCP 22 与 UDP 60000-61000),存在则复用。注意源码注释提示同名安全组无法重复创建,重复运行是安全的。

多进程并行与日志

main()使用multiprocessing.Manager().Queue分发任务(官方建议避免使用原生multiprocessing.Queue,因其实现缺陷在某些情况下会死锁)。每个 worker 进程把 stdout 重定向到自己的日志文件(test_client_process),主进程通过join(5 * 60)循环等待并定期输出.以保持 CI 心跳。全部完成后输出排序后的结果,任一失败则sys.exit(1),便于上层 CI 捕获失败信号。

已知限制(README Notes)

  • Marketplace 镜像需人工接受条款:部分 AWS 官方镜像(如官方 CentOS、FreeBSD 镜像)需要在 AWS Marketplace 网页上接受用户条款,此步骤无法自动化;
  • EC2 实例数配额:AWS EC2 默认 t2/t1 实例上限为 20 台,若 targets 超过该数量需通过在线表单申请提升配额。

与 Certbot 生态的协作位置

letstest 与仓库内其他测试设施分工明确:certbot-cicertbot-integration-tests)在容器/本地环境中做 ACME 端到端测试;而 letstest 面向真实云主机的多发行版矩阵,是 Certbot 发布前跨 OS 兼容性验证的重要一环。其测试脚本复用仓库根部的tools/venv.py构建开发环境,并与 Pebble 测试 ACME 服务器配合,可在不触碰生产 Let's Encrypt 服务的前提下完成完整的证书签发流程验证。letstest/scripts/version.py还提供了一个读取certbot/src/certbot/__init__.py中版本号的小工具,供发布流程获取当前版本。

快速上手清单

  1. aws configure --profile <profile>配置 IAM 凭据,区域设为us-east-1
  2. aws ec2 create-key-pair ... > MyKeyPair.pem创建密钥并妥善保管;
  3. 在 Certbot 开发环境中安装letstest包;
  4. 执行letstest targets/targets.yaml MyKeyPair.pem <profile> scripts/test_apache2.sh
  5. 观察终端打印的临时日志目录,等待完成;失败时查看results文件与各实例日志,配合--saveinstances保留实例进行人工排查。
  • 网络安全
  • CLI
  • 后端

【免费下载链接】certbot

Certbot is EFF's tool to obtain certs from Let's Encrypt and (optionally) auto-enable HTTPS on your server. It can also act as a client for any other CA that uses the ACME protocol.

项目地址:https://gitcode.com/gh_mirrors/ce/certbot
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询