Hyperledger Fabric - 来自 fabric-ca 的带有 TLS 的外部链代码
Hyperledger Fabric - external chaincode with TLS from fabric-ca
我正在尝试使用新的外部链代码服务功能设置 Hyperledger Fabric。 运行 具有默认配置(无 tls 或对等身份验证)的链代码按预期工作。
我已经阅读了很多关于这个主题的教程,但它们都只为此目的使用自签名证书 - 这不是很有帮助,因为我正在配置生产系统。我想使用我的网络中已经 运行 的证书颁发机构 (fabric-ca-server),并为我的订购者、同行等提供证书。
我的问题是:如何使用我现有的 CA 生成 root_cert 以及 client_cert 和 client_key?必须有一种方法可以使用 fabric-ca-client 来做到这一点。我已经尝试使用我的同行组织的 ca 证书,但那没有用(它似乎不包含链代码服务的主机名)。
感谢您的帮助。
更新:
我现在尝试使用 fabric-ca-client 的 register 和 enroll 命令来注册身份并为自己获取 tls Enrollment-profile。
fabric-ca-client register --caname $CANAME --id.name chaincode --id.secret chainpw --tls.certfiles $certfile --loglevel error
fabric-ca-client enroll -u https://chaincode: chainpw@$CA_HOST_ADDRESS:$nodePort --caname $CANAME -M "$chainDir/msp" --csr.cn diplom-$validK8SHostName --csr.hosts diplom-$validK8SHostName --tls.certfiles $certfile --loglevel error
fabric-ca-client enroll -u https://chaincode: chainpw@$CA_HOST_ADDRESS:$nodePort --caname $CANAME -M "$chainDir/tls" --enrollment.profile tls --csr.hosts diplom-$validK8SHostName --csr.hosts localhost --tls.certfiles $certfile --loglevel error
我从生成的 tls 目录中取出 /signcerts/cert.pem
并通过 awk 'NF {sub(/\r/, ""); printf "%s\n",[=14=];}' ...
将其格式化为单行并将其粘贴到 connection.json 中作为 root_cert
。
同样,我已将 cert.pem 文件复制到链代码容器中,并将环境变量 CORE_CHAINCODE_TLS_CLIENT_CACERT_FILE
设置为指向该文件。但是,对等点仍然无法连接到容器。
ClientHandshake -> ERRO 06c Client TLS handshake failed after 752.754µs with error: tls: first record does not look like a TLS handshake
更新 2:
好像我在链代码服务上设置了错误的环境变量。 CORE_CHAINCODE_TLS_CERT_FILE
必须设置为生成的 /signcerts/cert.pem
,CORE_CHAINCODE_TLS_KEY_FILE
必须设置为来自 /keystore
.
的私钥
链码服务现在似乎可以接受证书,但对等点抱怨它们是由未知机构签署的。
更新 3:
又一点进步。好像我在 fabric-ca-client
命令中犯了一个错误。我不小心设置了 csr.cn 参数,从而覆盖了我的 CA 主机名。在他的帮助下,我能够在我的 CA 中注册我的链代码服务,并获得相应的 TLS 证书,以便对我的服务有效并通过组织 CA 结帐:-)
fabric-ca-client register --caname $CANAME --id.name $NAME --id.secret $PW --tls.certfiles $certfile --loglevel error
fabric-ca-client enroll -u https://$NAME:$PW@$CA_HOST_ADDRESS:$nodePort --caname $CANAME -M "$chainDir/msp" --csr.hosts chain-$validK8SHostName --tls.certfiles $certfile --loglevel error
fabric-ca-client enroll -u https://$NAME:$PW@$CA_HOST_ADDRESS:$nodePort --caname $CANAME -M "$chainDir/tls" --enrollment.profile tls --csr.hosts chain-$validK8SHostName --csr.hosts localhost --tls.certfiles $certfile --loglevel error
initializing a CA server 上的 Fabric CA 文档提到:
The fabric-ca-server init
command generates a self-signed CA
certificate unless the -u <parent-fabric-ca-server-URL>
option is
specified. If the -u
is specified, the server’s CA certificate is
signed by the parent Fabric CA server. In order to authenticate to the
parent Fabric CA server, the URL must be of the form
<scheme>://<enrollmentID>:<secret>@<host>:<port>
, where <enrollmentID>
and <secret>
correspond to an identity with an hf.IntermediateCA
attribute whose value equals true
.
它还说你可以设置一个已经生成的密钥和证书文件
If you want the Fabric CA server to use a CA signing certificate and
key file which you provide, you must place your files in the location
referenced by ca.certfile
and ca.keyfile
respectively. Both files must
be PEM-encoded and must not be encrypted. More specifically, the
contents of the CA certificate file must begin with -----BEGIN CERTIFICATE-----
and the contents of the key file must begin with
-----BEGIN PRIVATE KEY-----
and not -----BEGIN ENCRYPTED PRIVATE KEY-----
.
因此,如果您已经拥有 CA 服务器 运行,则应该可以获得由其签名的证书或创建一个并将其包含在您的子 CA 中
我终于找到了问题的答案。正如我在第三次更新中所述,我已经使用 fabric-ca-client
为我的链代码服务注册了一个身份。
fabric-ca-client register --caname $CANAME --id.name $NAME --id.secret $PW --tls.certfiles $certfile --loglevel error
fabric-ca-client enroll -u https://$NAME:$PW@$CA_HOST_ADDRESS:$nodePort --caname $CANAME -M "$chainDir/msp" --csr.hosts chain-$validK8SHostName --tls.certfiles $certfile --loglevel error
fabric-ca-client enroll -u https://$NAME:$PW@$CA_HOST_ADDRESS:$nodePort --caname $CANAME -M "$chainDir/tls" --enrollment.profile tls --csr.hosts chain-$validK8SHostName --csr.hosts localhost --tls.certfiles $certfile --loglevel error
请注意,validK8SHostName
只是我容器的主机名,其中的点被破折号代替(k8s 不允许在服务或容器名称中使用点)。
这些命令在我的 chaindDir
中生成了一个 msp
和 tls
文件夹。引用为 JSON 属性的 certificates/keys 使用 awk 'NF {sub(/\r/, ""); printf "%s\n",[=16=];}'
转换为单行。链代码容器的环境变量是实际文件(我已将它们作为秘密安装在我的 k8s 集群中)。
tls/signcerts
-> “root_cert”属性 和 CORE_CHAINCODE_TLS_CERT_FILE 环境需要认证。
tls/keystore
-> 为 CORE_CHAINCODE_TLS_KEY_FILE 环境设置的私钥。
tls/tlscacerts
-> CORE_CHAINCODE_TLS_CLIENT_CA_CERT_FILE 环境需要证书。
msp/signcert
-> "client_cert" 属性. 需要证书
msp/keystore
-> 为“client_key”设置的私钥 属性
通过设置,我可以启动以 TLS 终止的链代码容器,并且只与那些具有相应证书和私钥组合的对等方通信。因此,所有证书和密钥均由我的组织 CA 生成。
有关其他信息,https://github.com/hyperledgendary/contract-as-a-service 是一个将链代码显示为外部服务的示例存储库。
那里采用的方法确实是 Victor 上面描述的方法,据我所知这是一个很好的方法。
我正在尝试使用新的外部链代码服务功能设置 Hyperledger Fabric。 运行 具有默认配置(无 tls 或对等身份验证)的链代码按预期工作。
我已经阅读了很多关于这个主题的教程,但它们都只为此目的使用自签名证书 - 这不是很有帮助,因为我正在配置生产系统。我想使用我的网络中已经 运行 的证书颁发机构 (fabric-ca-server),并为我的订购者、同行等提供证书。
我的问题是:如何使用我现有的 CA 生成 root_cert 以及 client_cert 和 client_key?必须有一种方法可以使用 fabric-ca-client 来做到这一点。我已经尝试使用我的同行组织的 ca 证书,但那没有用(它似乎不包含链代码服务的主机名)。
感谢您的帮助。
更新:
我现在尝试使用 fabric-ca-client 的 register 和 enroll 命令来注册身份并为自己获取 tls Enrollment-profile。
fabric-ca-client register --caname $CANAME --id.name chaincode --id.secret chainpw --tls.certfiles $certfile --loglevel error
fabric-ca-client enroll -u https://chaincode: chainpw@$CA_HOST_ADDRESS:$nodePort --caname $CANAME -M "$chainDir/msp" --csr.cn diplom-$validK8SHostName --csr.hosts diplom-$validK8SHostName --tls.certfiles $certfile --loglevel error
fabric-ca-client enroll -u https://chaincode: chainpw@$CA_HOST_ADDRESS:$nodePort --caname $CANAME -M "$chainDir/tls" --enrollment.profile tls --csr.hosts diplom-$validK8SHostName --csr.hosts localhost --tls.certfiles $certfile --loglevel error
我从生成的 tls 目录中取出 /signcerts/cert.pem
并通过 awk 'NF {sub(/\r/, ""); printf "%s\n",[=14=];}' ...
将其格式化为单行并将其粘贴到 connection.json 中作为 root_cert
。
同样,我已将 cert.pem 文件复制到链代码容器中,并将环境变量 CORE_CHAINCODE_TLS_CLIENT_CACERT_FILE
设置为指向该文件。但是,对等点仍然无法连接到容器。
ClientHandshake -> ERRO 06c Client TLS handshake failed after 752.754µs with error: tls: first record does not look like a TLS handshake
更新 2:
好像我在链代码服务上设置了错误的环境变量。 CORE_CHAINCODE_TLS_CERT_FILE
必须设置为生成的 /signcerts/cert.pem
,CORE_CHAINCODE_TLS_KEY_FILE
必须设置为来自 /keystore
.
链码服务现在似乎可以接受证书,但对等点抱怨它们是由未知机构签署的。
更新 3:
又一点进步。好像我在 fabric-ca-client
命令中犯了一个错误。我不小心设置了 csr.cn 参数,从而覆盖了我的 CA 主机名。在他的帮助下,我能够在我的 CA 中注册我的链代码服务,并获得相应的 TLS 证书,以便对我的服务有效并通过组织 CA 结帐:-)
fabric-ca-client register --caname $CANAME --id.name $NAME --id.secret $PW --tls.certfiles $certfile --loglevel error
fabric-ca-client enroll -u https://$NAME:$PW@$CA_HOST_ADDRESS:$nodePort --caname $CANAME -M "$chainDir/msp" --csr.hosts chain-$validK8SHostName --tls.certfiles $certfile --loglevel error
fabric-ca-client enroll -u https://$NAME:$PW@$CA_HOST_ADDRESS:$nodePort --caname $CANAME -M "$chainDir/tls" --enrollment.profile tls --csr.hosts chain-$validK8SHostName --csr.hosts localhost --tls.certfiles $certfile --loglevel error
initializing a CA server 上的 Fabric CA 文档提到:
The
fabric-ca-server init
command generates a self-signed CA certificate unless the-u <parent-fabric-ca-server-URL>
option is specified. If the-u
is specified, the server’s CA certificate is signed by the parent Fabric CA server. In order to authenticate to the parent Fabric CA server, the URL must be of the form<scheme>://<enrollmentID>:<secret>@<host>:<port>
, where<enrollmentID>
and<secret>
correspond to an identity with anhf.IntermediateCA
attribute whose value equalstrue
.
它还说你可以设置一个已经生成的密钥和证书文件
If you want the Fabric CA server to use a CA signing certificate and key file which you provide, you must place your files in the location referenced by
ca.certfile
andca.keyfile
respectively. Both files must be PEM-encoded and must not be encrypted. More specifically, the contents of the CA certificate file must begin with-----BEGIN CERTIFICATE-----
and the contents of the key file must begin with-----BEGIN PRIVATE KEY-----
and not-----BEGIN ENCRYPTED PRIVATE KEY-----
.
因此,如果您已经拥有 CA 服务器 运行,则应该可以获得由其签名的证书或创建一个并将其包含在您的子 CA 中
我终于找到了问题的答案。正如我在第三次更新中所述,我已经使用 fabric-ca-client
为我的链代码服务注册了一个身份。
fabric-ca-client register --caname $CANAME --id.name $NAME --id.secret $PW --tls.certfiles $certfile --loglevel error
fabric-ca-client enroll -u https://$NAME:$PW@$CA_HOST_ADDRESS:$nodePort --caname $CANAME -M "$chainDir/msp" --csr.hosts chain-$validK8SHostName --tls.certfiles $certfile --loglevel error
fabric-ca-client enroll -u https://$NAME:$PW@$CA_HOST_ADDRESS:$nodePort --caname $CANAME -M "$chainDir/tls" --enrollment.profile tls --csr.hosts chain-$validK8SHostName --csr.hosts localhost --tls.certfiles $certfile --loglevel error
请注意,validK8SHostName
只是我容器的主机名,其中的点被破折号代替(k8s 不允许在服务或容器名称中使用点)。
这些命令在我的 chaindDir
中生成了一个 msp
和 tls
文件夹。引用为 JSON 属性的 certificates/keys 使用 awk 'NF {sub(/\r/, ""); printf "%s\n",[=16=];}'
转换为单行。链代码容器的环境变量是实际文件(我已将它们作为秘密安装在我的 k8s 集群中)。
tls/signcerts
-> “root_cert”属性 和 CORE_CHAINCODE_TLS_CERT_FILE 环境需要认证。tls/keystore
-> 为 CORE_CHAINCODE_TLS_KEY_FILE 环境设置的私钥。tls/tlscacerts
-> CORE_CHAINCODE_TLS_CLIENT_CA_CERT_FILE 环境需要证书。msp/signcert
-> "client_cert" 属性. 需要证书
msp/keystore
-> 为“client_key”设置的私钥 属性
通过设置,我可以启动以 TLS 终止的链代码容器,并且只与那些具有相应证书和私钥组合的对等方通信。因此,所有证书和密钥均由我的组织 CA 生成。
有关其他信息,https://github.com/hyperledgendary/contract-as-a-service 是一个将链代码显示为外部服务的示例存储库。
那里采用的方法确实是 Victor 上面描述的方法,据我所知这是一个很好的方法。