dhach.acme_letsencrypt
acme-letsencrypt
概述
这是一个纯Ansible角色,用于实现以下功能:
- 创建ECC或RSA私钥
- 生成证书签名请求(针对多个域名)
- 将请求发送到Let's Encrypt或您选择的其他ACME提供商
- 在确定的位置安装所有文件
我编写这个角色的目的是为了能够获取Let's Encrypt证书,而不必依赖任何第三方工具(如certbot、acme-tiny、acme.sh等),并对过程有更多控制。
目前,仅支持HTTP挑战类型。
由于这只是一个Ansible角色,它不处理自动证书续订。要实现这一点,您可以从CI/CD管道定期运行此角色,或让它在Ansible拉模式下运行,并使用cron定时任务。
Ansible版本
从版本2.0.0开始,此角色仅保证与Ansible >=2.10兼容。
如果需要与<2.10兼容(即“预收集”),请使用任何1.x.x版本的发布。
要求
在目标主机上:
- openssl
示例剧本
使用secp384r1 ECC密钥为SAN证书(多个域名)获取证书。
- name: "获取webserver01的证书"
hosts: webserver01
become: true
roles:
- dhach.acme_letsencrypt
vars:
le_base_directory: /etc/letsencrypt
le_certificates:
- name: ecc.example.com
domains:
- secp.example.com
- ecc.example.com
key:
curve: secp384r1
现在使用secp256r1密钥,强制重新创建它,然后向Let's Encrypt生产验证服务器发出请求:
- name: "获取webserver02的证书"
hosts: webserver02
become: true
roles:
- dhach.acme_letsencrypt
vars:
le_acme_directory: https://acme-v02.api.letsencrypt.org/directory
le_certificates:
- name: another-domain.example.com
domains:
- another-domain-abc.example.com
- another-domain-def.example.com
- another-domain-ghi.example.com
- another-domain-jkl.example.com
- another-domain-mno.example.com
ssl:
type: ECC
curve: secp256r1
renew: true
或者使用RSA密钥为每个域获取一个证书:
- name: "获取webserver03的证书"
hosts: webserver03
become: true
roles:
- dhach.acme_letsencrypt
vars:
le_certificates:
- name: example.com
domains:
- foo.example.com
key:
type: RSA
size: 4096
- name: more.example.com
domains:
- bar.example.com
key:
type: RSA
size: 4096
文件的位置
所有生成的密钥、证书请求和后续证书可以在{{ le_base_directory }}/{{ le_certificates['name'] }}
下找到。
例如,如果您指定了'name'为'example.com',并且le_base_directory
设置为'/etc/letsencrypt/',结果将是:
/etc/letsencrypt/example.com/
├── domain.csr
├── domain.key
├── domain.pem
├── fullchain.pem
└── intermediate.pem
如何配置您的Web服务器
ACME服务器要求您通过在Web服务器的HTTP服务预定义路径中放置具有特定名称和内容的文件来响应挑战。
您的Web服务器必须服务于位置*/ .well-known/acme-challenge*,其内容为以下目录:{{ le_base_directory }}/.well-known/acme-challenge/
。
使用le_base_directory
的默认值的示例:
Nginx:
location /.well-known/acme-challenge {
alias /etc/letsencrypt/.well-known/acme-challenge/;
}
Apache:
Alias /.well-known/acme-challenge/ "/etc/letsencrypt/.well-known/acme-challenge/"
<Directory "/etc/letsencrypt/.well-known/acme-challenge/">
AllowOverride None
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
Require method GET POST OPTIONS
</Directory>
角色变量和默认值
以下列出了所有定义的变量及其各自的默认值。
证书请求
您可以控制要请求证书的域名。您还可以选择指定有关密钥生成的详细信息。选项在RSA和ECC密钥之间略有不同。
所有证书请求都构造为SAN(SubjectAltName)请求。
ECC:
le_certificates:
- name: example.com # 实际上是内部标识符和保存文件的位置
domains: # 您希望为其颁发证书的域名列表
- foo.example.com
- bar.example.com
key: # 如果要生成私钥,私钥的详细信息
type: ECC # (强制)支持类型:ECC、RSA
curve: secp384r1 # (可选 | 默认:secp384r1)ECC密钥的曲线(对RSA密钥没有影响)。
renew: false # (可选 | 默认:false)是否强制重新创建密钥。将始终保留备份
RSA:
le_certificates:
- name: example.com # 实际上是内部标识符和保存文件的位置
domains: # 您希望为其颁发证书的域名列表
- foo.example.com
- bar.example.com
key: # 如果要生成私钥,私钥的详细信息
type: RSA # (强制)支持类型:ECC、RSA
size: 4096 # (可选 | 默认:4096)RSA密钥的长度(对ECC密钥没有影响)
renew: false # (可选 | 默认:false)是否强制重新创建密钥。将始终保留备份
目录和权限
le_base_directory
: 所有生成文件的基础目录(默认:/etc/letsencrypt)
le_files_owner
: 生成的文件和文件夹的拥有者(默认:root)
le_files_group
: 生成的文件和文件夹应属于的组(默认:root)
Let's Encrypt账户密钥
le_account_key_path
: 放置(或查找)Let's Encrypt账户密钥的位置(默认:"{{ le_base_directory }}/account.key")
le_account_key_type
: 要用于账户密钥的密钥类型(RSA、ECC)(默认:RSA)
le_account_key_size
: 密钥的大小,仅适用于RSA密钥(默认:4096)
le_account_key_curve
: 要使用的曲线,仅适用于ECC密钥,对RSA密钥没有影响(默认:secp384r1)
le_account_key_regenerate
: 是否重新生成现有密钥,将保留备份(默认:false)
不幸的是,Let's Encrypt不容易支持ECC账户密钥。最好保持在RSA 4096。
Let's Encrypt / ACME版本和目录
le_acme_version
: 要使用的ACME版本。如果您选择使用其他发行者而不是Let's Encrypt,可能是必要的(默认:2)
le_acme_directory
: 请求证书的ACME目录URL。出于安全原因,默认设置为Let's Encrypt的临时环境(默认:https://acme-staging-v02.api.letsencrypt.org/directory)
Let's Encrypt生产目录为:https://acme-v02.api.letsencrypt.org/directory。
le_renew_if_invalid_after
: 如果证书有效期少于此天数,尝试续订证书(默认:30)
le_force_renew
: 尝试强制续订证书(默认:false)
le_csr_only
: 如果您只想生成私钥和CSR,请将其设置为true。这对于调试很有用(默认:false)
贡献和问题
欢迎所有贡献。请随时提出问题或创建拉取请求。
我会乐意关注任何提出的问题,并始终尽力改进这个角色。
测试
所有测试均通过Molecule进行。
CI管道通过GitHub Actions实现,并使用矩阵策略,在Ubuntu、Debian和CentOS上进行测试。
要开始本地测试,请设置一个本地Python虚拟环境,安装所有依赖项,并运行测试。这需要在您的计算机上安装Docker(或使用Docker-Machine):
python3 -m venv venv
source venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -r test-requirements.txt
molecule test
由于此角色本质上要求向ACME服务器发出请求,因此需要控制要动态设置DNS记录的域名,测试仅限于进行代码风格检查,检查密钥和CSR是否已创建并存在,并且它们的内容是否符合预期。
在实际的互联网连接机器上,手动测试所有功能的完整角色是针对Let's Encrypt的临时服务器进行的。
许可证
GNU通用公共许可证v3.0
Requests certificates from Let's Encrypt (or another ACME server)
ansible-galaxy install dhach.acme_letsencrypt