证书管理
集群内部通信的证书
每个{PVE}集群默认创建自己的(自签名的)证书颁发机构(CA)并为每个节点生成一个由上述CA签名的证书。如果使用SPICE,这些证书被用于与集群的`pveproxy`服务以及Shell/Console特性的加密通信。
CA证书和密钥存储在Proxmox集群文件系统(pmxcfs)中。
API和Web界面的证书
REST API和web GUI由`pveproxy`服务提供,该服务在每个节点上运行。
您可以为`pveproxy`使用以下证书选项:
-
默认情况下,使用位于`/etc/pve/nodes/NODENAME/pve-ssl.pem`的节点特定证书。该证书由集群CA签名,因此不会被浏览器和操作系统自动信任。
-
使用外部提供的证书(例如,由商业CA签名的证书)。
-
使用ACME(Let’s Encrypt)获取可信任的证书,并自动更新,这也集成在{pve} API和网络接口中。
对于选项2和3,文件`/etc/pve/local/pveproxy-ssl.pem`(以及无需密码的`/etc/pve/local/pveproxy-ssl.key`)将会被使用。
Note
|
请记住,/etc/pve/local 是一个指向 /etc/pve/nodes/NODENAME 的节点特定的符号链接。
|
证书通过{PVE}节点管理命令管理(参见`pvenode(1)`手册页)。
Warning
|
不要替换或手动修改在 /etc/pve/local/pve-ssl.pem 和 /etc/pve/local/pve-ssl.key 中自动生成的节点证书文件,或者是在 /etc/pve/pve-root-ca.pem 和 /etc/pve/priv/pve-root-ca.key 中的集群CA文件。
|
上传自定义证书
如果您已经有了一个证书,想要用于{pve}节点,您可以简单地通过Web界面上传该证书。
请注意,如果提供了证书密钥文件,该文件必须不受密码保护。
通过Let’s Encrypt (ACME) 获取受信任的证书
{PVE} 包括对自动证书管理环境(ACME)协议的实现,允许 {pve} 管理员使用像 Let’s Encrypt 这样的 ACME 提供者来轻松设置 TLS 证书,这些证书在现代操作系统和网络浏览器中被默认接受和信任。
目前实现的两个ACME端点是https://letsencrypt.org[Let’s Encrypt (LE)]的生产环境及其测试环境。我们的ACME客户端支持使用内置的web服务器对`http-01`挑战进行验证,以及使用支持所有DNS API端点https://acme.sh[acme.sh]的DNS插件对`dns-01`挑战进行验证。
ACME账户
您需要为每个集群注册一个ACME账户,并使用您想要使用的终端。该账户使用的电子邮件地址将作为ACME终端发出的续订到期或类似通知的联系点。
您可以通过网页界面 Datacenter → ACME
或使用 pvenode
命令行工具来注册和停用 ACME 账户。
pvenode acme account register account-name mail@example.com
Tip
|
由于 https://letsencrypt.org/docs/rate-limits/ [速率限制],如果您是第一次使用ACME或进行实验,您应该使用LE staging 。
|
ACME 插件
ACME插件的任务是自动验证您,因此您所操作的 {pve} 集群,是域名的真正所有者。这是自动证书管理的基础构建模块。
ACME协议规定了不同类型的挑战,例如`http-01`,其中一个web服务器提供一个包含特定内容的文件,以证明它控制了一个域名。有时这是不可能的,可能是因为技术限制,或者如果记录的地址无法从公共互联网访问。在这些情况下可以使用`dns-01`挑战。完成这个挑战需要在域的区域中创建一个特定的DNS记录。
'''{pve} 默认支持这两种挑战类型,您可以在 Datacenter → ACME
的网络界面下配置插件,或者使用 pvenode acme plugin add
命令进行配置。'''
ACME 插件配置存储在 /etc/pve/priv/acme/plugins.cfg
。对于集群中的所有节点,都有一个可用的插件。
节点域
每个域都是节点特定的。您可以在 节点 → 证书
下添加新的或管理现有的域条目,或者使用 pvenode config
命令。
为节点配置好期望的域名并确保已选择期望的ACME账户后,您可以通过Web界面订购新证书。成功后,界面将在10秒后重新加载。
更新将会自动进行。
ACME HTTP 挑战插件
总是有一个隐式配置的`standalone`插件,用于通过在端口80上生成的内置Web服务器验证`http-01`挑战。
Note
|
名称`standalone`意味着它可以自行提供验证,无需任何第三方服务。因此,这个插件也适用于集群节点。 |
要使用它进行Let’s Encrypts ACME的证书管理,有一些先决条件。
-
你必须接受Let’s Encrypt的服务条款(ToS)才能注册账户。
-
节点的端口 80需要能够被互联网访问。
-
端口80上必须没有其他监听器。
-
请求的(子)域名需要解析到节点的公网IP地址。
ACME DNS API 挑战插件
在那些通过`http-01`方法进行验证的外部访问不可能或不希望的系统上,可以使用`dns-01`验证方法。这种验证方法需要一个允许通过API配置`TXT`记录的DNS服务器。
配置ACME DNS API进行验证
{PVE}重用了为`acme.sh`项目脚注:[acme.sh https://github.com/acmesh-official/acme.sh] 开发的DNS插件,请参阅其文档以获取特定API配置的详细信息。
使用DNS API配置新插件最简单的方法是通过网络界面(数据中心 → ACME
)。
选择`DNS`作为挑战类型。然后你可以选择你的API提供商,输入凭据数据以通过他们的API访问你的账户。
Tip
|
请查看 acme.sh 的 https://github.com/acmesh-official/acme.sh/wiki/dnsapi#how-to-use-dns-api [如何使用 DNS API] wiki,以获取有关如何为您的提供商获取 API 凭证的更详细信息。 |
鉴于存在许多DNS提供商和API端点,{pve}会自动为一些提供商生成凭证表单。对于其他提供商,您将看到一个更大的文本区域,只需将所有凭证的`KEY`=`VALUE`对复制到那里即可。
通过CNAME别名进行DNS验证
一种特殊的 alias
模式可以用来在不同的域名/DNS服务器上进行验证,以防你的主要/真实DNS不支持通过API进行配置。手动为 _acme-challenge.domain1.example
设置一个永久的 CNAME
记录,指向 _acme-challenge.domain2.example
,并在 {PVE} 节点配置文件中设置 alias
属性为 domain2.example
,以允许 domain2.example
的DNS服务器验证 domain1.example
的所有挑战。
插件组合
结合使用`http-01`和`dns-01`验证是可能的,以防您的节点通过满足不同要求/拥有不同DNS配置能力的多个域名可达。通过为每个域指定不同的插件实例,也可以混合来自多个提供商或实例的DNS API。
Tip
|
如果可能的话,应该避免通过多个域名访问同一服务,因为这会增加复杂性。 |
ACME证书的自动续订
如果一个节点已经成功地使用ACME提供的证书配置(无论是通过pvenode还是通过GUI),证书将会由`pve-daily-update.service`自动续期。目前,如果证书已经过期,或者将在未来30天内过期,将尝试续期。
ACME案例与`pvenode`相关操作
例子:使用 Let’s Encrypt 证书的 Sample pvenode
调用示例
root@proxmox:~# pvenode acme account register default mail@example.invalid Directory endpoints: 0) Let's Encrypt V2 (https://acme-v02.api.letsencrypt.org/directory) 1) Let's Encrypt V2 Staging (https://acme-staging-v02.api.letsencrypt.org/directory) 2) Custom Enter selection: 1 服务条款: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf 您同意上述条款吗?[y|N]y ... 任务完成 root@proxmox:~# pvenode config set --acme domains=example.invalid root@proxmox:~# pvenode acme cert order 加载ACME账户详细信息 下达ACME订单 ... 状态为'有效'! 所有域名已验证! ... 正在下载证书 设置 pveproxy 证书和密钥 重启 pveproxy 任务完成
示例:设置OVH API以验证域名
Note
|
无论使用哪些插件,账户注册步骤都是相同的,并且在此不再重复。 |
Note
|
OVH_AK` 和 OVH_AS 需要根据 OVH API 文档从 OVH 获取。
|
首先你需要获取所有信息,这样你和{pve}才能访问API。
root@proxmox:~# cat /path/to/api-token OVH_AK=XXXXXXXXXXXXXXXX OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY root@proxmox:~# source /path/to/api-token root@proxmox:~# curl -XPOST -H"X-Ovh-Application: $OVH_AK" -H "Content-type: application/json" \ https://eu.api.ovh.com/1.0/auth/credential -d '{ "accessRules": [ {"method": "GET","path": "/auth/time"}, {"method": "GET","path": "/domain"}, {"method": "GET","path": "/domain/zone/*"}, {"method": "GET","path": "/domain/zone/*/record"}, {"method": "POST","path": "/domain/zone/*/record"}, {"method": "POST","path": "/domain/zone/*/refresh"}, {"method": "PUT","path": "/domain/zone/*/record/"}, {"method": "DELETE","path": "/domain/zone/*/record/*"} ] }' {"consumerKey":"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ","state":"pendingValidation","validationUrl":"https://eu.api.ovh.com/auth/?credentialToken=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"} 打开验证链接并按照指引将应用程序密钥与账户/消费者密钥关联起来。 root@proxmox:~# echo "OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" >> /path/to/api-token
现在你可以设置ACME插件:
root@proxmox:~# pvenode acme plugin add dns example_plugin --api ovh --data /path/to/api_token root@proxmox:~# pvenode acme plugin config example_plugin ┌────────┬──────────────────────────────────────────┐ │ key │ value │ ╞════════╪══════════════════════════════════════════╡ │ api │ ovh │ ├────────┼──────────────────────────────────────────┤ │ data │ OVH_AK=XXXXXXXXXXXXXXXX │ │ │ OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY │ │ │ OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ │ ├────────┼──────────────────────────────────────────┤ │ digest │ 867fcf556363ca1bea866863093fcab83edf47a1 │ ├────────┼──────────────────────────────────────────┤ │ plugin │ example_plugin │ ├────────┼──────────────────────────────────────────┤ │ type │ dns │ └────────┴──────────────────────────────────────────┘
最后您可以配置您想要获取证书的域名,并为其下达证书订单:
root@proxmox:~# pvenode config set -acmedomain0 example.proxmox.com,plugin=example_plugin root@proxmox:~# pvenode acme cert order Loading ACME account details Placing ACME order Order URL: https://acme-staging-v02.api.letsencrypt.org/acme/order/11111111/22222222 从 'https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/33333333' 获取授权详情 example.proxmox.com 的验证等待中! [Wed Apr 22 09:25:30 CEST 2020] 使用 OVH 端点:ovh-eu [Wed Apr 22 09:25:30 CEST 2020] 正在检查认证 [Wed Apr 22 09:25:30 CEST 2020] 消费者密钥正常。 [Wed Apr 22 09:25:31 CEST 2020] 正在添加记录 [Wed Apr 22 09:25:32 CEST 2020] 已添加,等待10秒。 添加 TXT 记录:_acme-challenge.example.proxmox.com 触发验证 等待5秒 状态为'有效'! [Wed Apr 22 09:25:48 CEST 2020] 使用 OVH 端点:ovh-eu [Wed Apr 22 09:25:48 CEST 2020] 正在检查认证 [Wed Apr 22 09:25:48 CEST 2020] 消费者密钥正常。 移除 TXT 记录:_acme-challenge.example.proxmox.com 所有域名已验证! 创建CSR 检查订单状态 订单已准备好,正在完成订单 有效! 下载证书 设置 pveproxy 证书和密钥 重启 pveproxy 任务完成
示例:从`staging`环境切换到常规的ACME目录
更改账户的ACME目录是不支持的,但由于{pve}支持多个账户,您可以直接创建一个以生产(受信任的)ACME目录作为终点的新账户。您还可以停用测试账户并重新创建它。
pvenode
将 default
ACME 账户的目录从 staging
更改为。root@proxmox:~# pvenode acme account deactivate default Renaming account file from '/etc/pve/priv/acme/default' to '/etc/pve/priv/acme/_deactivated_default_4' Task OK root@proxmox:~# pvenode acme account register default example@proxmox.com Directory endpoints: 0) Let's Encrypt V2 (https://acme-v02.api.letsencrypt.org/directory) 1) Let's Encrypt V2 Staging (https://acme-staging-v02.api.letsencrypt.org/directory) 2) Custom Enter selection: 0 服务条款:https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf 你同意上述条款吗?[y|N]y ... 任务完成