TWLogEye開発17日目:gRPCの完璧な暗号通知ができて狂喜乱舞しています
今朝は4時前に自力でおきました。助手の猫さんは、1階の自分のベッドで熟睡していました。今(6時前)かみさんの布団に来たみたいです。騒いでいたので、noteを書くのを中断して、ご飯を上げに行ってきました。
今朝、早く起きたのは、gRPCの暗号通信に対応するためです。
Go言語でgRPCの暗号通信をする方法は、
を読んで、おおまかに理解してから大元の
を読みました。
大元の説明によるとgRPCの暗号化には、
TLS
mTLS(mutual TLS)
ALTS(Google's Application Layer Transport Security)
があります。ALTSは、何となく最新感があって使ってみたくなりましたが、よく読むとGoogleのGCPでしか使えないようなので諦めました。
なので、TLSとmTLSに対応することにしました。暗号なしの通信も含めると3種類です。
TLSはサーバーが提示する証明書をクライアントが検証してOKなら暗号通信するというものです。ブラウザーでhttpsのサイトにアクセスする場合のほとんどがこの通信です。サーバーは信用できますが、サーバーはアクセスしてきたクライアントを信用していない状態です。TLSのサーバーは、TWSNMP FCでも作ったことがあります。
クライアントも信用する暗号通信がmTLSです。mutualは相互です。今回は、このmTLSに挑戦してみました。
TLSやmTLSに対応する時に、ぶつかる壁は、証明書の作成です。先程のnoteの記事や、大元では、opensslコマンドで証明書を発行する手順が紹介されています。opensslに精通している人ならよいのですが、ちょっと面倒です。
そこで、開発しているTWLogEyeに証明書を作成するコマンドを追加しました。gencertコマンドです。
$twlogeye gencert --serverCert /tmp/s.crt --serverKey /tmp/s.key
のように実行するサーバー証明書を作成します。
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
1f:40:30:21:97:d6:ea:66:13:02:3e:44:34:da:d1:a5
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=YMIM2ProMacMini.local
Validity
Not Before: Jan 30 19:22:59 2025 GMT
Not After : Jan 30 19:22:59 2026 GMT
Subject: CN=YMIM2ProMacMini.local
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (4096 bit)
Modulus:
00:c5:5a:26:3f:b4:bf:aa:06:48:1c:24:35:4c:c0:
94:86:9f
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment, Certificate Sign
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
14:74:7F:33:45:37:8E:AE:34:1B:49:F1:BA:15:C5:28:2F:38:6A:01
X509v3 Subject Alternative Name:
DNS:YMIM2ProMacMini.local, DNS:localhost, IP Address:192.168.1.24
Signature Algorithm: sha256WithRSAEncryption
aa:f7:9a:93:66:25:a8:4e:61:0d:2b:04:e7:0b:4d:01:dd:e2:
a5:fe:65:8e:f6:5b:78:00
のような証明書を作成します。発行者と対象が同じという、いわゆるオレオレ証明書です。TLSで使うには十分な証明書です。
$twlogeye gencert --clientCert /tmp/c.crt --clientKey /tmp/c.key --cn user
のように実行すると、クライアントの証明書も作成できます。
X509v3 Extended Key Usage:
TLS Web Client Authentication
が変わりますが、これもオレオレ証明書です。
秘密鍵は、自分のところだけにして証明書のファイルを相手と交換すれば、mTLSが実現できます。証明書は、オレオレなのでCAの証明書としても使えます。厳密なことが好きな人には、それは安全ではないと言われそうですが、暗号化しないか、片方だけ信用する通信よりは「まだ、まし、ちょっとまし}です。
できた証明書を使って、サーバーを起動できました。
サーバーの証明書と鍵を指定して起動すれば、TLSモードです。
さらに、クライアントの証明書をCA証明書として指定すればmTLSモードです。
クライアント側は、サーバー証明書をCA証明書として指定してコマンドを実行すれば、TLSモードです。さらに、クライアントの証明書と鍵を指定して実行すれば、mTLSモードです。
mTLSモードで起動したサーバーに、クライアント証明書と鍵をを指定しないでアクセスすると
2025/01/31 06:44:22 watch notify err=rpc error: code = Unavailable desc = connection error: desc = "error reading server preface: remote error: tls: certificate required"
exit status 1
証明書を提示してねというエラーになりました。
これぞ、完璧な相互信頼の暗号通信です。できて、かなり嬉しいです。
パスワードを交換するような認証機能を作ることを考えていましたが、mTLSができたので十分なように思います。
昨日、これからやることに書いた課題のgRPCのヘルスチェックは、
の通り作れました。gRPCの暗号化と認証も解決したので、残りは、
SIGMAルールとGROKの検証ですが、今朝は時間切れです。
明日に続く