GoのgRPCで独自の暗号化を行う

gRPCでは基本的にSSL/TLSを用いて通信の暗号化を行うのだが、何かしらの共通鍵暗号など独自の方式でやりたい!という場合があるかもしれない。そういう場合でもうまく拡張すれば実現できる。今回はAES+CTRを用いた実装を試みたので、その紹介をする。サンプルコードはtakaishi/hello2018/tree/master/grpc_with_record_cryptにある。

どうやるかというと、net.ConnのWrite()でデータを送る際に暗号化し、Read()で受け取る際に復号する。AES+CTRを用いた暗号化はGoだとライブラリがあるのでそれを使う。Go言語と暗号技術(AESからTLS)が参考になる。

Write/Read時の暗号化/復号をどうやるかだが、TransportCredentialsのClientHandshakeとServerHandshakeがポイント。この2つの関数はnet.Conn型であるrawConnを受け取り、net.Conn型の変数を返している。つまり、ここでrawConnをラップしたnet.Conn型を満たす構造体を用意し、その構造体のWrite/Readであれこれすればよい。これはATLSが使っている手法で、実装するにあたり大変参考になった。

net.Connをラップしたconnの例。これは暗号化・複合の処理は行わず、単純にラップするだけ。

暗号化・復号する処理を実装するとこんな感じになる。暗号化されたデータは元データとサイズが変わるため、Prefixとして暗号化されたデータのサイズを先に送り、そのサイズ分だけ読んだ後に復号する、というやりかたにした。

動かしてみる。暗号化しない場合、パケットキャプチャすると送受信したデータが読める(Hello!!!やThanks!!!など)ことがわかる。秘匿情報を送受信した場合、読まれる可能性があるだろう。

暗号化した場合はキャプチャしても以下のようになり、読むことが出来ない。共通鍵暗号なので、鍵がなければ解読できず、かなり安全になる。

ちょこちょこ書いて動くようになるまで1ヶ月ほどかかった。Read/Writeのラップがうまくいっていなかったのだけど、何もしない状態でテストを書くことで結果として暗号化・復号する場合でも同じ挙動になることが担保できたのでテストは大事だなと思う。

STNSと連携して公開鍵認証し、gRPCでサーバーに定義した処理を実行させるツールalpette

今年の4月頃にgRPCの独自認証周りを調べて、勉強がてらそれを使ってツールを作っていた。ものとしては、サーバー側でタスクを定義しておくとgRPC経由で実行させられるというもの。リポジトリは takaishi/alpette

挙動としては、まずサーバー側で以下のようにタスクを定義する。

そして、クライアント側からタスクを指定するとgRPCでサーバーと通信、サーバーはタスクを実行、実行結果を返すというもの。

サーバーで何かするときにSSHすることが多いと思う。しかし、SSHだと実行者が持つ権限が結構大きい。適切に権限を設定すればよいのだけど、別のアプローチとして定義した処理しか実行できないようにするのはどうかと思い試しに実装した。また、gRPCの認証部分でSTNSと連携した公開鍵認証を実装している。標準で使えるSSL/TLSやGoogleを使ってもいいのだけど、STNSと連携することでユーザー管理をSTNSにまかせたり、将来的には監査などに活用できるのでは?と思いやってみた。

gRPCで独自の認証機構を利用する(SSH公開鍵認証編) という記事に書いているように、WithTransportCredentialを使うことで独自に認証機構を実装できる。基本的にはSSHと同じなのだが、サーバーはSTNSから公開鍵を取得するのでフローとしては以下の図のようになるはず(間違っている箇所があったら教えてくれるとうれしいです)。

なお、これだけだと認証通過後の通信は暗号化されない。そのため、パケットキャプチャすると処理結果が見えてしまう。例えばSSHのように共通鍵を用いて暗号化するという処理が必要である。

テンプレートからテキストファイルをパッと作れるCLIツール、patt

2017年に思いついてガッと書いたもののその後忘れていて、今朝見つけて「ええやん!」と思ったのでリファクタリングしたりリリースまわり整備したりして使えるようにした。リポジトリは https://github.com/takaishi/patt

これは何かというと、普段僕は日報や1on1のメモやその他いろいろなテキストファイルを扱っているのだけど、テンプレートをコピーして日付やらを変えて…というのが面倒と思うことがある。そこで、テンプレートを一括管理して、日付などからファイルを生成して任意の場所に置いてくれるツールを用意したというわけ。

テンプレートはテキストファイルで、Hugoでおなじみのfront-matterを使う方式。テンプレート名と配置先を情報として持たせる。

テンプレートを一覧表示するとこんなかんじになる。

テンプレート名を指定してnewコマンドを実行すると、ファイルができて便利。

ビルドとかリリースまわりの設定をいろいろやったり、Homebrewでインストールできるようにしたりというのをやっていた。ツール名、今朝見たときは「パッと作れる〜」みたいなギャグかなと思ったけど、いろいろコードとかみてるとpatternからとってた気がする。サブコマンドがちょいわかりにくいのでしばらくブラッシュアップしていこうと思う。

Apple Watch Series 4 40mmを数日使った感想

日曜に買って、数日使っている。基本的にiPhoneを持ち歩いているのが前提で書いていく。

まず、画面を見ると次の予定をパッと確認できるのがいいなと思う。こういうとき、PCやスマホ・手帳を開かなくてよくて、わずらわしさが減ったと感じる。自宅だとスマートスピーカーに教えてもらうという手もあるけど。ちょっとした通知をウォッチから確認できるのも便利だった。小さい画面で確認してもなあと思っていたけど、そこまで読みにくくもない(Series4だからかもしれない)。

活動量計としてももちろん使えるのだけど、記録するだけじゃなくてちょっと動けよ!とせかしてくるのは結構いい。思った以上に動いてるな、というのも可視化できる。寝るときにもつけて、睡眠トラッキングアプリも試し中。目が覚めたタイミングが記録に残っているのである程度睡眠の質はわかりそう。

最近はSpotifyばかり使っていて、ウォッチからどのくらい操作できるかわからなかったのだけど再生・一時停止や曲送りなどはできるようなので、そこは便利だった。iTunes/Apple Musicだともうちょっと複雑な操作もできるのかな。試してみてもいいかもしれない。

時計のテーマがいろいろあるけど、そこはあまり関心がなかったようで、今のところ情報の多いテーマで固定している。

ウォッチをつけてるとMacのロックが自動で解除されるのは便利。他の認証系アプリ・機能はまだ試していない。

ウォッチ用アプリがあまりないように見えるのが残念。GoogleカレンダーやGmailを見られると便利なんだけどな。

サイズとしてもG-Shockと同じくらいかコンパクトなくらいだし、時刻が見えるだけじゃなくていろいろいできるデバイスなのでつけてて損はないなという感じ。いかに長くつけるか、というのは考えず、家でリラックスしている時とかは外していいし、気分によってはつけない・別の時計にしてもいいじゃんという心構えでいくつもりでいる。心拍数など記録できるということもあって、ついつい完全性を意識してしまうので。

 

 

Kubernetes Meetup #13 でKnative Servingの紹介をした

Kubernetes Meetup Tokyo #13 で、Knative Serving 入門という話をしてきた。台風で一度延期になったが、もとは9月頭のイベントでKnativeが発表されて1ヶ月くらいのタイミングだったので、考え方やアーキテクチャについての紹介をした。いくつか質問もいただき、ありがたい限り。今回はたまたま?Kubernetesの拡張に関係するセッションが多かったが、自分はまだまだそこまでいけてないのでやっていかねばという気持ちに。