SSL/TLS 证书§
/certificates 部分的 控制 API 处理与 Unit 的 侦听器 一起使用的 TLS 证书。
要为侦听器设置 SSL/TLS,请将包含证书链和私钥的 .pem 文件上传到 Unit,并在侦听器的配置中命名上传的捆绑包;接下来,可以通过 SSL/TLS 访问侦听器。
注意
有关 Unit 中证书颁发和续订的详细信息,请参阅 TLS with Certbot 中的示例。
首先,使用证书链和私钥创建一个 .pem 文件
$ cat cert.pem ca.pem key.pem > bundle.pem
通常,网站的证书(可选,后面跟中间 CA 证书)足以构建证书链。如果您向链中添加更多证书,请按从叶到根的顺序排列它们。
将生成的捆绑包文件上传到 Unit 的证书存储中,并使用适当的名称(在本例中为 bundle)
# curl -X PUT --data-binary @bundle.pem --unix-socket \
/path/to/control.unit.sock https://127.0.0.1/certificates/bundle
{
"success": "Certificate chain uploaded."
}
警告
不要对使用 strong class="program">curl 上传的文件使用 -d;此选项会损坏 .pem 文件。在上传基于文件的 data 时,请使用 --data-binary 选项,以避免数据损坏。
在内部,Unit 将上传的证书捆绑包与其 state 子目录中的其他配置 data 一起存储;控制 API 使用 /certificates 将其中一些属性公开为 GET 表格 JSON
{
"certificates": {
"bundle": {
"key": "RSA (4096 bits)",
"chain": [
{
"subject": {
"common_name": "example.com",
"alt_names": [
"example.com",
"www.example.com"
],
"country": "US",
"state_or_province": "CA",
"organization": "Acme, Inc."
},
"issuer": {
"common_name": "intermediate.ca.example.com",
"country": "US",
"state_or_province": "CA",
"organization": "Acme Certification Authority"
},
"validity": {
"since": "Sep 18 19:46:19 2022 GMT",
"until": "Jun 15 19:46:19 2025 GMT"
}
},
{
"subject": {
"common_name": "intermediate.ca.example.com",
"country": "US",
"state_or_province": "CA",
"organization": "Acme Certification Authority"
},
"issuer": {
"common_name": "root.ca.example.com",
"country": "US",
"state_or_province": "CA",
"organization": "Acme Root Certification Authority"
},
"validity": {
"since": "Feb 22 22:45:55 2023 GMT",
"until": "Feb 21 22:45:55 2026 GMT"
}
}
]
}
}
}
注意
通过索引访问数组项,例如链中的各个证书及其属性
# curl -X GET --unix-socket /path/to/control.unit.sock \
https://127.0.0.1/certificates/bundle/chain/0/
# curl -X GET --unix-socket /path/to/control.unit.sock \
https://127.0.0.1/certificates/bundle/chain/0/subject/alt_names/0/
接下来,将上传的捆绑包添加到 侦听器;生成的控制 API 配置可能如下所示
{
"certificates": {
"bundle": {
"key": "<key type>",
"chain": [
"<certificate chain, omitted for brevity>"
]
}
},
"config": {
"listeners": {
"*:443": {
"pass": "applications/wsgi-app",
"tls": {
"certificate": "bundle"
}
}
},
"applications": {
"wsgi-app": {
"type": "python",
"module": "wsgi",
"path": "/usr/www/wsgi-app/"
}
}
}
}
全部完成;现在可以通过 SSL/TLS 访问应用程序
$ curl -v https://127.0.0.1
...
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / AES256-GCM-SHA384
...
最后,您可以从存储中删除不再需要的证书捆绑包
# curl -X DELETE --unix-socket /path/to/control.unit.sock \
https://127.0.0.1/certificates/bundle
{
"success": "Certificate deleted."
}
注意
您无法删除配置中仍然引用的证书捆绑包,使用 put 覆盖现有捆绑包,或删除不存在的捆绑包。