たごもりすメモ

コードとかその他の話とか。

TCP serverをSSL/TLS化するのに nginx の stream_ssl_module/stream_proxy_module が便利

最近 Fluentd の通信プロトコルまわりをアップデートするためにあれこれいじっている*1んだけど、これはおおむね fluent-plugin-secure-forward がサポートしていた内容を Fluentd 組込みの forward plugin でもサポートしますよ、というものになる。
んで問題なのが secure-forward は SSL/TLS での接続のみしかサポートしてなかったんだけど forward では生の TCP で通信する*2ので、本当に secure-forward と forward それぞれの実装間で互換性が保たれているのか、直接的には確認する手段がない、ということになってしまう。

TCP server の SSL/TLS

一方世の中には SSL/TLS ターミネータという機能があって、たとえばロードバランサなんかがこの機能を持っている。何をやるかというとSSL/TLSの処理だけはフロントエンドのサーバがやって、バックエンドで実際の処理を担当するサーバはSSL/TLSのことなんか知らず生のTCPに対して処理を行う、というものだ。Webサービスの提供をするときにもこの構成はよく使われるし、AWS ELBなどをはじめ各種ロードバランサで広くサポートされている。

[client] -----> (SSL/TLS) -----> [Load Balancer] -----> (TCP) -----> [server]

これは Fluentd においては次の構成にあたる。

[out_secure_forward] -----> (SSL/TLS) -----> [Load Balancer] -----> (TCP) -----> [in_forward]
TCP client の SSL/TLS

いっぽう、本番システムにはあまり存在しない構成として、SSL/TLSに対応していないクライアントを無理矢理にでも SSL/TLS のみしかサポートしないサーバと通信させるたい、という要望がある。おそらくほとんどのユースケースは開発時のものだと思う。強いて言うと tcpdump で中身がわかって便利、みたいな SSL/TLS に正面から挑戦するような利点がある。

[client] -----> (TCP) -----> [Load Balancer] -----> (SSL/TLS) -----> [server]

Fluentd においてはさっきと真逆の構成。

[out_forward] -----> (TCP) -----> [Load Balancer] -----> (SSL/TLS) -----> [in_secure_forward]

プラグイン実装の対称性が保たれているかを確認するためにはこっちのテストも必要だったのです。

nginx の stream_ssl_module と stream_proxy_module

さてこのような構成を手元で作って動作確認したいと思ったときにどうするか。本番システムなら AWS ELB とか使えばいいけどちょっと動作を試したいとかオレオレ証明書とかであれこれ実験したいとかいうときにはいかにも面倒くさい。
おっさんとしては昔ながらの安定のツール stone とかも思い付くけど、うーん、さすがにちょっと今更感がある*3し、英語が大前提のOSSプロジェクトではオススメしづらい。

どうしようかなと思っていたら、最近の nginx はTCPのproxyもできる stream という機能が足されてたのを思い出した。自分でちゃんと使ったことがなかったんだけど、ドキュメントを見ているといかにも SSL/TLS の処理もできそうに書かれてていかにも使えそうだったので、試してみたところ、見事に(簡単に!)使えた。期待通りに動くソフトウェアというのはすばらしい。えらい。

なお stream およびその他今回使用したモジュールは通常の nginx では有効になっていない。自分は --with-stream --with-stream_ssl_module を有効にしてソースコードから configure && make && make install した。バージョンは最新安定板の 1.10.1 を使っている。

stream_ssl_module

https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html

これは SSL/TLS なクライアントからの通信において TLS termination を nginx で行い、TCPの通信としてバックエンドに流すために使う。つまり、こっちの構成用。

[out_secure_forward] -----> (SSL/TLS) -----> [Load Balancer] -----> (TCP) -----> [in_forward]

もちろん手元で適当なオレオレ証明書を事前に用意しておく。その上で以下のように設定を書くだけ。簡単!

worker_processes auto;
error_log /Users/tagomoris/nginx.err;
events {
  worker_connections 64;
}
stream {
  upstream backend {
    server 127.0.0.1:24224;
  }
  server {
    listen 24284 ssl;
    proxy_pass backend;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
    ssl_certificate     /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    ssl_password_file   /path/to/pass.txt;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;
  }
}

port 24284 を SSL 有効にして listen し、その通信をバックエンドの Fluentd port 24224 に流す。こっちはTCP
手元テスト用なので ssl 関連の設定は適当、本番環境にこれをコピペしてはいけない……のはともかく、これで動く。素晴らしい。

stream_proxy_module

https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl

こちらは TCP で受けた通信を SSL/TLS が有効なサーバに向けてプロキシしてやるために使う。こっちの構成用。

[out_forward] -----> (TCP) -----> [Load Balancer] -----> (SSL/TLS) -----> [in_secure_forward]

こっちは証明書まわりの設定がいらない*4から、もっと簡単。こんな。

worker_processes auto;
error_log /Users/tagomoris/nginx.err;

events {
  worker_connections 64;
}
stream {
  upstream backend {
    server 127.0.0.1:24284;
  }
  server {
    listen 24224;
    proxy_pass backend;
    proxy_ssl on;
  }
}

TCP port 24224 で受けた通信をバックエンドの port 24284 に流す、その際に SSL を有効にする、と指定してやるだけ。超簡単。
このとき証明書の検証まわりの制御について設定が必要なら、適宜 proxy_ssl_verify などを正しく指定してやればいい。各自がんばれ。

まとめ

nginx の stream がすばらしくて、なんといっても手元で使いやすいので開発時にも特に便利にお使いいただけます、というものになってた。
今後の選択肢のひとつとして覚えておきたい。

*1:なお過去の通信プロトコルと互換性があるので心配性のみなさんも安心の内容でございます

*2:SSL/TLSのサポートも予定にあるんだけど今のところはまだコードが無い

*3:と思ってたけどリポジトリを見るとまだアップデートされてるんだなあ、すごい https://osdn.jp/cvs/view/stone/stone/stone.c?view=log

*4:in_secure_forward側でやってある前提だ

松江市でOSSの話をした & Fluentd meetup をやった

なんか最近プレゼンテーションやった話しかエントリに書いていない……。。。

それはともかく、しまねOSS協議会というところから周年記念講演で話さないかというお誘いがありまして、お受けしたので島根県松江市で話してきた。せっかくRuby City Matsueに行くことだしついでにイベントやってこようということで Fluentd meetup in Matsue もやることになり、そんなわけでふたつ発表してきた。

第106回オープンソースサロン・総会記念講演

第106回オープンソースサロン・総会記念講演 | しまねOSS協議会 OS4

しまねOSS協議会ということで、オープンソースソフトウェアの話。

というか、トレジャーデータという会社がOSSを使い倒してビジネスをやってるのは何故なのか、それは内外の開発者にとってはどういう意味があってどう見えているのか、みたいなことを中心に話していた。具体例についてはどっちかというとRubyよりはJava(というかデータ処理ミドルウェア界隈)の話に寄ったけど、一般化できる内容ではあったと思う。

自社サービスの話、USとJPをまたいだ話(採用とか)、業務としてOSSのパッチを書く話など、あれやこれや話してた。質問もいろいろ頂いて、話しに行けてよかった。お呼びいただきありがとうございました。

Fluentd meetup in Matsue

Fluentd meetup in Matsue - dots. [ドッツ]

せっかくなので開催してきた。東京以外でのFluentd meetupは福岡、San Franciscoに続いてのなんと3ヶ所目。とりあえず自分からはFluentdそのものの導入やら最近のユースケースやらアップデートやらをざーっと話すという感じにしてみた。

Fluentdを使ったことがない人もいたので、これはこれでとりあず必要な内容というか。こういう総論的なFluentdの紹介スライドはどっちにしろ定期的にアップデートする必要があって、ちょうどいい機会でもあった。
他の発表も募集したところちゃんと話してくれる人が出てきてくれたので本当によかった。しかも素晴らしい内容だった。

あとFluentdの新ロゴが載ってるノベルティが配られた初のFluentd meetupでもありました。よかったよかった。

Stream Processing Casual Talks #1 に行ってきた&しゃべってきた

なんか、やろうぜー、という話になってそのような勉強会が行われたので、参加してた。

connpass.com

会場&飲食の提供はYahoo! Japanさん。ありがとうございました。面白かった。

しゃべってきた

Norikraそのものの話はさすがに今更感あったので、Norikraの大事なところと、あとPerfect Norikra (仮)について話してきた。

まあ、まだ1byteも存在しないソフトウェアなんだけどな! 存在しないソフトウェアについて話せるようになったの、ちょっと実績解除感があるのではないだろうか。だめか。

Norikraを分散処理対応にするにはクエリ処理エンジンおよびデータ転送層を丸ごと書き直すしかないなー、しかもそこに色々なアイデアが必要だなとは思っていて、そのうちのひとつであるところの動的スケールアウトには最低限何が必要なのか、みたいな話をしてた。
この他にもまだあれこれ必要なんだけど、この先はどんどん話の前提が増えていくから、さすがに勉強会の単発の発表でやるのはキツそう。というか、書かないとなあ……。

行ってきた

Hadoop Summit での空気感*1とか、Y!Jでの実際のアプリケーションの話とか、その他各ミドルウェアの話とか聞いてた。たのしかったー。

特にPipeline DBの話がじつに面白かった。Norikraと完全に逆の方向を向いてて、RDBMSの外側にハックをかぶせていかにストリーム処理をストリーム処理に見せないか、という方向に突っ走ってた。なるほどなあ、それならJDBC使えるわー。でも自分はそっちの方向には絶対行かないなあ。

そのあとも飲みながらあれこれ話したりとか、じつに面白い勉強会でした。またやりたいですね。

*1:やっぱり各ベンダーの人の話はその意向が出るよなあ、という強烈な印象だけがある……

LinuxCon Japan 2016に行ってきた&しゃべってきた

LinuxCon Japan、今回は ContainerCon Japanとの併催。サブトラックみたいなのもいくつかあった。
とにかく普段に自分が行くカンファレンスとぜんぜん空気が違ってて、東京都内で行われてるカンファレンスなのに会場の感じとか食事・飲み物の提供とか冷房のキツさとか、あれこれがだいぶ海外のカンファレンスっぽい。参加費が高いからできることなんだろうけど。そして海外からと思しき参加者も非常に多かった。すごいな。
日本国内からも大手メーカー系のスポンサードと参加者が非常に多かった。普段見ないあたりの世界だなあ。

しゃべってきた

プロポーザルを出してみたら通ったので初めての参加&発表だった。行ったことないので全体的にどういう空気なのかも分からないまま、初日のキーノート後の通常の発表枠の中で最初に時間だった。お、おう……。

今回はロギングに関してのアーキテクチャを議論するよ、ということで、特にコンテナを使うのが当たりまえという世界でロギングってどうやるんだっけ、どうすればちゃんとスケールさせられるんだっけ、という話をあれこれやった。

実例で特にFluentdを取り上げているけど、話の内容自体は一般論として何でもやれるはず。アプリケーション側をできるだけ単純にしつつ、ログのトラフィックの増大にどう対応するか、ログの種類の増大にどう対応するか、ストレージの性能特性によってどのように構成を考える必要があるか、などなど。
ちょっと英語でのスピーチがうまくやれなかったなと思ってたけど、聴衆から参考になったって感想言いにきてくれた人がいたので良かった。ありがたいことです。

そのほか

最近 Treasure Data が Linux Foundation のプロジェクトのひとつであるCNCFに参加したということもあって、LinuxConの分科会のひとつとしてCNCFのトラックもあって、そっちでは @repeatedly がFluentdの話をしていた。これはこれで、普段リーチしてない層に届いたのかなあ、という感じ。
あとはふらふらと各セッションを巡ってたんだけど、面白いのもあればなんだこりゃ、というのもあった。総じて、うーん、もうちょっとこう……まあカンファレンスごとのノリもあるしね、難しいよね、みたいな感じはする。

そして期間中ひたすら強烈な冷房を浴びつづけたせいか、しまいには盛大に体調を崩してしまった。きびしい。

YAPC::Asia Hachiojiに行ってきた&しゃべってきた

この週末に開催されていた YAPC::Asia Hachioji に参加してきた。2日目は体調崩してダウンしてたので1日目だけだったのが残念だけど、楽しかったー。
yapcasia8oji-2016mid.hachiojipm.org

しゃべってきた

普段あんまりプログラミングテクニックそのものについてはプレゼンをやる機会がないんだけど、Fluentd v0.14で使わざるをえなかったあれこれとか一度しゃべっとくかということで出してたので、やった。主に黒魔術について。なんだろう、使っても許される黒魔術の用途と実践、みたいな感じ?

30分という時間*1で何故そういうハックが必要なのかを説明して実装を説明して、ということになって、また大分駆け足になってしまった。が、後で聞いた感想によると前提の説明があったから良かったという話だったので、まあよかったんじゃないかなー。たぶん。
最近はアーキテクチャの話とかもっとエモめの話とかをすることが多かったので、コードそのものの話はやってて楽しかった。

いってきた

あんまり多くのセッションを聞いてないけど、みんな自分のやったことについて楽しそうに話してるなー、という感じで、参加してても面白かった。
主催のかたがた、たいへんお疲れさまでした!

*1:もっと長い時間で申請しとけばよかったって超思った

Fluentd v0.14.0 をリリースした & Fluentd meetup 2016 Summer をやってしゃべってきた

最近めっきり対外的なアウトプットが減っていたのは、ぜんぶこいつのコードを書きまくってたからです。すごい書いた。

Fluentd v0.14.0 has been released | Fluentd

ということで出ました、Fluentd v0.14.0。だいぶいろいろ良くなってるはずだけど、そのあたりはこれからv0.14対応プラグインが増えてきたりすると分かってくるかなと思う。ユーザにとっても嬉しい変更が山盛りです。
で、まずそのことをアピールしなければならんということで、Fluentd meetupではがっつりとしゃべってきた。

Fluentd meetup 2016 Summer - dots. [ドッツ]


元々45分の予定だったのに90分弱くらいしゃべってしまったらしい。すまんかった。しかし省略できそうな場所が無かった。

これからドキュメントとかいっぱい書くんだけど、他にまだまだ機能を v0.14.x のバージョンで載せていかないとだし、あれこれやるぞー、という気分。ユーザ&プラグイン開発者のみなさんからもいっぱいフィードバックいただけると嬉しいですね!