unixcharles/acme-client
GitHub: unixcharles/acme-client
一个遵循 RFC 8555 标准的 Ruby 客户端库,用于在代码层面自动化处理 ACME 协议的证书申请、验证与管理流程。
Stars: 503 | Forks: 123
# Acme::Client
`acme-client` 是 ACME / [RFC 8555](https://tools.ietf.org/html/rfc8555) 协议的 Ruby 客户端实现。
你可以找到 Go 语言的 [服务端](https://github.com/letsencrypt/boulder) 和 Python 语言的 [客户端](https://github.com/certbot/certbot) 的 ACME 参考实现。
ACME 是 [Letsencrypt](https://letsencrypt.org/) 项目的一部分,该项目的目标是通过自动化获取和更新流程来提供免费的 SSL/TLS 证书。
## 安装
通过 RubyGems:
```
$ gem install acme-client
```
或者将其添加到 Gemfile 中:
```
gem 'acme-client'
```
## 用法
- [Acme::Client](#acmeclient)
- [安装](#installation)
- [用法](#usage)
- [设置客户端](#setting-up-a-client)
- [账户管理](#account-management)
- [获取证书](#obtaining-a-certificate)
- [订购证书](#ordering-a-certificate)
- [准备 HTTP 验证](#preparing-for-http-challenge)
- [准备 DNS 验证](#preparing-for-dns-challenge)
- [请求验证核查](#requesting-a-challenge-verification)
- [下载证书](#downloading-a-certificate)
- [订购备用证书](#ordering-an-alternative-certificate)
- [额外](#extra)
- [证书吊销](#certificate-revokation)
- [证书续期](#certificate-renewal)
- [未实现](#not-implemented)
- [环境要求](#requirements)
- [开发](#development)
- [Pull request?](#pull-request)
- [许可证](#license)
## 设置客户端
客户端使用私钥和 ACME 提供商的 directory URL 进行初始化。
LetsEncrypt 的 `directory` URL 是 `https://acme-v02.api.letsencrypt.org/directory`。
他们还有一个 staging endpoint,地址为 `https://acme-staging-v02.api.letsencrypt.org/directory`。
`acme-ruby` 接受 `OpenSSL::PKey::RSA` 或 `OpenSSL::PKey::EC`。
你可以使用 OpenSSL 在 Ruby 中生成一个。
```
require 'openssl'
private_key = OpenSSL::PKey::RSA.new(4096)
```
或者从 PEM 文件加载
```
require 'openssl'
OpenSSL::PKey::RSA.new(File.read('/path/to/private_key.pem'))
```
有关文档,请参阅 [RSA](https://ruby.github.io/openssl/OpenSSL/PKey/RSA.html) 和 [EC](https://ruby.github.io/openssl/OpenSSL/PKey/EC.html)。
```
client = Acme::Client.new(private_key: private_key, directory: 'https://acme-staging-v02.api.letsencrypt.org/directory')
```
如果你的账户已经注册,你可以通过直接传入 key ID 来节省一些 API 调用。这将避免从私钥检索 key ID 的多余 API 调用。
```
client = Acme::Client.new(private_key: private_key, directory: 'https://acme-staging-v02.api.letsencrypt.org/directory', kid: 'https://example.com/acme/acct/1')
```
## 账户管理
账户与私钥绑定。在允许创建订单之前,必须注册账户并使用私钥接受服务条款 (ToS)。账户将被分配一个 key ID。
```
client = Acme::Client.new(private_key: private_key, directory: 'https://acme-staging-v02.api.letsencrypt.org/directory')
account = client.new_account(contact: 'mailto:info@example.com', terms_of_service_agreed: true)
```
注册后,你可以检索账户密钥标识符 (kid)。
```
client = Acme::Client.new(private_key: private_key, directory: 'https://acme-staging-v02.api.letsencrypt.org/directory')
account = client.new_account(contact: 'mailto:info@example.com', terms_of_service_agreed: true)
account.kid # =>
```
如果你已经拥有一个现有账户(例如在 ACME v1 中创建的账户),请注意,除非在初始化时提供了 `kid`,否则客户端会在需要 `kid` 时通过向 `newAccount` 发送 `POST` 请求来延迟加载 `kid`。因此,你可以轻松获取现有账户的 `kid`,并(如果需要)将其存储以供复用:
```
client = Acme::Client.new(private_key: private_key, directory: 'https://acme-staging-v02.api.letsencrypt.org/directory')
# kid 未设置,因此调用 newAccount 以懒加载初始化 kid
client.kid
=> "https://acme-staging-v02.api.letsencrypt.org/acme/acct/000000"
```
## 外部账户绑定支持
你可以通过提供带有 `kid` 和 `hmac_key` 的 `external_account_binding` 来使用外部账户绑定。
```
client = Acme::Client.new(private_key: private_key, directory: 'https://acme.zerossl.com/v2/DV90')
account = client.new_account(contact: 'mailto:info@example.com', terms_of_service_agreed: true, external_account_binding: { kid: "your kid", hmac_key: "your hmac key"})
```
## 获取证书
### 订购证书
要订购新证书,客户端必须提供标识符列表。
返回的订单将包含一系列 `Authorization`,为了完成订单,这些授权需要被完成,通常每个标识符对应一个。
每个授权包含多个挑战 (challenge),通常是 `dns-01`、`dns-account-01` 和 `http-01` 挑战。申请人只需完成其中一项挑战。
`dns-account-01` 挑战在 `_acme-challenge` 之前添加一个特定于账户的标签,生成形式为 `_
标签:ACME协议, DNS验证, Gem包, HTTP验证, Let's Encrypt, OpenSSL, RFC 8555, Ruby, SSL证书, TLS, Web服务器, 加密, 安全测试工具, 客户端库, 密码学, 开源库, 手动系统调用, 搜索引擎爬虫, 漏洞扫描器, 知识库, 网络安全, 网络调试, 自动化, 证书管理, 证书颁发机构, 防御工具, 隐私保护