TSLなし、TSLあり、TSL+Client 証明書という環境のテストをKafkaクライアントから実施したいと思っている。
多分Bitnami の helm チャートが一番簡単っぽいので、それでコンフィグレーション出来るようにしたい。
ところが、自分が十分に openssl
や keytool
をよくわかっていないことが分かったので、そのチュートリアルで使われている スクリプトで使われている openssl
と keytool
のコマンドを理解しながら何をやっているか整理したいと思う。
1. CA certificate と CA の Private Key の作成
詳細のオプションの説明は下に書いておいたが、CA の Private Key と、CA の自己署名証明書を作成している。作成時には証明書に下記の情報を入れる必要があり、最初に証明書のパスワードを聞かれるので入力している。Common Name
は、通常は Server FQDN
を入れるのだと思うが、自分の名前でもよさげなので、自己証明書なので、自分の名前を入れておく。
Line 70
$ openssl req -new -x509 -keyout ca-private-key -out ca.crt -days 1000
Generating a RSA private key
.....................+++++
..............................................+++++
writing new private key to 'ca-private-key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Washington
Locality Name (eg, city) []:Kirkland
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Simplearchitect
Organizational Unit Name (eg, section) []:Main
Common Name (e.g. server FQDN or YOUR name) []:tsushi
Email Address []:MY_EMAIL_HERE
-
req
: サブコマンド。PKCS#10 の証明書リクエストと、証明書を作成するユーティリティ -
-new
: 証明書のリクエストを作成する。-key
が指定されていなければ、RSA の private keyを作成する。 -
-x509
: 証明書リクエストの代わりに、自己署名証明書(SelfSignedCertificate) を出力する -
-keyout
: 新しく作られた private key を出力する -
-out
: 標準出力をファイルに出力する。この場合、-x509
の項目が指定されているので自己署名証明書が出力される -
-days
: 出力される証明書の有効日数。デフォルトは30 日
NOTE: man openssl req
より
Output
$ ls
ca-private-key ca.crt
``
# 2. Ca証明書 を trust keystore に格納
1. で作成した、CA用の 証明書を Keystore に入れる。`openssl` と `keytool` はやれることがオーバーラップしてややこしいが、`keytool` しかできないことに、KeyStoreの作成がある。KeyStore は証明書をエイリアスをつけて格納できたり、取り出せたりするキーストアだ。Java のエコシステムでよく使われる。Kafaも、Javaで作られているので、これを参照するのだと思う。ただ、他の言語がクライアントの場合は、KeyStoreを使わない場合が多いと思うので、理屈を知っておく必要がある。実行時に1.で聞かれたパスワードを聞かれる
_Line 92_
```bash
keytool -keystore kafka.truststore.jks -alias CARoot -import -file ca.crt
-
-import
: サブコマンドimportcert
と同様。証明書か証明書チェーン (PKCS#7 reply か X.509証明書)を読み込んでキーストアに入れる。 -
-keystore
: キーストア。なければ作成される。 -
-alias
: ストアされるエンテイティ(証明書)のエイリアス -
-file
: 読み込む証明書
Output
新たにキーストアが作成されている。
$ ls
ca-private-key ca.crt kafka.truststore.jks
3. キーペアと、証明書の作成、キーストアへの格納
ここでいう証明書は、CA証明書にサインされる予定の証明書で、サーバーに格納されるなどの用途で使われる証明書です。
Line 144
keytool -keystore kafka.keystore.jks -alias localhost -validity 1000 -genkey -keyalg RSA
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: Tsuyoshi Ushio
What is the name of your organizational unit?
[Unknown]: Simplearchitect
What is the name of your organization?
[Unknown]: Main
What is the name of your City or Locality?
[Unknown]: Kirkland
What is the name of your State or Province?
[Unknown]: Washington
What is the two-letter country code for this unit?
[Unknown]: US
Is CN=Tsuyoshi Ushio, OU=Simplearchitect, O=Main, L=Kirkland, ST=Washington, C=US correct?
[no]: yes
-
-genkey
: サブコマンド。-genkeypair
と同様。Key Pair (Private/Public key) と、X.509 の自己証明書が、証明書チェーンとしてストアされる。 -
-validity
: 有効日数 -
-keyalg
: キーアルゴリズム名
Output
$ ls
ca-private-key ca.crt kafka.keystore.jks kafka.truststore.jks
4. キーストアから、CA証明書を取り出す
Line 157
$ keytool -keystore kafka.truststore.jks -export -alias CARoot -rfc -file ca.crt.exported
Enter keystore password:
Certificate stored in file <ca.crt.exported>
KeyStoreから、出力されたCA証明書は同じものです。スペースが違うので、-b
オプションをdiffに着けていいます。
$ls
ca-private-key ca.crt ca.crt.exported kafka.keystore.jks kafka.truststore.jks
$diff ca.crt ca.crt.exported -b
5. 証明書のサインリクエストを取得する
先ほど 3. で作成した自己証明書に対して、サインリクエストを作成します。
Line 163
$ keytool -keystore kafka.keystore.jks -alias localhost -certreq -file cert-sign-request
Output
$ls
ca-private-key ca.crt ca.crt.exported cert-sign-request kafka.keystore.jks kafka.truststore.jks
6. CA の Private Key で証明書にサインする
Line 170
$ openssl x509 -req -CA ca.crt -CAkey ca-private-key -in cert-sign-request -out signed.crt -days 1000 -CAcreateserial
Signature ok
subject=C = US, ST = Washington, L = Kirkland, O = Main, OU = Simplearchitect, CN = Tsuyoshi Ushio
Getting CA Private Key
Enter pass phrase for ca-private-key:
-
x509
: 証明書のサインと表示のためのユーティリティ -
-out
: 標準出力から読み込みを行う -
-CA
: CA 証明書を指定する -
-CaKey
: CA の Private Key を指定する -
-req
: デフォルトでは、標準入力から証明書を読み込むが、代わりにリクエストを読み込む -
-CAcreateserial
: CAシリアルナンバーファイルが出力される(使用が推奨される)
Output
サインされた証明書が出力されている。また、CAのシリアルファイル ca.srl
が出力されている。
ca-private-key ca.crt ca.crt.exported ca.srl cert-sign-request kafka.keystore.jks kafka.truststore.jks signed.crt
7. CA 証明書をキーストアに入れる
Line 180
$ keytool -keystore kafka.keystore.jks -alias CARoot -import -file ca.crt
スクリプトではこの後、CA証明書を消している。キーストアから取り出せるから
8. サインされた証明書をキーツールに格納する
Line 188
keytool -keystore kafka.keystore.jks -alias localhost -import -file signed.crt
まとめ
スクリプトで一瞬で生成されて、keystore
に明るくなかったので、どうしたらいいんだろう?と思っていましたが、全部解析してみると keytool
と openssl
のコマンドを背景含めて理解できました。
Resource
下記のほかには、man openssl <subcommand>
で検索すると良いマニュアルが出てきました。
- keytool 古いので古い名前が参照されている(e.g. -import)
- keytool common options
- A Java “keytool genkey” example
- openssl コマンドの使い方 かなり良い openssl の使い方
- Java “keytool import”: How to import a certificate into a keystore file