我现在花了太多时间试图弄清楚这一点,我真的需要一个指针。tl;dr 是我需要在一个节点上手动生成证书,然后通过 API 发出证书请求。
根据官方文档,这应该是相当直截了当的。这就是我所做的。
为 myhost.foobar.local 生成证书(来自客户端)
$ puppet cert generate myhost.foobar.local
从证书生成 CSR(来自客户端)
$ openssl req -new -key /var/lib/puppet/ssl/private_keys/myhost.foobar.local.pem -subj "/CN=myhost.foobar.local" -out request.csr
向 Puppet Master 发出证书请求(来自客户端)
该 API 已为远程 API 调用开放,因此我们可以从测试节点进行 API 调用。但是,我只得到一个错误。
$ curl -k -X PUT -H "Content-Type: text/plain" --data-binary @request.csr https://puppetmaster:8140/production/certificate_request/no_key
Could not intern from s: not enough data
其他调用工作得很好,例如:
$ curl -k -H "Accept: pson" https://puppetmaster:8140/production/certificate_statuses/all
[
{
"state" : "signed",
"fingerprints" : {
"default" : "5A:35:D2:19:59:C6:6E:B8:BE:64:54:FA:14:10:CE:FC:4A:C8:45:F6:DE:8E:7C:E9:2D:B0:5B:E0:5D:93:35:DD",
"SHA256" : "5A:35:D2:19:59:C6:6E:B8:BE:64:54:FA:14:10:CE:FC:4A:C8:45:F6:DE:8E:7C:E9:2D:B0:5B:E0:5D:93:35:DD",
"SHA1" : "04:13:AF:B9:CB:44:01:64:24:C9:E0:D6:F4:0D:60:41:52:77:EE:45",
"SHA512" : "2C:97:11:B9:ED:38:00:1F:B0:7B:75:ED:4C:DB:B1:3E:3D:63:09:C1:38:E2:A3:4F:50:A4:FD:71:FF:55:94:C3:7A:0B:F6:D5:79:09:6D:53:39:B1:EC:C2:BF:DF:CD:9B:67:60:B9:9C:0C:82:51:E9:23:30:AA:33:AC:8B:E9:94"
},
"name" : "puppet.foobar.local",
"dns_alt_names" : [
"DNS:puppet",
"DNS:puppet.foobar.local"
],
"fingerprint" : "5A:35:D2:19:59:C6:6E:B8:BE:64:54:FA:14:10:CE:FC:4A:C8:45:F6:DE:8E:7C:E9:2D:B0:5B:E0:5D:93:35:DD"
},
{
"state" : "signed",
"fingerprints" : {
"default" : "32:7B:B3:4E:BE:EB:66:21:E5:96:D0:7B:BA:BF:1D:FC:D5:90:E1:6F:52:6B:AB:CF:98:7E:2A:E3:48:00:A2:CF",
"SHA256" : "32:7B:B3:4E:BE:EB:66:21:E5:96:D0:7B:BA:BF:1D:FC:D5:90:E1:6F:52:6B:AB:CF:98:7E:2A:E3:48:00:A2:CF",
"SHA1" : "A4:17:D3:05:8A:72:BE:6C:C2:0C:FA:C4:8A:3B:6E:C4:29:90:4B:95",
"SHA512" : "2D:C3:EE:7E:E3:39:99:C8:21:B8:97:E8:BF:FE:62:26:A8:B8:63:30:C9:F1:77:80:DB:FC:DF:B8:ED:1E:A2:6C:C2:F9:FE:5D:CA:17:D9:08:1E:EB:AA:AF:3D:99:A6:F9:3D:E6:86:A0:B3:3F:E9:EC:1C:7F:25:95:B5:D6:7C:51"
},
"name" : "965c252e48c3",
"dns_alt_names" : [
],
"fingerprint" : "32:7B:B3:4E:BE:EB:66:21:E5:96:D0:7B:BA:BF:1D:FC:D5:90:E1:6F:52:6B:AB:CF:98:7E:2A:E3:48:00:A2:CF"
}
]
(为便于阅读而格式化)
我不确定我是否在这里遗漏了什么。所有其他 API 调用似乎都可以正常工作,包括节点的签名和删除/撤销。只是证书请求调用似乎失败了。也许我错过了一些明显的东西。
Puppet master 正在运行“3.7.2-1puppetlabs”。
与 Puppet Labs 的优秀人员一起解决了这个问题。正确的签名证书请求调用应该是:
首先,我注意到在您的 shell 片段中,您的提示符是“$”。毫无疑问,我的 puppet 配置与我的不同,但我需要以 root 身份运行这些命令。在客户端系统上几乎可以肯定,您将以 root 身份运行 puppet。如果您以 root 以外的身份运行 puppetmaster,那么您可能会以该用户身份运行 puppet CA 命令。
其次,(同样,您的设置可能有所不同),我从不需要直接运行 openssl 命令。我用 puppet 命令做所有事情。
我要做的是:
首先,确保您的客户的 FQDN 符合您的要求,因为这将用于证书的命名。检查与
hostname -f
在客户端系统上(以 root 身份):
假设密钥尚未退出,上面将显示证书的指纹,但如果您随后需要显示它,请使用:
在 puppetmaster 上(以 root 身份):
检查指纹,然后执行:
如果出现问题,则在 /var/lib/puppet/ssl(在客户端)和 /var/lib/puppet/ssl/ca(在主服务器上)中查找各种密钥、证书和证书请求。以我的经验,布局是不言自明的,擦除东西并期望它重新生成是安全的。
我确实看到您在专门询问 API,但您真的需要手动访问它吗?如果你这样做了,那么按照上面的方法,生成证书、证书请求等,然后使用 openssl 命令查看在我指定的位置创建的文件,并与你生成的文件进行比较。
如果归结为查看 puppet 如何格式化 API 请求,我会做的是使用 ltrace 来捕获传入/传出 openssl 库调用的数据。更熟悉 ruby 框架 puppet 使用的人可能会选择在其中插入一些调试代码。(虽然 ltrace 在生产服务器上更安全)