grpc-java で HTTPS を使うための設定


gRPC は Google が公開しているオープンソースの RPC ライブラリです。gRPC は通信プロトコルに HTTP/2 を採用していますが、セキュアに通信したいときは HTTPS を利用することができます。しかし grpc-java には HTTPS を使う場合のサンプルコードがなく、若干ハマりがちです。健康で文化的な最低限度の設定を共有します。

設定

基本的には公式のドキュメント SECURITY.md が参考になります。

OpenSSL 依存性の設定

以下の Maven パッケージへの依存をビルド定義に記述します。

  • io.netty » netty-tcnative-boringssl-static » 1.1.33.Fork17
  • io.netty » netty-codec-http2 » 4.1.0.CR4

ここでは簡単のために tcnative static を使いましたが、dynamic との違いについては SECURITY.md#TLS with OpenSSL を読んでください。

サーバーの設定

NettyServerBuilder.forPort(port)
  .useTransportSecurity(
    new File("/path/to/your/certificate"),
    new File("/path/to/your/private-key")  // 秘密鍵は PKCS8 形式
  ).addService(...)
  .build()
  .start();

クライアントの設定

NettyChannelBuilder.forAddress(host, port)
  .sslContext(
    GrpcSslContexts.forClient().trustManager(new File("/path/to/root-ca-certificate")).build()
  ).build();

SslContext の生成には io.netty.handler.ssl.SslContextBuilder を使わず、GrpcSslContexts を使ってください。これは、gRPC サーバーが受け入れる cipher suite の利用を強制するために必要な設定です。

テスト

動作確認するとき、手元に正しい SSL 証明書があれば問題ありませんが、ない場合は grpc-go のリポジトリからテスト用の証明書・秘密鍵・ルートCA証明書を借りてくると楽です。証明書の CA の検証が行われるので、 openssl x509 -text -in grpc-go/testdata/server.crt で Subject Alternative Name を調べ、 /etc/hosts に設定しておきましょう。