読者です 読者をやめる 読者になる 読者になる

水深1024m

技術的なメモとか日記的なもの

git-secrets の Homebrew Formula 作った

最近流行りの AWS の認証情報とかを github で大公開する事故を防ぐためか AWS が作った git-secrets という git plugin があります。 インストール手順はレポジトリを clone して make install するような感じだったので、初めて Homebrew の Formula 書いて Homebrew に取り込んでもらいました。 (git-secrets 自体シンプルな git plugin なので全く大した内容ではない)
git-secrets 1.0.0 (new formula) by kanny · Pull Request #47322 · Homebrew/homebrew
というわけで Mac && Homebrew 使ってる人は

$ brew update
$ brew install git-secrets

すればインストールできます。

使い方は別の方が Qiita にまとめてくださっていますね。 クラウド破産しないように git-secrets を使う - Qiita

自分が何か作るときは認証情報はだいたい1ファイルに認証情報だけまとめて gitignore に書くようにしてるのですが、git-secrets 使うとそれでも事故るようなケースを防げてとても良いですね。 初心者向けハンズオンとかでも、

  • git init
  • git secrets —install
  • 認証情報をまとめたファイルを作る
  • .gitignore を作る

くらいまで、そんなに時間かからないと思うし紹介できると良いのかなー。

Pull Req 取り込んでもらう間に眺めてて気づいたんですが、Homebrew には毎日すさまじい量の Pull Req が来ています。 Formula 書くのも楽なので、取り込んでもらえるとみんな幸せになれそうなものは書いてみると良いかも。もちろん雑に書くのではなくちゃんとドキュメント読んで brew audit 通して、ですよ。

これを数人のメンテナで (日々寄せられる Pull Req のレビューとかも全て) 回していて、すごいなあ。

MSPJ マイグレーションコンペティション2015fall に参加してきた

MSPJマイグレーションコンペティション2015fall というイベントに出場してきました。 かなり古いシステムがオンプレっぽい環境にあるのでクラウドにいい感じに移す、というコンペティションです。 参加して敗北したのですが、初回ですし次回もぜひ開催いただければと思っているので、どういう感じだったかまとめたいと思います。

ルールやチームについて

やることは上述しましたが “古いシステムをいい感じにマイグレーションする” です。 イベントページから引用しておきます。

- お題: いま動いているふるーいシステムをバージョンアップしてね
 - できれば利用者に影響なしでやりたい
 - できれば冗長化したい
 - できればさくさく動くようになると嬉しい
 - できればプロビジョニングコードが欲しい
 - できればサーバに関する資料があると嬉しい
- 実施した内容と結果については報告してくださいね
- 背景という名の発注者の弁
 - もうすぐサポート切れるって言うし、セキュリティが心配だし、でもそんなにきちんと管理する手間もとれないし、わかるひともいないし、今のうちになんとかしておきたいんだよねー
 - あんまり何回もいじりたくないから、できるだけ長く使えるようにしてほしいなぁ

当日配布されたお題もほぼこれと同様の内容でした。 チームは当日編成されるので、あらかじめチーム組んでおいで出るみたいなことはできません。

参加者は30歳以下という縛りがあったこともあり、20代のエンジニアが幅広くという感じでした。僕のチームも社会人3年目、3年目、2年目というチームでワイワイしてました。
Slack に運営との連絡用 private chat ができ、僕らは GitHub の private repo に issue などを立ててメモを書いたりするという感じで進めました。 制限時間は10:30 過ぎから 17:00 までの6時間ちょっと。

初期環境

初期環境とさくらのクラウドのアカウント (後述) が渡されて競技開始です。お題はみんな大好き wordpress でした。
使われていたのは CentOS 5.x で、 PHP 5.1 と MySQL 5.0 の環境。PHP が古すぎるので wordpress アップデートもできないし、MySQL も特に設定はされておらず MyISAM のテーブルがあるだけという状況。
また、チームごとに teamN.example.com という単位で DNS のゾーンが分割されていて (ドメインは例です)、その NS を担う bind が立っていました。 始まって30分くらいで大体の状況は把握して新環境の設計をざっくり作り始めました。

設計

使えるサーバ台数などに特に制限もないクラウド環境だったこともあり、いわゆる普通の3層構造を当初作ろうかと話していました。
が、依頼者の背景に “趣味と実益を兼ねて作っているブログ” という話があり、お題にあるようにあまり弄りたくない、きちんと管理する手間も取れない、ということでサーバ台数とコストを抑える (ただし “できれば” の部分はできるだけ満たす) という方針で最終的には作っていました。

移行

初期環境と同時に、さくらのクラウドのアカウントを渡され (好きに使って良いとのことだった) これを使って新環境を作っていきます。 さくらのクラウドをまともに使うのははじめてだったので、とりあえずドキュメントを読みながら石狩リージョンにルータ+スイッチを作り、新環境の App サーバと DB サーバ (設計方針変更により最終的には1台に統合された) を作ります。 サポート期間が長いものを、というところと、チーム的に手に馴染んでいそうということでディストリビューションとしては CentOS7 を選びましたが、個人的には systemd や firewalld がっつり触っているわけではなかったこともあり少しもたつきました。

ディストリビューションが CentOS7 になったので、ApacheMySQL をパッケージからインストールしていけば現代で使われているバージョンになります。 CentOS7 からは MariaDB が標準採用されたという話は知っていたけどチームメイトがインストールしてくれたのは MySQL で、おや?と思ったのですが、さくらのクラウドの public image では rpmforge とか remi とか MySQL community repo とかが最初からインストールされているのですね。へーと思いました。

馴染みの道具は大体揃ったので、旧環境から新環境へのレプリを設定して (wordpress のデータベースだけ)、新環境の App を作っていきます。レプリはチームメイトがいい感じに設定してくれたので、移行先のスレーブを先にガッと InnoDB に ALTER しつつ buffer pool など基本的な設定を入れました。wordpress 本体はそのままコピーして終了。
旧環境でも新環境でも25秒くらいかかるクエリがあってこれはなんだろと思ったら、wordpress のテンプレートタグで SQL_CALC_FOUND_ROWS が使われてるみたいな話があるのですね。移行が第一目標だったので勝手にテンプレート編集するわけにもいかんよな、と思いつつクエリキャッシュが効きそうなケースだったので有効にしたら収まりました。

Web サーバはまあ無難だよねというところで Apache + mod_php になりました。APC も入れたけど先述のクエリのほうが負荷としてはとても高かったので効果は目立たなかったと思います。

新環境の準備が大体できたので、動作確認をしてとりあえず旧環境から新環境に移行していきます。さくらのクラウドでは GSLB が使えるので、そこに切り替えることにしました。

実際に気づいたのは移行よりかなり前ですが、クラウド環境への移行だし DNS サーバは立てずにさくらのクラウドに用意されてる DNS サービスに移せば自前より良いよね、という話を当初していて、いざゾーンを作ろうとしたらゾーンが登録できない旨のエラーが返ってくるというところで少しハマりました。

ドキュメント を読むと、”上位ドメインが当サービスで提供するDNSサーバにNSが向いて” いる、あるいは “上位ドメイン、および下位ドメインが当サービスで既に登録されて” いるものは使えないという記載がありました。

ハッと思い運営の方に質問したところ、予想通り移譲されているドメインの上位ドメインがそもそもさくらのクラウド DNS で既に運用されているとの回答を得た + “具体的に作業内容を伝えれば” その通りに作業をしてくださるとのことだったので、自分のチームに移譲されているドメインの NS 設定を消して自チームのサービス用ドメインへの CNAME を直接設定してもらいました。(この方法をとったのは我々だけだったらしい)

移行は無事一発で済んだので、旧環境からのレプリ設定などを消したり後始末。これで旧環境には用がなくなりました。ここまでで残り1時間30分くらいだった気がする。

冗長化

チームメイトが既に東京リージョンにもサーバを作っていてくれていたので、ネットワーク設定などをざっと入れつつアプリをコピーし、データベースは石狩リージョンに向けました。スレーブは東京リージョンのサーバにもありましたが、このフェイルオーバーまでは作りきれずドキュメントだけ書いておこうという方針になりました。
さくらのクラウドのスイッチはリージョン間接続ができるので、東京リージョンと石狩リージョンの間で L2 ネットワークを結べて便利でした。 GSLB に東京リージョンのサーバ IP を書いたので、これで「石狩が落ちると手動で切り替える必要があるけど東京が落ちても耐えられる」構成となりました。 かなり不完全ですが。。。

プロビジョニングスクリプト

当初は普段使っているItamae などでできる限りスクリプトを作るか、という話をしていたのですが、時間が足りずここは諦めることにしました。 ISUCON などで「プロビジョニングスクリプトから作っていると大抵時間がなくなって崩壊する」というのはわかっていたので、最初から手を付けず、あとから諦める判断だけしたのは良かったと思います。

終了、そして敗北

そうこうしているうちに時間は16:30と終了寸前。チームメイトがかなりきっちりしたサーバ資料を書いていてくれていたのでそちらは完全に任せきりで、こちらはざっくりと技術的な改善点や移行時の手順をメモとして残しつつ、忘れられていた運営チェック用アカウントの作成と疎通確認、再起動耐性の簡単なチェック (実際再起動している時間はなかったのですが) などをしていました。再起動耐性については特にどこにも書いてなかった項目ではありますが ISUCON のトラウマみたいなもので…

17時までに Slack 経由で資料を提出して終了となりました。 懇親会はピザや寿司やお酒などをいただきつつ、チームの構成などについて話して盛り上がっていました。

懇親会も半ばとなったところで結果発表。残念ながら我々のチームは入賞を逃しました。

講評

講評では、”MUST 要件をちゃんと考えて適切な作業やコミュニケーションをしよう” というもっともな話がまずあり、そもそも移行に失敗した (旧環境から NS を移すのを忘れていた?) チームがかなり多かったこと、移行成功したのは数チームであったものの、我々のチームは1つだけ書き込みのテストをしたテストデータが残っていたことが入賞を逃した理由として説明されました。 移行プロジェクトということで、確かに移行したアプリに勝手にテストデータ書き込まれてそれが残ってたら怒られるのはもっともだなーという感想を得ました。アプリを書き換えないという選択はしたのにテストデータはスルーしたというのも甘かったですね。。。

ただ、他チームの話を聞いている限り、ゼロダウンタイムでの移行 + 不完全とはいえ冗長化 + パフォーマンスチューニング + ドキュメントの作成、を達成したのは我々のチームだけのようでしたので、正直かなり悔しかったです。

これがなかったらおそらく優勝していたであろう内容だったので、トップスコア fail した ISUCON5 と同様、最近詰めが甘いことが多すぎるということへの反省と力不足を痛感しました。

最後に

ISUCON 同様、時間が限られた中、チームで何らかの作業をすることは、技術スキルや優先度の判断など個人の能力に加えてチームワーク(というかコミュニケーション)もかなり重要になるので、個人的にはかなり良いトレーニングになるなと感じています。チームがランダムということで若干の緊張感はありましたが、チームメイトもとても良い方々で、バランスの悪いことなどに対してお互い指摘が入れられるような形で作業が進められたのはとても良かったです。

また、さくらのクラウドをほぼ初めて使わせていただいたのですが、普段 AWS や GCE などを触っているとあまり考えることのないレイヤを触っていく必要があり、「ネットワークを作っている」感が強いなーと感じました。このあたりは、求める抽象化の度合いやコスト感 (金銭的なものだけではなく) によって他社クラウドと住み分けがされていくのだと思います。 個人的には、NIC の付け外しがオンラインでできたり、マネージドな DHCP サーバがあったりすると嬉しかったです。

長々と書いてしまいましたが、自分と同じくらいの世代のエンジニアと交流でき、かつ個人的にかなり反省するところもあり、色々と学びがありました。 運営いただいた日本MSP協会のみなさま、ありがとうございました。次回開催も楽しみにしております。

ISUCON5 本選でトップスコア fail した

ISUCON5 に .dat として @y_matsuwitter@TakatoshiMaeda で参加してきました。本選6位だった昨年に引き続き、今年で2年目です。 幸運にも予選を(2日目)1位で通過することができてたのですが、主にネットワークやミドルウェア周りを担当していた自分としては結構なニート状態だったので、本選ではもうちっとは貢献したいなーという気持ちがありました。

Go - ISUCON5予選でスコア34000を出す方法 - Qiita

で、本選ですが、アプリケーションレイヤでやったことは @y_matsuwitter の記事にほぼ全て書いてあります。 ISUCON5本選にてスコアトップの18万点でfailしました - Qiita

サーバ構成に関することも書いてあるので僕が記事書く必要もなさそうですが、せっかくなのでやったことをちょこまかと書きます。

基本的なセットアップ

@TakatoshiMaeda が完璧に仕上げたセットアップスクリプトで一撃でした。Ubuntu 15.04 + systemd だった予選と違い Ubuntu 14.04 + upstart + supervisord だったわけですが、そのへんの差異も特に気にせずドーンという感じです。 @TakatoshiMaeda++

開幕 tcpdump

改善に限られる時間が限られており、特に今回の問題では外部 API という要素が入ったこともあって、可能な限り早い段階でそれらを含めた全体像を把握する必要がありました。 アプリケーションレイヤの改善を僕以外の二人に任せていたので、アプリケーションの変更をせずある程度の分析を行っておきたいと思い、ベンチマークのパケットダンプを取っていました。 把握できたのは大体以下のようなことです。

  • ベンチマーカが送ってくるヘッダ、リクエストパターン
    • Accept-Encoding: gzip とか (最終的には忘れてたけど。。。)
  • 外部 API が返してくるヘッダ
    • リクエスト/レスポンスの仕様
    • tenki API が Last-Modified を返していたのはこの時に分かってた
  • 外部 API に接続するときに DNS リクエストをしていない
    • /etc/hosts に書いてあった
    • ハードコードしても問題ない

まあ、初手の分析としては十分なのかなーと思いました。 で、API の中にわざわざ HTTPS のエンドポイントが含まれてるのを見かけたので、おもむろに nghttp2 とリンクした curl をビルドして接続したところ HTTP/2 接続に成功しました。ベンチマーカーや外部 API に仕込まれていた要素については開始45分くらいで大体把握できていたと思います。

js の改変

一通りのチェックが終わり、大体の方針を決めて @y_matsuwitter が作業に入り、僕と @TakatoshiMaeda は airisu.js から行う XHR 先を分散できないかという検証をやっていました。結果としてそもそも js の改変そのものがどのようなレベルでも許されていなさそうなことが分かったのですが、CORS 周りの設定にハマり少し時間を無駄にしてしまったのが後悔でした。そもそも静的ファイルの変更がどのくらい許されるか自体はもっと小さな変更で確認できたはずで、検証すべきことを切り分けず最小限のことだけをやらなかったのは大きなミスでした。

ミドルウェア類の設定

正直ここについては、ざっと絵を描いた段階でチーム3人とも意見が一致していたこともあり、"あとは書くだけ"状態だったので特に考えることもハマることもなかったです。nginx, Redis, kernel 周りの設定など必要のあることをやっただけ。 @y_matsuwitter の Redis 実装をマージして1台で実行して13万点を超えたので、そこから複数台構成になるように修正。 先頭に置いた nginx (静的ファイル配信 + リバースプロキシ) で CPU affinity を固定してあげたりするとこのマシンは CPU を使い切れる状態に達しました。

終了まで

ちょうどこのタイミングで行われたベンチマーカーの修正により "ちゃんと fail するようになった" バグが最後まで取りきれずに敗北することになります。 正直この修正が発表された時はあまり真剣に考えてなかったのが痛かったです。会場内で2つだけ用意された会議室 (先着順で使える) を扉を閉めて使っていたこともあったのかもしれないけれど、アナウンスはちゃんと聞いて自分たちへの影響を確かめようというのは反省でした…

ミドルウェア側での大きな構成変更は3台構成にしてからはほぼなく、先述のバグの他にも fail がいくつかあったため他の2人にその修正をひとまず任せ、再起動耐性のチェックを行いました。バグが最後まで取りきれなかったため、再起動テストをそもそも行うことができなかったのですが、結果として再起動後もきちんと動いていたようなのでまあここはよかったのかな。。。 その後はバグ取りのサポートなどをしていましたが、結局取りきれず提出。

他にやりたかったこと

大体のことは @y_matsuwitter の記事に書いてあるのでそちらを。 他には ken API のデータを見ていて、ああこれはみんな大好きKEN_ALL.csvじゃないか、ということでこれを作りなおしてそもそも API リクエストをやめる、という案はありましたが、それ以前の問題が多すぎたので却下。

感想

Cache-Control に泣いた去年と比べ、初手でそういった目に見えないポイントを洗い出すことができていたのは進歩だったかなーと思います。スコアがどうだろうと fail というのは変わらず、”僕と @TakatoshiMaeda がこまい改善を積み上げておいて @y_matsuwitter がかめはめ波を撃つ” というのが毎回のスタイルではあるのですが、もっとやれることはあったなーと思うし実力不足を痛感しました。 あと1つのfailがなければスコア的には優勝だった、というのは事実そうなのですが、このfailを落ち着いて潰せるかどうかというところに大きな差があったわけで、そういう意味でも「次やったらきっと勝てる」というレベルの話でもないよなーという実感があります。悔しい。

とはいえチームとしての動き方も毎回良くなっていることは確かなので、来年は足回りの力をがつっと上げて優勝しに行きたいと思っています。

今回は、予選本選通して特にベンチマークがとても快適だったのが印象的でした。 本選の Microservices 問題も、自分としてはリアリティのある問題だったこともあり楽しかったです。 予選、本選、懇親会 (ハロウィンで渋谷の治安が崩壊してましたが) どれをとっても最高でした。関係者のみなさまありがとうございました!来年もぜひよろしくおねがいします。

AWS re:Invent 2015 これが見たいリストと tips とか

来週から AWS re:Invent 2015 ですね。 今年は幸運にも 無料で行ける ことになったし、日本からの参加者も多いようなので 気になってるセッションなどについて書いておきます。

選び方

セッションは カテゴリ+レベル という表記がされていて、自分の興味分野やレベルに合わせて選びやすくなっています。 まあ普段 AWS を使ってる人であれば Level 4 (Expert) を中心に3 (Advanced) のもので興味のあるやつを拾っていくと良いんじゃないかなーと思います。

Deep Dive 系セッションについて

○○ Deep Dive というタイトルの、AWS の SA や PM が担当しているセッションが多く用意されています。(だいたい Level 4)
だいたいドキュメントに書いてあることの話かと思いきや、書かれていない内部実装の話や初公開される数値 (ベンチマークなど) 、さらにはしれっと新機能がアナウンスされることがあります。VPC ClassicLink とかそうでしたね。
ただ、資料がよくできていて、知りたいことは大体書いてあったりするので、これらのセッションに行きすぎてもあんまり意味ないかなーと最近は思っています。 新サービスの Deep Dive もいきなり発表される (そしてすぐ埋まる) ので、気になる人は早めに行きましょう。

ユーザセッションについて

AWS の人ではなく、AWS を使っている人たちのセッションです。Netflix や Riot Games (LoL 作ってる会社) など日本でも知られているような規模の会社の話が聞けます。
去年行った時は Chaos Engineering でおなじみ Netflix の障害挿入に関する話とか、Adroll が100万 req/s を 5ms 以内で返す話 とか見てて面白かったです。
ただ、スポンサーセッションもあって、自社製品の紹介がメインみたいなセッションもあるので、abstract をよく読んで決めたほうが良いと思います。 ホテル内はアホかってくらい広いので、あーやっぱ違うわと思ってから移動するのに結構時間を食います。

個人的に気になってるセッション

まあだから何という話ですが、個人的に気になってるセッションについて簡単に書いておきます。選んでる時にメモつけたやつもそのまま載せているので参考までに。間違ってたこと書いてたら教えてください。
個々のセッションへのリンク貼るのはめんどうだったので、気になる人は Session Catalog をどうぞ。

  • ISM301 - Engineering Netflix Global Operations in the Cloud
    • Netflix のオペレーション全体像について聞けそう
  • STG403 - Amazon EBS: Designing for Performance
  • CMP405 - Containerizing Video: Creating the Next Generation Video Transcoding Pipeline
    • 動画変換を ECS や Lambda, S3, EFS (!!) などを使ってうまいことやってる話っぽい。SONY (グローバルのほう) の人
  • GAM402 - Turbine: A Microservice Approach to Three Billion Game Requests a Day
    • Turbine という Warner Brothers Games 傘下のゲームスタジオがゲームバックエンドを microservices で作っている話
  • CMP404 - Cloud Rendering at Walt Disney Animation Studios
    • 書いてあるのそのままだけど、Walt Disney のレンダリング環境に関する話
  • SEC302 - IAM Best Practices to Live By
  • SEC312 - Reliable Design and Deployment of Security and Compliance
  • SEC304 - Architecting for HIPAA Compliance on AWS
    • 病院の臨床情報とかを共有するサービスで AWS を使いながら HIPAA 準拠する話
  • ARC403 - From One to Many: Evolving VPC Design
    • 毎年おなじみのセッション。VPC を使うネットワークアーキテクチャについて、毎年のアップデートを盛り込みながら最新ベストプラクティスみたいなのが聞ける
  • CMP407 - Lambda as Cron: Scheduling Invocations in AWS Lambda
    • セキュリティベンダーでおなじみ Sophos のエンジニアのセッション。タイトルで吹いた
  • DAT407 - Amazon ElastiCache: Deep Dive
    • ElastiCache の Deep Dive と Riot Games の話が聞ける
  • SEC320 - AWS Security Beyond the Host: Leveraging the Power of AWS to Automate Security and Compliance
    • evident.io のスポンサーセッション。Intuit (会計ソフト) の DevSecOps の話も聞けるぽい
  • SEC402 - Enterprise Cloud Security via DevSecOps 2.0
    • 最近ちまちま聞く DevSecOps についてのセッション
  • SEC401 - Encryption Key Storage with AWS KMS at Okta
  • SEC326 - Security Science Using Big Data
    • これも IntuitAWS が吐くセキュリティ系のログをうまいこと解析する話っぽい
  • CMP403 - AWS Lambda: Simplifying Big Data Workloads
  • NET404 - Making Every Packet Count
    • 実践ハイパフォーマンスEC2ネットワーキング
  • CMP310 - Building Robust Data Processing Pipelines Using Containers and Spot Instances
  • NET402 - Consolidating DNS Data in the Cloud with Amazon Route 53
  • SEC403 - Timely Security Alerts and Analytics: Diving into AWS CloudTrail Events by Using Apache Spark on Amazon EMR

そもそも時間が重複してるとか、予定があるとか、体力的な問題 (結構体力使う) で絶対全部は回れないんですが、このへんの話を聞きたいと思っています。あとはせっかく現地行ってるので、セッション後に細かい話を直接聞きに行ったりするとよさそう。
ランチ食べながらやる BoF とか, サービスチームと話ができる Ask me about コーナーとかもありますね。コミュ力

ちなみに全セッション基本的に先着順で、人数上限が設定されてるセッションだと waitlist とか表示されてることもあるのですが、特に関係なく先着枠に入れば入場できるはず (逆に Scheduler に入れてても入場できない) です。

その他

内容が一新されて ISUCON みたいになってる GameDay とか、 ホテル中のバーが貸し切りで無限に飲んで話せる Pub Crawl とか、 Pub Crawl の腹ごしらえに便利っぽいチキン大食いイベントの Tatonka Challenge とか、 人数規模が爆発してついに会場が隣のホテルの駐車場という謎スケールになった re:Play とか、 セッション以外でも面白イベントがいろいろありますね。英語力のなさには定評があるけど勇気を出してがんばっていきたい。

はー楽しみだ。参加されるエンジニア各位ぜひ声かけてください。よろしくおねがいします。

iOS9 で導入される ATS とは結局何なのか

iOS9 で導入される ATS (App Transport Security) の話です。 ATS は OSX, iOS アプリケーションが NSURLConnection, CFURL, NSURLSession を利用してサーバに接続する際 現時点で最善に近いセキュアな接続をデフォルトとする仕組みです。 この記事で言いたいことはだいたい 公式ドキュメント に書いてあるのですが、"よくわからんから全てにおいて ATS を無効化する" で終わらないためにどうすれば良いかについて書きます。 個人的に AWS をよく使っているので、AWS における事情なども適宜付加します。

何が変わるのか

"Default Behavior" の項目に記載されていますが、 ATS が有効になっていることによって外部接続先に要求される要素は、以下のものです。

  • サーバは TLS 1.2 をサポートしていなければならない
  • 利用できる暗号 (正確には Cipher Suite) は、Forward Secrecy を提供できる (かつ、ドキュメントに示されている) ものに限られる
  • 利用されるサーバ証明書は SHA256 以上のハッシュアルゴリズムによって署名されており、2048ビット以上の RSA 鍵、もしくは 256ビット以上の ECC 鍵が使われている必要がある
    • 検証できない証明書はエラーとなり接続ができない

また当然というか前提ですが、サーバは HTTPS に対応している必要があります。

対応の要否と対応方法について

接続先サーバが HTTPS に既に対応しているのであれば、あとは上に書いた3つの条件を満たせば問題なく通信できます。 cipherscanQUALYS SSL Labs の SSL Test を使うとこの条件を一度に検証できるでしょう。 以下に、SSL Test を利用した場合の例について記載します。 (検査対象のドメインがしばらくトップページに載るので、イヤな方は "Do not show the results on the boards" にチェックを入れてください)

TLS 1.2 に対応しているかどうかは "Protocols" 欄を見れば分かります。 f:id:kani_b:20150908000129p:plain

対応していない場合は TLS 1.2 を有効にする必要があります。現代のソフトウェアで TLS1.2 を有効にできない環境は意図的に設定しない限りそう無いと思いますので、 有効にしてください。

提供する Cipher Suite の確認は "Cipher Suites" 欄で確認できます。 横に小さく FS と記載されているものが Forward Secrecy (前方秘匿性、詳細はググれば分かります) を提供する CipherSuite です。 より厳密には、Apple の公式ドキュメント に記載されている "accepted ciphers" に記載があるものが含まれていれば OK です。 f:id:kani_b:20150908000149p:plain

こちらも、ここ数年のサーバ環境であれば問題なく設定できると思います (AWS ELB であれば、対応する CipherSuite にチェックを入れるだけです)。

最後に気づきにくいのが、サーバ証明書のハッシュアルゴリズムと鍵の強度について。 RSA 公開鍵長については2048ビット未満の鍵長を使った証明書発行が既に禁止されているため、 この条件を満たせないことがほぼ無いかと思われます。 問題となるのは "SHA256 以上のハッシュアルゴリズムによって署名されている" 部分でしょう。 AWS 公式サイトの結果を例とすると、以下のように、Signature Algorithm として SHA256 という表記が含まれていれば問題ありません。 f:id:kani_b:20150908000758p:plain

対応していない場合は、例えば SHA1withRSA といった表記になります。 こちらはまさに移行期間真っ最中 (いわゆる SHA-2 移行) というところですので、対応がサーバによってまちまちだと思われます。 最近証明書を購入された方であれば、明示的に SHA-1 証明書を購入していない限り問題はありません。 長い有効期間の証明書を購入している場合でも、多くのケースでは既に認証局側に SHA-2 証明書を再発行してもらえば移行することが可能なはずです。 ただし、SHA-2 証明書に移行することにより、いわゆるガラケーはじめ未対応端末での接続ができなくなりますので、クライアント環境をよく確認して移行するようにしてください。

対応ができないケース

多くの場合、特に iOS アプリケーションは開発者が直接面倒を見ていない (例: 広告配信) サーバに接続することがあると思います。 そうした場合、 Web サービス全体の HTTPS 事情を見ていても、 iOS9 リリースと同時に全接続先で ATS を有効にすることは困難だと思います。 そのため、最初のうちはまず自社 (あるいは自身) で作っている接続先を ATS 対応できるようにした上で、接続先サーバの対応を待って完全 ATS に切り替えていく必要があるでしょう。 私は検証できていませんが、ATS はドメインごとに有効/無効を指定できるようです。 またドキュメントにも書いてありますが、個々の要素 (TLS サポート、Cipher Suite など) を個別に無効にすることもできます。 SHA-2 証明書にまだ移行できない場合でも他の要素は有効にできるというケースも多いのではないでしょうか。

ATS 無効化は "セキュアではない" のか

諸説あるとは思いますが、ATS を切ることそのものが危険な状態に繋がるわけではなく、 こうしたものをあまり理解せずに切ってしまったり、切ったまま対応を考えないといったことが危険な状態を招くと考えています。 (ATS はあくまでベストプラクティスへの準拠を要求するものであり、ATS を切ったとしても安全な通信は可能です) 個人的には、世の中の HTTPS 化の流れは避けられない (かつ、移行すべき) と考えているので、歓迎している動きではあるのですが、 Apple が ATS で示しているものについて、あまり理解されていないのかなーと感じたので書いてみました。

なお、私は普段 iOS / OSX 開発に携わっているわけではありませんので、間違いなどがありましたらご指摘いただけると嬉しいです。

AWS ウルトラクイズで優勝してきた (AWS Summit 2015)

ちょっと日が経ってしまったけど、先週AWS Summit 2015 という AWS のカンファレンスに行ってきました。

http://www.awssummit.tokyo/

参加自体は今年で3回目。ちょうど社会人になってから毎年参加していることになります。 個人的に今年のメインはデベロッパーカンファレンス (DevCon) でした。 去年の Summit に行った時に、だんだんターゲット層が変わってきたなーというのを 発表内容とかを見ながら思っていたのだけど、ちょうどそう思う人達に向けたようなカンファレンスでした。来年もぜひお願いします。

どのセッションでも発表中はカメラのシャッター音が鳴りまくっていて、登壇者が「資料あとで公開します」と言っても鳴り止まなくて、大変だなーという気持ちになりました。

個々の発表内容については資料とか映像を参照するとして、全体的な感想としては、 これまであまり繋がりのなかった分野の技術者 (テレビ局とかもっと大きい規模のところ) と AWS で繋がって交流できているのは面白いなーと思いつつ参加していました。 データセンターという枠がなくなって、共通化される部分が大きくなったというのがあるのかな。

全セッション終了後に最後のイベントとして JAWS-UG (勉強会) があり、そこでは AWS ウルトラクイズという、AWS に関するクイズ大会がありました。優勝賞品はラスベガスで行われるカンファレンス re:Invent の参加一式 (渡航費宿泊費参加費)。 新卒1年目、2年目と参加して両年とも4位(入賞は3位から)という微妙すぎる順位で毎年帰ってきていたので、今年は一発当てたいと思っていたところ、優勝しました。 ガソリン入れて気合注入と思っていたら緊張のためか開始時には4缶空けていて途中の問題をよく覚えていないのですが、最後の問題はその日の朝にリリースされた Kinesis のパラメータの変更 (PutRecord の最大サイズ) でした。 ちょうど Kinesis 使いたい構成を考えていた時に読んでいたリリースだったこともあり、まあ運が良かったと思います。

ちなみに AWS は色々なリリースを粒度に応じてか、色々な場所で公開してくる (AWS Blog, 各サービス (Mobile とか Security) の Blog, forum, etc) ので、フィード購読して流し読むと"えっそんな変更あったの"が少なくなります。
今の自分の仕事は "AWS を使うこと"ではなく "サービスをユーザに届けること" なので、そんなん細かく読んでる意味あるの?みたいな自問自答もしますが、むしろ自分たちが(半分)身を預けてるサービスだし、とことん使い倒さないと意味ないなーと。 別に AWS だろうと GCE だろうと Azure だろうと同じですが、いわゆるロックインを恐れて中途半端に使う状態が一番最悪ですね。 むしろ他のサービスもとことん使っていった上で最適なものを選んで使うことができれば、それが一番健全なのかなーと思います。各社色々なサービスを出してきていますし、もうちょっとするといわゆるマルチクラウドのような環境で色々できるようになるんでしょうか。楽しみです。

というわけで、同じく1年目から運良く参加し続けている re:Invent に今年も無事参加できることになりました。10月なのでまだまだ先ですが楽しんできます。わーい。

ISUCON4 予選2日目2位通過

できました。楽しかったー
ISUCON については公式ページをご覧ください。
ISUCON公式Blog

.dat というチームで参戦しました。チームメイトは @TakatoshiMaeda@y_matsuwitter というメンバー。
以前一緒の会社で働いてて、@TakatoshiMaeda とは現職でも同僚。
一緒に朝までデバッグしてたりつらいことを共有してきた仲ということもあり、色々やりやすかったです。

今回の ISUCON4 予選最大の誤算は ShellShock と AWS リブート祭でした。 ISUCON の性質上 Web インフラ界隈の参加者が多いようですし、 他の参加者でも巻き込まれた方々が多かったんじゃないでしょうか。お疲れ様でした。
ほんとは僕の自宅でモニタとか持ち込んで前日からワイワイやる予定だったのですが、 状況を冷静に考えて会社のオフィスでやることにしました。
祭が 3:00 AM - 7:00 AM JST という時間ゆえに当日影響を確認しつつ眠れたのは 5:30 AM という状態で、 @TakatoshiMaeda に「オフィスのこのへんで寝てるから起こして」と書き残して眠りについたら、
本人曰く「遠足前の小学生」だったテンションでその3時間後に叩き起こしてくれました。感謝。

#isucon 4予選参戦記 - 2日目暫定3位でした - takatoshi-maeda’s diary
#isucon 2014予選二日目を三位で通過した話 - Qiita

うちのチームがやったことは大体上記 URL の二人の記事に書いてありますので今更書くこともそんなに無いと思います。
@TakatoshiMaeda が全体の分析や初期のサーバセットアップ周りをめっちゃ前から準備してくれていて、当日非常にスムーズに開始できました。 大体11時前には環境構築、初期のベンチマーク、ひと通りの計測、コードリーディングをざっと済ますことができたことは非常に大きかった。
うまくいった理由は特に以下の3点だと思っています。

  • 3人の得意分野がいい感じにばらけていて補完できた
  • 上にも書いたように初期準備が非常にスムーズにいった。@TakatoshiMaeda++
  • ベンチを取りながら最初にガッとコードを読み、当初決めた戦略 (martini の入れ替えとフル Redis 化) がそのままピッタリハマった。

最初にコード読んだ段階で、ロジックの整理しやすい login_log 周りにかなりのコストがかかっており、レギュレーションの確認(再起動後もデータを保っている必要がある)がとれたので、かなり初期の段階で方針については合意できました。
僕は kernel, nginx, Redis のチューニング、あとはアーキテクトっぽいこととデバッガぽいことくらいしか仕事がなかった気がします。実際ノーチューンというか削れるだけ削りましたみたいな my.cnf は一度も触りませんでした。
あとはベンチマーク中の I/O などを眺めつつ、できるだけパフォーマンスを上げられるような設定を詰めていきました。
全部1サーバでやるという制約上、多少なりともオーバーヘッドのあるネットワーク通信を使いたくなかったので、 nginx - Go App - Redis 間は全て UNIX domain socket に変更していて、ベンチマーク的にはこれも結構効果が大きかったのではと思っています。
カーネル周りのチューニングは ISUCON 頻出というか現実世界でも頻出な TCP 周りの設定を入れ、 nginx は基本的なチューニングと静的ファイルを nginx で返すように設定。 あとは細かい点を直したり、他の二人の実装レビューしたりデバッグ手伝ったり、で終了。
何度も再起動したり AMI から作りなおしたりして確認後に AMI 提出。 暫定3位でしたが正式順位発表で2位となりました。
ISUCON4 本戦出場者決定のお知らせと本選出場者の利用言語比率 : ISUCON公式Blog

ISUCON では普段やっていないことはできないし、大胆なことをやるなら初期の段階にやるのが良いというのをなんとなく察していたので、状況によっては巻き戻して MySQL でやれるだけやることも(自分の中では)考えていたのですが、 @y_matsuwitter の進撃の実装力により何ら問題なく変更が完了したので杞憂に終わりました。 よかった。

感想と本戦に向けて

予選は1サーバのみで全てやるという制約上、とにかくメモリに載せるという戦略がどうしても取りやすくなってしまうとは思うのですが、単にメモリに載せるだけではダメで保持しているデータをどうするか、などの問題も絡んでくるので、やっていてとても楽しかったです。普段の仕事でもやるようなことを考えるので、"あ、これゼミでやったところだ!!!" 的なことも色々とありました。
本戦は過去の例を見ていると複数のサーバを使うことになりそう、つまり今回あまり重要な要素ではなかったネットワークをどう使うかという部分が重要になってきそうで、非常に楽しみにしています。
尻に火を付けられてガリガリやっていく感覚というのは健康上あまりずっと味わいたくはないわけですが、たまにやるエクササイズとしては最高ですね。
直前になって ShellShock みたくおしゃれニックネームとかおしゃれアイコンとか特設 Web サイトが登場するような脆弱性が出ないこと、インスタンスが大量リブートしたりすることのないことを祈りつつ、楽しみに本戦を待ちたいと思います。
運営のみなさま、大変だとは思いますが引き続きよろしくお願い致します!