Slide 1

Slide 1 text

その「s」を付けるために ~はてなブログHTTPS化の軌跡~ by id:papix (@__papix__) 株式会社はてな

Slide 2

Slide 2 text

papix 株式会社はてな アプリケーションエンジニア (2017年2月~) ブログMediaチーム サービスリード 「はてなブログ」をつくっています アカウント類 はてな: id:papix Twitter: @__papix__ GitHub: papix CPAN: PAPIX ブログ: https://papix.hatena(blog.(com|jp)|diary.jp)/ 趣味はPerlと, (交通機関を利用した)旅行 去年JGC修行(JAL)を完遂しました(年間53搭乗/40,573km) 来年はいよいよSFC修行(ANA)をします

Slide 3

Slide 3 text

もくじ はてなブログとHTTPS化 ~ここまでの流れ~ なぜHTTPSにするのか? はてなブログHTTPS化の難易度 第1部: 激闘! Mixed Contents!! 第2部: 組み上げろ! 証明書自動発行システム!! まとめ

Slide 4

Slide 4 text

はてなブログとHTTPS化 ~ここまでの流れ~

Slide 5

Slide 5 text

はてなブログとHTTPS化 ~ここまでの流れ~ 2017年9月25日 ... 告知 http://staff.hatenablog.com/entry/2017/09/25/143000 2017年11月20日 ... 管理画面HTTPS化完了 (第1フェイズ) http://staff.hatenablog.com/entry/2017/11/20/175000 2018年2月22日 ... はてな提供ドメインブログのHTTPS化完了 (第2 フェイズ) http://staff.hatenablog.com/entry/2018/02/22/150000 2018年6月13日 ... 独自ドメインブログのHTTPS化完了 (第3フェイ ズ) http://staff.hatenablog.com/entry/2018/06/13/160000

Slide 6

Slide 6 text

今日話すこと 第1部: 激闘! Mixed Contents!! 第1フェイズ~第2フェイズの出来事 主にMixed Contents対応を中心に... 第2部: 組み上げろ! 証明書自動発行システム!! 第3フェイズの出来事 Let's Encryptを活用した証明書取得の仕組みについて

Slide 7

Slide 7 text

なぜHTTPSにするのか?

Slide 8

Slide 8 text

なぜHTTPS化が必要か http://staff.hatenablog.com/entry/2018/02/22/150000

Slide 9

Slide 9 text

なぜHTTPS化が必要か より安全にはてなブログを活用して頂くため 「はてなブログMedia」という企業向けの展開も行っているため セキュリティ強化は重要 HTTPSが前提となる技術スタックの登場 Progressive Web Apps, Service Worker... HTTPS化推進の波 様々な企業/団体がWebサイトのHTTPS化を推進している Let's Encryptもその流れの中で登場してきた Chromeでは, HTTPの場合に警告が出るようになっている

Slide 10

Slide 10 text

はてなブログHTTPS化の難易度

Slide 11

Slide 11 text

UGCサービス UGC = User Generated Content サービスの利用者がコンテンツを生み出すサービス ブログの場合, サービスの利用者(はてなブロガー)が記事という コンテンツを"生み出す" はてなブログはUGCプラットフォームとして"自由度"が高い HTMLで自由にブログをデザイン出来る, ブログの記事の中に も自由にHTMLを記述出来る

Slide 12

Slide 12 text

マルチテナント ユーザーごとにブログを開設できる 更に, 1人で複数のブログを持てる ブログは, デザインもCSS含めてかなり柔軟にアレンジ出来る 加えて, 企業向けの「はてなブログMedia」も同じコードの上で動い ている

Slide 13

Slide 13 text

他サービスとの連携 公式で様々なサービスのコンテンツを埋め込める Twitter, ニコニコ動画, はてなブックマーク, Amazon, iTunes... 自社サービスとの連携もある はてなスター, はてなブックマーク

Slide 14

Slide 14 text

Mixed Contents ユーザーが自由にHTMLを書ける = 様々なコンテンツを埋め込める/ 読み込める 画像, 動画, iframe, JavaScript, CSS... HTTPSのブログでHTTPのコンテンツを読み込むと, Mixed Contentsが発生する

Slide 15

Slide 15 text

独自ドメイン はてなブログが提供するドメインだけでなく, 任意のドメインでブ ログを開設できる 正確に言えば, はてなブログが提供するドメインから, 任意のド メインに切り替えることができる 独自ドメインについては, これまではHTTPS対応が難しかった ユーザが発行した証明書を預かるのは難しい(出来れば避けた い) Let's Encryptによって独自ドメインのHTTPS化も目処が立っ てきた

Slide 16

Slide 16 text

要するに... はてなブログはHTTPS化という観点で見ると「数え役満」状態 UGCサービス マルチテナント 他サービスの連携 Mixed Contents 独自ドメイン 日本でも屈指のHTTPS化難易度を誇るのではないか...?

Slide 17

Slide 17 text

第1部: 激闘! Mixed Contents!!

Slide 18

Slide 18 text

はじめに: Mixed Contentsとは? HTTPSのURLでウェブサイトを読み込んだ時に起こりうる 読み込んだHTMLから, 更に読み込まれるコンテンツがHTTPで 読み込まれる時に発生する HTTP接続は暗号化されていないので, 改竄されたり, 通信を盗 聴される危険性がある ウェブサイトを閲覧しているユーザーに注意を呼びかけるため, ブ ラウザ上に警告が表示される

Slide 19

Slide 19 text

Mixed Contentsを回避するには? やることはシンプル HTTPSのウェブサイトから読み込むコンテンツは, 全てHTTPS で読み込むようにする つまり, http://... で読み込んでいる所に s を足して, https://... にすれば良い

Slide 20

Slide 20 text

Mixed Contentsを回避するには? しかし, 単純に http://... を https://... に置換するだけでは いけない 当然ながら, そのコンテンツがHTTPSで配信されていなければ 意味がない! 従って... 機械的に/自動的に解決するのは難しい(埋め込むことが出来る コンテンツの種類が増えれば増えるほど) コンテンツごとに作戦を建てて, 丁寧に取り組んでいく必要が ある

Slide 21

Slide 21 text

第1フェイズ~第2フェイズの方針

Slide 22

Slide 22 text

方針 まずは, はてなブログが公式に提供する機能で埋め込んだコンテン ツによって, Mixed Contentsが発生しない状態を目指す(Mixed Contents対策) 写真(Fotolife/Google Photo), はてなブログで書いた過去記事, 他のはてなブログの記事の引用, Amazon, 楽天, YouTube, Twitter, Instagram, はてなブックマーク, ニコニコ動画, pixiv, iTunes, Evernote, ぐるなび/食べログ, Gist, Flickr, 絵, ミイル... 他にも, ユーザーが入力したはてな記法によって展開され, 埋め 込まれるコンテンツも存在する

Slide 23

Slide 23 text

方針 その後に, アプリケーションの改修を実施してHTTPSで利用可能に なる状態を目指す(アプリケーション改修) HTTPSでページを表示出来るようにする HTTPSに対応したページにHTTPでアクセスした場合, HTTPS にリダイレクトするようにする HTTPSに対応したページへはHTTPSでリンクを貼る フォームの送信先をHTTPSに変更する

Slide 24

Slide 24 text

Mixed Contents対策 HTTPS化したときに起こりうるMixed Contentsに対して, 取りうる 対策は以下のどれか: HTTPSで配信する HTTPSのリソースが使えるように改良する 機能を撤廃する

Slide 25

Slide 25 text

HTTPSで配信する 自社が提供するコンテンツであれば, HTTPSで配信するように修正 することもできる 部署間で調整して作業を依頼したり, 直接修正してPull Requestを送ったり... これで済むなら一番手っ取り早い

Slide 26

Slide 26 text

HTTPSのリソースが使えるように改良する 他社のサービスが提供するコンテンツを埋め込む場合, そのサービ スが提供するAPIを使って, 埋め込むための情報を取得していること が多い API側も昨今のHTTPS化の流れに乗って, HTTPSでリソースを 提供してくれることが多い HTTP/HTTPSの両方でリソースのURLを示してくれてい たり... 利用するAPIのバージョンを上げると, リソースのURLが HTTPSになることもあった

Slide 27

Slide 27 text

機能を撤廃する 最終手段 どうしてもHTTPでしか配信されていないものもある 対応が難しい場合, 記事中での利用状況なども調査して, 機能そのものを撤廃することもあった 例: ニコニコ動画のマイリスト埋め込み機能 当時は動画とコミュニティしかHTTPSでの埋め込みに対 応していなかった

Slide 28

Slide 28 text

絵文字事件 果てしないMixed Contents対策の中でも, 特に思い出深いエピソード...

Slide 29

Slide 29 text

「絵文字記法」の発見

Slide 30

Slide 30 text

「絵文字記法」の発見

Slide 31

Slide 31 text

「絵文字記法」の発見 古参スタッフですら知らなかった「絵文字記法」の存在に気づいた 絵文字記法を使うと, 指定したコードに従って, 最終的に画像が 埋め込まれる その画像がHTTPでしか配信されていなかった! 更に何故か, その絵文字の画像ははてな社内の他サービスが配信し ていた!!!

Slide 32

Slide 32 text

「絵文字記法」の対応 そもそも, はてなブログで使っているコンテンツを, 他サービスが配 信しているという状況が良くない そのサービスが万が一撤退することになった時, またてんやわ んやすることになる この機会に, 丁寧にはてなブログ側で配信するように手を加え た 手間としてはそこまでかからなかったが, 延々と対応している中で 唐突に作業対象が増えるのは精神的に参った...

Slide 33

Slide 33 text

アプリケーション改修 これもまた, Mixed Contentsと同じく地道な作業が必要 HTTPS化が必要な(可能な)エンドポイントをリストアップし て, 1つずつ対応していく

Slide 34

Slide 34 text

開発環境のHTTPS化 まずは開発者の環境もHTTPS化しておきたい 出来れば手元でもHTTPSで確認したい 開発環境はHTTPで本番環境はHTTPSだと, 意図せぬMixed Contentsを埋め込んでしまうかもしれない... 今回は, Docker + Nginx + いわゆるオレオレ証明書で解決 ちょうどHTTPS化の作業が始まる前に, 開発環境のDocker化 を推進していた アプリケーションの前にNginxのコンテナを立てて, 開発環境 もHTTP/HTTPSの両方に対応

Slide 35

Slide 35 text

テストの追加やリファクタリング 当然, テストもHTTPS環境に準拠したものに書き換えていく 平行して, リファクタリングした方が良さそうなポイントは積 極的に手を入れていった 特に, リダイレクト周りの処理は丁寧にテストを用意 はてなブログに存在する様々なパターンを網羅してテストした 例: HTTPSが有効なはてなブログに, HTTPでリクエストする と, HTTPSにリダイレクトする...

Slide 36

Slide 36 text

QA アプリケーションの改修が完了した後, リリース前にQAフェイズを 用意した はてなには専属のQAチームはないので, カスタマーサポートを 担当するサポート部に協力を依頼 "QAシート"を用意して, それに従って操作を試し, 結果をまと めてもらう

Slide 37

Slide 37 text

QAシートの用意

Slide 38

Slide 38 text

QAの成果 幾つか考慮漏れだったポイントを発見できた サポート部とHTTPS化による成果を共有できた 言うまでもなく, ユーザーからのお問い合わせに対しては, サポ ート部のメンバーが対応する HTTPS化によって, ブログの挙動がどのように変わるかを, QA を通じて共有することができた

Slide 39

Slide 39 text

リリース

Slide 40

Slide 40 text

リリース まずは社員向けにリリースして動作検証 問題がなければ, 一般公開を進めていく GitHubのIssueに手順書を用意して, リリースにあたって必要な作業 を全て列挙 関係部署への連絡, リリース後の動作確認手順など...

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

リリース 前述の通り, 2017年11月20日に管理画面のHTTPS化(第1フェイズ), 2018年2月22日にはてな提供ドメインブログのHTTPS化(第2フェ イズ)が完遂 リリース前後でデータロストやサービス停止などの問題もな く, 平和にリリース出来た そしていよいよ正念場, 独自ドメインブログのHTTPS化(第3フェイ ズ)へと足を踏み入れる...

Slide 44

Slide 44 text

第2部: 組み上げろ! 証明書自動発行システム!!

Slide 45

Slide 45 text

はじめに 技術的詳細については, 一緒に実装を担当した id:aereal の 「Builderscon tokyo 2018」における発表資料を参考にしてください 「ブログサービスのHTTPS化を支えたAWSで作るピタゴラスイ ッチ」 https://speakerdeck.com/aereal/the‑construction‑of‑large‑ scale‑tls‑certificates‑management‑system‑with‑aws

Slide 46

Slide 46 text

前提 はてなブログでは数万単位のブログが独自ドメインで配信されてい る それらの証明書を取得し, 配信時に適切に利用する必要がある 「証明書発行」についてはLet's Encryptの登場によって解決 独自ドメインのための「証明書取得」と「証明書配信」を実装しな ければならない

Slide 47

Slide 47 text

余談: Let's Encryptへの貢献 Let's Encryptは, Internet Security Research Group(ISRG)という非 営利団体によって運営されている このような仕組みを無料で提供するISRGに経緯を評し, 寄付も 実施した http://developer.hatenastaff.com/entry/2018/06/04/14 0000 毎年, 継続して寄付の活動を続けていきます

Slide 48

Slide 48 text

証明書取得の技術選定 AWS Certificate Manager はてなブログはAWSで構築されているので, AWSのフルマネー ジドサービスで対応出来ないか検討 AWS Certificate Managerで取得した証明書は, ELBに紐 づけて利用することが出来る 結果としては, 今回のオーダー(数万単位のブログ)では用途に適 さないことが判明し, 断念

Slide 49

Slide 49 text

証明書取得の技術選定 自前実装 こうなってくると, 自前で仕組みを作るしかなさそうという結 論に至る 証明書の取得だけでなく, 更新(Let's Encryptの証明書は3 ヶ月で有効期限が切れる)も考慮しないとけない Step Functionsを軸に, LambdaやDynamoDBなど, AWSのフ ルマネージドサービスをフル活用して実装することを計画 Lambdaで動かすコードは, 公式に対応されたGo言語を活用す ることに決定 チームメイトの言語習熟度や, 社内においてMackerelなど でGoが使われていることも後押しとなった

Slide 50

Slide 50 text

証明書配信の技術選定 AWS Certificate Managerが利用出来れば取得だけでなく配信も担 えたが, これは断念 SAN Subject Alternative Names, 1つの証明書で複数のドメインを 紐付ける仕組み Let's EncryptでSANを使う場合, ACME challenge(証明書発行 のための認証)は, 現時点ではdns‑01のみが利用可能 dns‑01の認証ではDNSの設定が必要であり, はてなブログ ではドメインのDNS設定は各ユーザーに委ねなければな らないので, 自動化が困難 また, そもそもとしてLet's EncryptのSANでは, 1つの証明書あ たり100ドメインまでしか含めることができない 結果としては, 証明書配信についても自前実装することを決意

Slide 51

Slide 51 text

証明書配信の技術選定 はてなブログでは, ProxyとしてNginxを採用している(EC2上に構築 し, 複数台のProxyが配置されている) Q. 取得した証明書を, 複数台のProxyに配信どのように配信する? 取得した全ての証明書を配信するのは厳しい 万単位のブログの証明書を読み込むと, メモリ使用量が著 しく増加する 証明書の更新が行われる度に読み込み直す必要がある

Slide 52

Slide 52 text

証明書配信の技術選定 最終的には, GMOペパボでの事例なども参考に, 証明書の動的読み 込みシステムを構築した ngx_mrubyを利用して, リクエストがある度に証明書をロード する Nginxではmruby以外にLuaを動かすことも可能だが, チームメ イトの言語習熟度を考慮してmrubyを採用した

Slide 53

Slide 53 text

プロトタイプ実装 本格的に開発を始める前に, 2週間のプロトタイプ実装期間を用意し た プロトタイプを実装することで, 見積もりの最適化(誤差を減ら す)と技術的課題点の早期発見を狙える 正式版(?)の実装においては, プロトタイプの知見を利用す るが成果物はそのまま使わない ...ので, 「ひとまず動くものを作る」の精神で, 素直に実装を 進めていく エンジニアは東京オフィス/京都オフィスで別れていたので, 東京オ フィスに集まって実装

Slide 54

Slide 54 text

プロトタイプ実装 プロトタイプ実装は, Mackerelの次世代TSDBでの知見を活用 予めプロトタイプ実装することで, 見積もりの精度を高めるこ とができた 実際, 第3フェイズはプロトタイプ実装後の見積もりとに対してほぼ 誤差なく終えることができた

Slide 55

Slide 55 text

ベンチマーク プロトタイプを利用して, ベンチマークも実装した 実際にLet's Encryptで取得した証明書を, Nginx + ngx_mruby で捌くことが出来るか? 結果としては, 後述するキャッシュの仕組みなども想定して実 装していたため, 無事に捌き切ることができた

Slide 56

Slide 56 text

プロトタイプの成果 実際に動作するものを一通り構築する中で, 事前にタスクを見積も った時に考慮が漏れていた点を発見できた 正式版の開発に着手するにあたって, 良い「お手本」が出来た 自分の場合, Go言語にそこまで慣れていなかったので, プロト タイプで書いたコードはとても良いお手本になった デプロイの仕組み, CIの仕組みなども構築でき, それを正式版に活か すことができた

Slide 57

Slide 57 text

実装 第3フェイズは, 2つのフェイズに分けて作業を進めた 第3フェイズα ... 証明書の取得/配信の仕組みを作る 第3フェイズβ ... 構築した証明書の取得/配信の仕組みと, 既存 のはてなブログを繋ぎこむ 前述の通り, プロトタイプ実装の成果もあって, 第3フェイズαについ ては見積もりどおり終わった 第3フェイズβについては, 予定よりも少し伸びてしまった とはいえ, 第3フェイズ開始前の予定から大きく後ろに伸びるこ とはなかった

Slide 58

Slide 58 text

詳解

Slide 59

Slide 59 text

結果 2018年6月13日, 無事独自ドメインのHTTPS対応(第3フェイズ)をリ リースできた こちらもまた, サービスの停止やデータロストといった大きな 障害なくリリースすることが出来た

Slide 60

Slide 60 text

このようにしてHTTPS化は進んだのです!!!

Slide 61

Slide 61 text

まとめ ほぼ1年をかけて, はてなブログのHTTPS化を成し遂げることができ た これほどの規模で, 長期間のプロジェクトに携わったことはな かったので, 良い経験になった 第3フェイズの中で, Go言語やAWSの各種フルマネージドサービス といった, 新しい知見を得ることができて良かった また, それぞれのフェイズでサービスダウンやデータロストと いった大規模な障害なくリリースを終えることが出来たのも自 信になった 様々な条件がある中で, それらを満たしつつ, サービスをHTTPSする 良い実装が作れたと思う

Slide 62

Slide 62 text

ご清聴ありがとうございました!