KotlinでgRPC。SSL/TLSを有効にする方法をまとめた。


前回のエントリではgrpc/grpc-javaをベースにkotlinでgRPCを試しました。今回はSSL/TLSを有効にする方法をまとめていきます。grpc/grpc-java/SECURITY.mdを参照しながら進めました。

証明書を準備する

手元に適当な証明書がなかったのでgrpc-go/testdataにある証明書を利用しました。

Subject Alternative Name を確認するとマルチドメインに.test.google.fr, waterzooi.test.google.be, .test.youtube.comが定義されていますので、hostsにwaterzooi.test.google.beを追加しました。

1
openssl x509 -text -in ./server1.pem
1
127.0.0.1 waterzooi.test.google.be

OpenSSLを有効にする

netty-tcnativeをプロジェクトに追加します。

1
2
3
4
5
6
7
8
9
buildscript {
  repositories {
    mavenCentral()
  }
}

dependencies {
    compile 'io.netty:netty-tcnative-boringssl-static:1.1.33.Fork26'
}

netty-tcnativeはDynamicStaticがあります。このエントリではStaticを利用しました。grpc/grpc-java/SECURITY.mdを参照するとStaticの利用を推奨していますがOpenSSLのセキュリティパッチが提供された場合、Staticではパッチ反映が即座には行われないためプロジェクト方針によってはDynamicの利用を検討する必要があります。

GrpcSslContextsでSslContextを生成する

サーバ側とクライアント側ではGrpcSslContextsに定義されているforServerforClientのメソッドをつかってSslContextを生成します。

サーバ側

1
2
3
4
5
6
(serverBuilder as NettyServerBuilder).sslContext(
        GrpcSslContexts.forServer(
                File(classLoader.getResource("server1.pem").file),
                File(classLoader.getResource("server1.key").file))
                .clientAuth(ClientAuth.OPTIONAL)
                .build())

クライアント側

1
2
3
4
5
6
NettyChannelBuilder.forAddress("waterzooi.test.google.be", 50051)
        .sslContext(
                GrpcSslContexts.forClient()
                        .trustManager(File(classLoader.getResource("ca.pem").file))
                        .build())
        .build()

上記の実装を行えばSSL/TLSが有効になります。

コードを公開しています

このエントリのコードはgithubに公開しています。
SSL/TLSを有効にするにあたり情報が少ない印象をもちました。java or kotlinで実装をする方に少しでも参考になると嬉しいです。

関連エントリ

KotlinでgRPC。実運用にも活かせるWEBアプリケーション構成で試してみた。 - 平日インプット週末アウトプットぶろぐ