nickjj.acme_sh

什么是 ansible-acme-sh? 构建状态

这是一个 Ansible 角色,用于:

  • 安装 acme.sh 以颁发、续期或移除基于 Let's Encrypt 的 SSL 证书
  • 为单个、多个或通配符域名颁发证书
  • 通过一个证书或单独的证书配置多个域名
  • 使用 acme.sh 的自动 DNS API 功能颁发基于 DNS 的挑战
  • 如果预设不够用,可以运行自定义的 acme.sh 命令

你为什么想使用这个角色?

这个角色使用 acme.sh,这是一个独立的 Bash 脚本,用来处理颁发和自动续期 SSL 证书的所有复杂性。

这个角色的目标是高度可配置,同时有足够的合理默认值,让你只需要提供一个域名列表,设置你的 DNS 提供商,并提供 DNS 提供商的 API 密钥就可以开始使用。

每个任务也都是幂等的,因为这就是我的工作方式!

为什么只支持基于 DNS 的挑战方法?

通过 DNS 完成挑战意味着你可以在你的 web 服务器或代理准备好之前就设置好证书。这也意味着你的 web 服务器不需要知道 ACME 挑战是如何工作的。你只需要引用这个角色生成的最终证书。

另一个好处是如果你在 Docker 中运行 web 服务器,你可能需要等到服务器由 Ansible 提供后才能启动。例如,通常会设置基于 git 的部署来启动应用部署。

使用 DNS 挑战也很好,因为 DNS 挑战是使用 Let's Encrypt 颁发通配符证书的唯一方式。将精力集中在一个适用于所有证书类型的解决方案上似乎是正确的选择。

也就是说,我可能不会支持其他模式,比如 standalone、webroot、nginx 或 Apache,但这并不是绝对的。

支持的平台

  • Ubuntu 16.04 LTS (Xenial)
  • Ubuntu 18.04 LTS (Bionic)
  • Debian 8 (Jessie)
  • Debian 9 (Stretch)

角色变量

# 将运行 acme.sh 的系统用户。请记住,这个用户必须已经存在, 
# 这个角色不会创建它。
acme_sh_become_user: "root"

# acme.sh 包依赖。默认值适用于 Debian / Ubuntu。
# 对于 CentOS 和 Fedora,你可以将 "cron" 替换为 "crond"。
acme_sh_dependencies: ["cron", "git", "wget"]

# 要克隆的 acme.sh 仓库。
acme_sh_git_url: "https://github.com/acmesh-official/acme.sh"

# 将被克隆的分支、标签或提交。
acme_sh_git_version: "master"

# 默认情况下,如果你现在克隆这个仓库,然后六个月后再次克隆,
# 它将保持旧的 master 版本。如果你希望每次运行都拉取最新的 master 版本,请将其设置为 True。
acme_sh_git_update: False

# 这个仓库将被克隆到哪里?
acme_sh_git_clone_dest: "/usr/local/src/acme.sh"

# 启用后,acme.sh 将自我升级到最新版本,这与更新 git 仓库是不同的。
# 因为 acme.sh 在克隆源代码后通过一个安装程序安装自己。
#
# 启用它可能会获取最新的发布版本,可能会有 bug 修复,
# 但请记住,如果这样做,你可能会每次运行都会得到不同的结果。
# 我建议偶尔将此设置为 True,但通常保持禁用。
acme_sh_upgrade: False

# 启用时,将删除克隆的源代码、安装路径、日志文件和续期 cron 任务。
#
# 已安装的证书不会被移除。如果你想删除已安装的证书,还有另一个选项,我们稍后会介绍。
acme_sh_uninstall: False

# 创建初始 Let's Encrypt 账户时,你可以选择提供一个电子邮件地址。
# 默认情况下没有设置,但如果你愿意,请随意添加你的电子邮件地址。
# 如果设置了它,当你的证书在 20 天内到期时,你会收到电子邮件。
#
# 我强烈建议设置这个,因为如果一切顺利,你不会收到邮件,除非 acme.sh 没能续期某个证书。
acme_sh_account_email: ""

# 证书将通过 acme.sh 管理的 cron 任务自动续期。默认情况下,
# acme.sh 为每次续期尝试使用 60 天,但我选择默认使用 30 天以提供额外的尝试空间。
#
# 不需要续期的证书将被 acme.sh 跳过,因此一切正常。
# 还值得一提的是,这个值不能大于 60 天,这是 acme.sh 强制的限制,
# 这个角色不对该值进行双重检查。
acme_sh_renew_time_in_days: 30

# 证书将被复制到的基本路径。如果你熟悉 acme.sh,这就是用 --install-cert 生成的证书。
#
# 这是证书的最终目的地,你选择的用户需要对此路径具有写入权限。
# 这个路径将被设置为 acme_sh_become_user 值的拥有者和所属组。
acme_sh_copy_certs_to_path: "/etc/ssl/ansible"

# 在运行结束时,Ansible 调试消息将打印出具有有效 SSL 证书的域名列表及其到期日期。
# 你可以通过将其设置为 False 来禁用此功能。
acme_sh_list_domains: True

# 如果设置为 False,它将使用实时的 Let's Encrypt 服务器,因此请确保一切与 staging True 一起正常工作,
# 否则你可能会遇到速率限制。
#
# 值得一提的是,当在 staging 和 live 之间切换时,你需要强制颁发新证书,反之亦然。
acme_sh_default_staging: True

# 如果设置为 True,即使你的域名列表没有变化,这也将重新颁发新证书。
# 这也用于设置新的 DNS 提供商和 API 密钥。
#
# 对此要小心,因为如果在实时服务器上,可能会受到速率限制。
# 只有在更新 DNS 提供商时考虑使用此选项。完成后应将其设置回 False。
acme_sh_default_force_issue: False

# 如果设置为 True,这将为现有的证书列表重新生成新证书。
# 这不会更新你的 DNS 提供商或 API 密钥。
#
# 如果证书过期,这可能会很有用。完成后应将其设置回 False。
acme_sh_default_force_renew: False

# 如果设置为 True,这将向 STDOUT 提供更详细的信息。
# 如果你在 staging 模式下测试角色,这可能会很有用。
acme_sh_default_debug: False

# 你应该使用哪个 DNS 提供商?
# 支持的提供商列表可以在这里找到:
#   https://github.com/acmesh-official/acme.sh/tree/master/dnsapi
# 要获取使用的名称,也可以在上面的 URL 中找到。
#
# 默认值为 DigitalOcean。确保包含 dns_ 部分的名称,
# 但省略 .sh 文件扩展名。
acme_sh_default_dns_provider: "dns_dgon"

# 你的 DNS 提供商的 API 密钥是什么?
# 要使用的密钥名称可以在这里找到:
#   https://github.com/acmesh-official/acme.sh/tree/master/dnsapi
#
# API 密钥可以在你的 DNS 提供商网站上创建。
# 一些提供商需要 1 个密钥,而其他提供商则需要 2 个以上。
# 只需在这里添加键 / 值对,而不需要 "export "。
#
# 例如,如果你使用 DigitalOcean,你可以输入:
#    acme_sh_default_dns_provider_api_keys:
#      "DO_API_KEY": "来自 DO 控制面板的 API 密钥"
acme_sh_default_dns_provider_api_keys: {}

# acme.sh 在尝试将 TXT 记录设置为你的 DNS 记录后,应该休眠多长时间?
# 一些 DNS 提供商的更新速度不快。
#
# 120 是 acme.sh 本身的默认值,但请记住,如果你使用 NameSilo,
# 他们的 DNS 更新每 15 分钟只传播一次,因此你需要将此值设置为 900,
# 否则你可能会面临 DNS NXDOMAIN 错误。
#
# 我建议在 DNS 提供商需要时将其保持在 120 或更高。
#
# 此外,我在测试该角色时对 DigitalOcean 使用了 10,并且连续工作了 30 次。
# 但在生产中,为了安全起见,我会使用 120,因为这 2 分钟的延迟只会影响你第一次 Ansible 运行。
# 之后,它将在后台通过 cron 任务更新。
acme_sh_default_dns_sleep: 120

# 在颁发新证书时,你可以选择添加默认未包含的其他标志。
# 将它们提供,就像在命令行上那样,例如 "--help"。
acme_sh_default_extra_flags_issue: ""

# 在续期证书时,你可以选择添加默认未包含的其他标志。
# 将它们提供,就像在命令行上那样,例如 "--help"。
acme_sh_default_extra_flags_renew: ""

# 在安装证书时,你可以选择添加默认未包含的其他标志。
# 将它们提供,就像在命令行上那样,例如 "--help"。
#
# 安装与颁发不同,我们稍后会介绍。
acme_sh_default_extra_flags_install_cert: ""

# 当证书已颁发或续期时,acme.sh 会尝试运行你选择的命令。
# 这可以是重新启动或重新加载你的 web 服务器或代理。
#
# 请记住,你在 acme_sh_become_user 中设置的用户需要有 sudo 权限,
# 如果在这里使用 sudo,否则需要有重新加载你的 web 服务器 / 代理的权限。
#
# 要获取 Docker 示例,请查看此 README 的示例部分。
acme_sh_default_install_cert_reloadcmd: "sudo systemctl reload nginx"

# 如果你需要比 reloadcmd 更精细的控制, 可以在颁发或续期证书的生命周期中挂钩。
# 默认情况下,以下 3 个选项不做任何事情,除非你填充它们。
# 它们不是一切正常所必需的,只要你的 reloadcmd 工作。
#
# 当颁发或续期证书时,acme.sh 会尝试在颁发证书之前运行一个命令。
# 这只能在颁发证书时应用,但它将被保存并用于续期。
#
# 即使证书未成功颁发/续期,这也会执行。
acme_sh_default_issue_pre_hook: ""

# 当颁发或续期证书时,acme.sh 会尝试在尝试颁发证书之后运行一个命令。
# 这只能在颁发证书时应用,但它将被保存并用于续期。
#
# 即使证书未成功颁发/续期,这也会执行。
acme_sh_default_issue_post_hook: ""

# 当证书已成功续期时,acme.sh 会尝试运行一条命令。
# 这只能在颁发证书时应用,但它将被保存并用于续期。
#
# 只有在证书成功颁发/续期时,这才会执行。
acme_sh_default_issue_renew_hook: ""

# 如果设置为 True,证书将被删除,并且不会再被设置为续期。
# 这不会卸载 acme.sh。
acme_sh_default_remove: False

# 此列表包含域名列表以及配置每组域名的键/值对。
#
# 这里有一个文档化的例子和几个真实示例,将在这个 README 的示例部分包含:
acme_sh_domains:
#  一个或多个域名的列表,你可以使用 ["example.com", "*.example.com"] 或 
#  ["*.example.com", "example.com"] 来设置通配符证书和根域名证书的组合。
#  列表中的第一个域名将被用作证书名称的基本文件名。
#
#  如果你想要单独的文件,请在列表中创建一个新的 "domains:" 项。
#  - domains: ["example.com", "www.example.com", "admin.example.com"]
#    # 可选覆盖默认的 staging 变量。
#    staging: False
#    # 可选强制颁发新证书。
#    force_issue: False
#    # 可选强制续期证书。
#    force_renew: False
#    # 可选打开调试模式。
#    debug: True
#    # 可选覆盖默认的 DNS 提供商。
#    dns_provider: "dns_namesilo"
#    # 可选覆盖默认的 DNS API 密钥。
#    dns_provider_api_keys:
#     "Namesilo_Key": "来自 Namesilo 控制面板的 API 密钥"
#    # 可选覆盖默认的 DNS 休眠时间。
#    dns_sleep: 900
#    # 可选将额外标志添加到这三个操作中的任何一个:
#    extra_flags_issue: ""
#    extra_flags_renew: ""
#    extra_flags_install_cert: ""
#    # 可选设置不同的重新加载命令。
#    install_cert_reloadcmd: "whoami"
#    # 可选在证书颁发过程中不同阶段运行命令:
#    extra_issue_pre_hook: ""
#    extra_issue_post_hook: ""
#    extra_issue_renew_hook: ""
#    # 可选删除并禁用证书。
#    remove: True

示例用法

为了这个示例,假设你有一个叫 app 的组,并且你有一个典型的 site.yml 文件。

要使用此角色,请编辑你的 site.yml 文件,使其看起来像这样:

---

- name: 配置应用服务器
  hosts: "app"
  become: True

  roles:
    - { role: "nickjj.acme_sh", tags: ["acme_sh"] }

这里有几个示例。你可以通过打开或创建 group_vars/app.yml 在你的 end 重现此示例,它位于相对于你的 inventory 目录,并且让它看起来像这样:

---

acme_sh_account_email: "[email protected]"

# 一个 DNS 提供商需要两个密钥进行 API 访问的示例:
acme_sh_default_dns_provider: "dns_cf"
acme_sh_default_dns_provider_api_keys:
  "CF_Key": "来自 Cloudflare 控制面板的 API 密钥"
  "CF_Email": "[email protected]"

# 在名为 "nginx" 的 Docker 容器中重新加载 nginx。
# 如果你在 Docker 容器中运行 nginx,那么你还需要挂载你的证书
# 但我相信你已经知道这一点了!
acme_sh_default_install_cert_reloadcmd: "docker exec nginx nginx -s reload"

# --- 这里是几个不同的 acme_sh_domains 示例 --------------------------
# 根据你想要做的事情,你只需提供其中一个即可!
# ------------------------------------------------------------------------------

# 为所有域名提供 1 个证书文件。
acme_sh_domains:
  - domains: ["example.com", "www.example.com", "admin.example.com"]

# 在你的服务器上生成:
#   /etc/ssl/ansible/example.com.key (私钥)
#   /etc/ssl/ansible/example.com.pem (完整证书链)

# ------------------------------------------------------------------------------

# 使用上面相同的域名生成 2 个证书文件。
acme_sh_domains:
  - domains: ["example.com", "www.example.com"]
  - domains: ["admin.example.com"]

# 在你的服务器上生成:
#   /etc/ssl/ansible/example.com.key (私钥)
#   /etc/ssl/ansible/example.com.pem (完整证书链)
#   /etc/ssl/ansible/admin.example.com.key (私钥)
#   /etc/ssl/ansible/admin.example.com.pem (完整证书链)

# ------------------------------------------------------------------------------

# 使用相同的例子,但会移除和禁用 admin 证书。
acme_sh_domains:
  - domains: ["example.com", "www.example.com"]
  - domains: ["admin.example.com"]
    remove: True

# 在你的服务器上生成:
#   /etc/ssl/ansible/example.com.key (私钥)
#   /etc/ssl/ansible/example.com.pem (完整证书链)

# ------------------------------------------------------------------------------

# 使用相同的例子,但在 admin.example.com 上从 staging 切换到 live
# (但记得在运行一次后移除 force_issue)。
acme_sh_domains:
  - domains: ["example.com", "www.example.com"]
  - domains: ["admin.example.com"]
    staging: False
    force_issue: True

# ------------------------------------------------------------------------------

# 使用相同的例子,但强制续期 admin.example.com 
#(假设发生了灾难性错误,证书过期了)。
acme_sh_domains:
  - domains: ["example.com", "www.example.com"]
  - domains: ["admin.example.com"]
    force_renew: True

*如果你在寻找一个 Ansible 角色来创建用户,请查看我的 用户角色*。

现在你可以运行 ansible-playbook -i inventory/hosts site.yml -t acme_sh

安装

$ ansible-galaxy install nickjj.acme_sh

Ansible Galaxy

你可以在官方的 Ansible Galaxy 找到它,如果你想评分。

许可

MIT

关于项目

Install and auto-renew SSL certificates with Let's Encrypt using acme.sh.

安装
ansible-galaxy install nickjj.acme_sh
许可证
mit
下载
48.8k
拥有者
Currently a self employed freelance developer & teacher. I mainly work with Flask, Rails, Bash, Docker, Kubernetes, Ansible & Terraform. Also a @docker captain.