WAFが必要になってきた
近年サイバー攻撃が増加しているというニュースをよく耳にします。ホワイトプラスが運営するサービスのLenetも例外ではなく、日々多数の攻撃を受けています。攻撃は防ぎ切れていますが対応に時間を取られているのが現状です。Lenetは少数のエンジニアで運用しているため、もっと手軽に効率よく対応できないかということでWAFの導入が検討されました。
Lenetのアーキテクチャ紹介
まずは導入対象となるLenetのインフラ構成を簡単に紹介したいと思います。
LenetはGCPをメインに使用していて、アプリケーションはGKEで稼働しています。GKEで使用しているIngressのコントローラーとしてingress-nginxを使用しています。ingress-gceではありません。
ingress-nginxを使用している理由
Lenetではリリース手法としてBlue/Greenデプロイを採用しています。Blue/Greenデプロイを採用している理由として大きく分けると2つあり、ロールバックが簡単にできる点と複数のバージョンのアプリケーションが同時にアクセスを受けないことが保証される点です。
GKEに移行するときにRolling Updateに変更することも検討しましたが、複数バージョンが同時にアクセスを受けることが許容できず見送られました。
GKEでBlue/Greenデプロイを実現する方法として一番シンプルな方法がk8sのServiceでselectorを変更することです。
Google Cloud Skills Boostでも紹介されているアプローチになります。
このアプローチをingress-gceで作成したIngressを経由してアクセスすると一定期間(5分〜10分程度)BlueとGreenの両方にトラフィックが行ってしまうという問題があります。Ingress関係の設定を可能な限り変更してみましたが改善しませんでした。GCPのL7LBかコントローラーの実装に問題がありそうです。
次にingress-nginxを使ってみました。こちらをGKEで使用するとGCPのL4LBがServiceのtype: LoadBalancer
により作成され、L7の処理はk8s内に作成されたnginxコンテナが行うことになります。このコントローラーでBlue/Greenデプロイを実行してみたところselectorの変更直後に全てのトラフィックが切り替わり、意図した通りの挙動となったためこの構成で行くことになりました。
導入候補のWAF
WAFの選定において重要なポイントは以下になります。
- サイバー攻撃を少ない工数で防御できる
- 維持費(料金、保守工数)が高くなりすぎないこと
- 少ない工数で導入できること
- WAFの導入で削減される工数を超えないこと
これらを踏まえて各WAFサービスを調査していきます。
Cloud Armor
GCPで稼働しているということもあり、まずはCloud Armorを検討してみました。
ドキュメントを読んでみたところCloud ArmorはGCPのL7LBに対して設定する仕様のため、ingress-nginxを使用している現在の構成では設定することができませんでした。L4LBに対して設定することもできるようでしたが、Serviceのtype: LoadBalancer
によって作成されるL4LBは旧型だったため対応していません。仮に対応していたとしてもL4の攻撃しか防御できないため効果は薄くなってしまいます。
この時点でそのまま導入することはできないことがわかりましたが、他のWAFと比較するために料金も調べてみました。Cloud Armorの料金体系はアクセス数による従量課金で、1ユーザー当たりのアクセス数が少ないという特徴があるLenetにとって相性がよさそうです。
Cloudflare
次にCloudflareを見てみます。CDNがメインのサービスですがDDoSの防御としても有名です。
ドキュメントを読んでみたところCloudflareのWAFはCDNとセットになっていて、WAFの導入はCDNの導入を意味し、サイト全体をCDN経由で配信することになります。LenetではCDNはfastlyを使用していて静的ファイルだけをCDNから配信するアプローチを取っています。
色々と噛み合っていない部分があり見送りました。
Fastly
Cloudflareを調査した流れでFastlyにもWAFサービスがないかなと思い調べてみたところ、Fastly Next-Gen WAFというサービスがあったため検討してみました。
Fastly Next-Gen WAFはここまでで検討してきたWAFとはアーキテクチャが異なり様々な場所で実行することができます。一般的にはLBの後ろでnginx等のwebサーバーに組み込んで実行しますが、k8sの場合はPodにサイドカーとして追加する方法もあります。これらが難しい場合はリバースプロキシとして実行する方法やFastlyのEdgeで実行するオプションもあるようです。
このように導入方法が多く自分たちの環境にあった方法で導入できることが魅力で、Lenetの環境でもnginxやサイドカーであれば既存の構成を変更することなく導入できるため有力候補となりました。
しかし料金を調べてみたところ一番安いプランで月額3,000USDからと高額で、Cloud Armorと比較すると1アクセス当たり数十倍の料金であることが判明しました。手頃な価格であれば導入に向けて動き出すところでしたがあまりにも高額なため見送りとなりました。コストよりも導入スピードが優先にならない限りは難しそうです。
ModSecurity
ここまでは有料のサービスを見てきましたが最後にOSSのWAFであるModSecurityを検討してみます。
ModSecurityはingress-nginxに組み込まれていて設定を変えるだけで有効にできます。そのため、現在の構成から変更する必要がなく導入のハードルが低いことが大きな魅力になります。しかし、GUIが存在せずログから全ての状況を把握する必要があります。また、ルールの追加などの設定もファイルにテキストを記述する方式になっていて、Log4jのような脆弱性が見つかったときも自身でルールを書いて適用する必要があり、運用にコストがかかりがちです。SaaSのWAFであればGUIで確認や操作ができ、新たな脆弱性も自動で対応してくれたりしますが、有料サービスではないので自身で行うのは当然といえば当然です。
このように覚悟を持てば導入もありえる状況でしたが、ModSecurityの先行きが怪しくなる情報が出てきました。ModSecurityはTrustwaveという企業が開発と有償のサポートを行っていましたがOWASPというコミュニティに移管され、それに伴いnginxチームによる統合アドオンのサポートも終了することが発表されていました。
ingress-nginxでは現在も動きますが、取り除く提案がされていることも事実です。
この状況で新規に導入するのはリスクが高いと判断し見送ることにしました。
検討を終えて
ここまでいくつかのWAFを調査してきましたがこれと言ったものが無いというのが現状です。
費用を考えるとCloud Armorを導入することが最善ですがingress-nginxと相性が悪いです。GCPのL7LB (ingress-gce) からingress-nginxにトラフィックを流す構成は一般的なものから外れどのような罠が潜んでいるかわかりませんし、Blue/Greenデプロイの切り替えのためにproxyを導入するのは障害点の増加につながってしまいます。Argo RolloutsのようなBlue/Greenデプロイ用のツールを新規で導入するのも現在の課題感からすると大きくなりすぎです。
導入と維持の両方でコスパよくする方法はないかを模索し、視野を広げ前提となっている制限から見直してみることにしたところ、ingress-nginxを使用することになった理由であるBlue/Greenデプロイが必須ではなくなる可能性がでてきました。
バックエンドチームでフィーチャーフラグの導入などリリース方法の拡充を計画していて、それが実用化されれば複数バージョンが混ざっても問題なくなるとのことでした。これでCloud Armorを導入する道が見えてきました。
結論として、数ヶ月待ってからCloud Armorを導入しリリース手法をk8sデフォルトのRolling Updateに変更することになりました。
その後については後日公開予定です。もう少々お待ち下さい。