前回までのあらすじ
第1回では独自ドメインを取り、第2回ではCloudFront(=Webサイトのデータを配信するサービス)とOAC(=CloudFrontからだけS3へアクセスさせる仕組み)を使い、S3(=HTMLや画像などを保存するサービス)は非公開のままサイトを公開しました。
第3回では、公開前の記事まで見えていたため、記事をdraft(=下書き状態)とpublished(=公開対象の状態)に分け、生成範囲を見直しました。
その整理へたどり着く前に、AWS WAF(=Webアクセスをルールで制御するサービス)でサイト全体を隠しています。今回は、入れたあとで目的とずれていると気づき、外すまでの話です。
見せたくないなら、入口を閉じればいいと思った
公開前の内容が見えていると気づいたとき、最初に欲しかったのは、とにかく外から見えない状態でした。公開対象を整理するより、入口で止めるほうが早いと考えたわけです。
そこでAWS WAFをCloudFrontへ関連付け、自分のIPアドレスから来たアクセスだけを許可する構成にしました。
狙いどおり自分以外からは開けなくなり、ひとまず安心しました。ただ、公開サイトなのに自分しか読めません。少し落ち着くと、応急処置のままではいけないと分かりました。
CloudFrontへWAFのIP制限を付けた
入口を閉じる方針を決めたときは、ひとまずこれで落ち着けると思っていました。今回の環境では、CloudFrontにWeb ACL(=WAFでアクセス判定ルールをまとめる設定)を関連付けました。IP set(=判定に使うIPアドレスをまとめた一覧)には、自分が使う接続元を登録しています。
自分のIPアドレス ── 許可 ──┐
├─ AWS WAF ─ CloudFront ─ OAC ─ 非公開S3
それ以外のIPアドレス ─ 拒否 ─┘
Web ACLのデフォルト動作を拒否にし、IP setに一致するアクセスだけを許可しました。設定上は単純に見えましたが、「自分は通る、ほかは止まる」を実際に見るまでは少し緊張しました。仕組みはAWS公式のWeb ACLのデフォルトアクションに関する説明でも確認できます。
実際のIPアドレスは載せません。残したいのは設定値ではなく、なぜ選び、なぜやめたかです。
確かに隠せた。でも、公開サイトではなくなった
IP制限は機能しました。自分の接続元から表示でき、それ以外が拒否されるのを見たときは「これで隠せた」と安心しました。
ただ、隠したかったのは公開前の記事と実験テーマです。トップページや公開済みの記事まで閉じたいわけではありませんでした。
ところが、入口を閉めても公開物の整理は何も進みません。トップページまで自分しか開けない画面を見ているうちに、急場はしのげても、サイトを続ける方法としては目的とずれていると気づきました。
問題はアクセスではなく、生成する範囲にあった
CloudFrontとOACはS3を直接公開しないための仕組みです。一方、見えていた記事は正常に配信された公開用ファイルでした。
ここでようやく、直す場所を間違えていたと分かりました。問題はアクセス経路ではなく、ビルド(=Markdown原本から公開用ファイルを生成する処理)が、まだ見せない内容まで含めていたことです。
- S3への直接アクセスはOACとバケットポリシーで制限する
- 記事はMarkdownのstatusで公開対象を分ける
- 実験テーマは公開フラグが有効になるまで生成物へ含めない
箇条書きにして並べると、S3を閉じる話と記事を隠す話が別だと見えてきます。WAFで全体を隠すより、公開してよいものだけを生成するほうが、起きていた問題に合う対処でした。
常設する理由を考えると、今回は弱かった
SAMEKORO LABは、今回の時点ではログイン、問い合わせフォーム、APIのない静的サイトです。公開内容の整理不足を理由にWAFを常設するのは違うと感じました。
どのアクセスを何のために止めるのか。置いて安心するのではなく、運用中も理由を説明したいのですが、自分のサイトではまだ弱い状態でした。
費用と運用も小さくはなかった
今回は、公開内容の整理不足を隠すためにWAFを置いていました。その目的では、常設する理由として弱いと判断しました。
AWS WAFの料金はWeb ACL、ルール、処理したWebリクエストなどで変わります。固定額とはせず、AWS WAFの公式料金ページで確認します。
接続元が変わるたびに許可リストを見直す手間もあります。誰かに読んでもらう公開サイトでは、費用にも運用にも納得できませんでした。
WAFを外して、必要な仕組みを残した
公開対象を生成処理で分けられるようになったところで、CloudFrontからWeb ACLの関連付けを外しました。一度入れた設定を戻すので少し迷いましたが、残す理由を説明できないままにするほうが気になりました。
WAFを外しても、CloudFront+OACと非公開S3は残しています。S3を直接公開する形へ戻したわけではありません。
publishedの記事だけをサイトへ出し、draftはホーム、一覧、詳細へ出しません。実験ノートも準備中のままです。目的に合わない制限だけを外し、必要な境界は残しました。
外したあとに実際の表示を確認した
設定変更後は、今回の環境で実際のアクセスを確認しました。
- 独自ドメインからトップページとpublishedの記事を読める
- S3のオブジェクトURLへ直接アクセスすると拒否される
- draftの記事は公開サイトへ出ない
- 実験ノートは準備中表示のままになる
公開したいものは読めて、見せないものは公開用ファイルに含まれません。外したあとに普通にトップページが開いたときは、派手ではありませんが結構うれしかったです。入口を全部閉じるより、こちらのほうが今のサイトに合っていました。
入れてから外したことにも意味はあった
一度動かしたことで、Web ACLやIP setがどこで判定するかを確認できました。それ以上に、アクセス制御とコンテンツの公開管理を分けて考えられるようになりました。
使えるサービスを増やすことと、常設することは別です。個人環境だからこそ、試したあとで「今回は違う」と判断し直せます。
また必要になったら、そのとき考える
今回は外しましたが、AWS WAFが不要なサービスだと考えたわけではありません。再導入を考えるのは、たとえば次の状況です。
- ログインやAPIなど、動的な入口を追加した
- 実際に防ぎたい攻撃や不正アクセスが見えてきた
- 運用ルールと確認方法を決められた
守る対象と運用方法を先に決められれば、WAFを置く理由も説明できます。そのときに、あらためて必要なルールを選びます。
まとめ
公開前の内容を隠すため、自分のIPだけを許可するWAFを試しました。ただ、本来直すべきなのはアクセスではなく、公開用ファイルの生成範囲でした。
そこでWAFは外し、CloudFront+OACと非公開S3を残したまま、記事のstatusと生成処理で公開範囲を管理する形にしました。
一度入れたものを外すのは少しもったいない気もしました。それでも、理由を説明できない構成を残すより、今のサイトに合う形へ戻せてすっきりしています。