etcd TLS 全攻略

最近做了一个分布式数据推送项目,第一版是用普通 http 轮询,第二版是 grpc 的 stream 长连接,第三版是用 etcd 的 watch 功能进行监听。其中跨机房的数据备份是用官方提供的 make-mirror,于是乎如何在公网上安全保密的传输就格外重要了。

make-mirror

  • 首先,make-mirror 这个官方工具有个巨大的缺点,就是假如两个 etcd 集群都设了账号密码,只有在源 etcd 集群可以配置账号密码,并没有配置目标 etcd 集群的入口。
  • 所以只能使用 TLS Common Name 去做安全保密的传输。

生成证书

  • 因为项目是用 Java 写的,同时需要使用 v3 的 client,所以选择 jetcd 。由于 jetcd 的本质是 grpc,所以一开始我以为生成证书是和 grpc-java 里的方式一样。但这是错误的姿势!!但这是错误的姿势!!但这是错误的姿势!!
  • 正确的姿势是使用 cfssl ,详见官方文档,同时官方还有一个非常好的 demo。亲测可以搭一个 etcd 集群起来。然后你可以使用 etcdctl ,再加上证书进行访问。
  • 使用 jetcd 的话,还需要对证书进行转换,然后使用转换过的证书。
openssl pkcs8 -topk8 -nocrypt -in cert/etcd1-key.pem -out cert/etcd1.key

jetcd 配合证书进行访问

  • 生成了证书只是成功了一半。之后还需要用 jetcd 使用证书访问 etcd,首先说一下 jetcd-core 和 jetcd-all 的差别,当你的项目有 netty 和 grpc 全套相关依赖时,使用 jetcd-all,这样可以避免版本不一致导致的包冲突。如果没有,请使用 jetcd-core。jetcd-all 是对一些常用包名做了替换。
  • 使用了 jetcd-core,仍然会有java.lang.IllegalStateException: Could not find TLS ALPN provider; no working netty-tcnative, Conscrypt, or Jetty NPN/ALPN availabler 之类的报错。主要是因为 jetcd 使用的是 grpc-netty,而我们之前用 grpc-netty-shaded。下面是官方原话

Users of grpc-netty-shaded will automatically use netty-tcnative with BoringSSL.
grpc-netty users will need to add the appropriate netty-tcnative-boringssl-static artifact to the application’s classpath. Artifacts are available for 64 bit Windows, OS X, and 64 bit Linux.

  • 所以需要使用 netty-tcnative-boringssl-static
  <dependencies>
    <dependency>
      <groupId>io.netty</groupId>
      <artifactId>netty-tcnative-boringssl-static</artifactId>
      <version>2.0.20.Final</version> <!-- See table for correct version -->
      <scope>runtime</scope>
    </dependency>
  </dependencies>
  • 注意,要使用正确的版本号!!要使用正确的版本号!!要使用正确的版本号!!

正确版本号

结束语

  • 路漫漫其修远兮,好记性不如烂键盘。加油加油!坚持月更!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章