首页 > 解决方案 > Bazel 远程缓存不适用于证书/TLS

问题描述

我正在从docker 内部的https://github.com/buchgr/bazel-remote运行 Bazel 远程缓存,通过运行以下命令来启动httpgrpc服务器:

docker pull buchgr/bazel-remote-cache
docker run -u 1000:1000 -v /path/to/cache/dir:/data -p 9093:8080 -p 9094:9092 buchgr/bazel-remote-cache

到目前为止,我可以通过运行以下命令之一从客户端运行一些测试:

bazelisk test  --remote_cache=http://<SERVER_IP>:<SERVER_PORT> <TEST_TARGET>
bazelisk test  --remote_cache=grpc://<SERVER_IP>:<SERVER_PORT> <TEST_TARGET>

但是当我通过向服务器调用添加以下标志来让我的服务器在TLS上运行时:

-v /path/to/certificate_authority:/etc/bazel-remote/ca_cert
-v /path/to/server_cert:/etc/bazel-remote/server_cert
-v /path/to/server_key:/etc/bazel-remote/server_key
--tls_ca_file=/etc/bazel-remote/ca_cert
--tls_cert_file=/etc/bazel-remote/server_cert
--tls_key_file=/etc/bazel-remote/server_key

虽然我创建了一个根CA证书来签署我的服务器客户端的证书,但我无法通过httpsgrpcs访问我的服务器。https出现以下错误:

avax.net.ssl.SSLHandshakeException: General OpenSslEngine problem


sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target


sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

grpcs如下:

javax.net.ssl.SSLHandshakeException: General OpenSslEngine problem

java.security.cert.CertificateException: No subject alternative names present

ERROR: Failed to query remote execution capabilities: General OpenSslEngine problem

这个问题与根CA证书本身是自签名的事实有关,还是我在做其他愚蠢的事情?

我使用了以下链接中的相同命令:https ://github.com/bazelbuild/bazel/blob/master/src/test/testdata/test_tls_certificate/README.md

标签: httpsgrpctls1.2bazel

解决方案


对于grpcs,您的问题是客户端使用的主机名与证书不匹配。当我连接到localhost(就像那些默认的方向一样)时,它可以工作:

bazel test --remote_cache=grpcs://localhost:9094 --tls_client_certificate=/path/to/client.crt --tls_client_key=/path/to/client.pem --tls_certificate=/path/to/ca.crt //...

但是如果我切换到127.0.0.1,它会像你看到的那样失败。如果您有主机名,更改SERVER_CN以匹配它应该可以工作。不过,IP 地址有点棘手,因为您必须使用主题替代名称将证书与 IP 联系起来。我知道的最直接的方法是extensions.cnf用这一行创建一个文件:

subjectAltName=IP:<SERVER_IP>

然后-extfile在生成证书时使用该文件。您只需在说明末尾添加此命令即可生成包含它的新证书:

openssl x509 -req -passin pass:1111 -days 358000 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -extfile extensions.cnf

我不认为 bazel 支持带有https的客户端证书。您可以使用自定义信任库解决您遇到的问题,但我不知道如何通过客户端证书。使用该选项的代码的唯一部分看起来像是特定于 GRPC 的。文档并没有说清楚...

更多 x509 基础知识:CA 证书通常是自签名的,因为作为信任根的客户端并不关心它们是如何签名的。这些方向生成的服务器证书不是自签名的,这与 echo 语句相反。客户端验证他们从服务器接收的证书是否与他们尝试连接的实体匹配(例如,为 yourwebsite.com 颁发的证书不能被用来伪装成 google.com)。CN 是一个可以将它们绑定在一起的字段,subjectAltName 是一个扩展,可用于将证书绑定到各种格式的多个实体。


推荐阅读