【入門編】 Kubernetes APIサーバーに対するDoS攻撃とリソース制限 – オフェンシブセキュリティ & リバースエンジニアリング防御ガイド

こんにちは!インフラやセキュリティの世界へようこそ。これからKubernetes(クーベネティクス、略してK8s)という、現代のシステム開発には欠かせない技術を学び始めるあなたに向けて、とっても大切なセキュリティのお話をしますね。

今回テーマにするのは、「Kubernetes APIサーバーへの過剰なリクエストによる機能不全(DoS攻撃)」と、それを防ぐための「ResourceQuota(リソースクォータ)およびLimitRange(リミットレンジ)を用いたリソース制限」です。

なんだか難しそうな名前が並びましたよね。でも安心してください!まずは身近な「お家の防犯」に例えて、一歩ずつ優しく紐解いていきましょう。

—

1. 家の鍵と「インターホン」に例えるKubernetesの仕組み

皆さんが住んでいるお家を想像してみてください。お家には玄関のドアがあり、来客があったときはインターホンを押しますよね。家族や宅配の人が「ピーンポーン」と鳴らし、あなたが「はーい」と出て対応します。

Kubernetesの世界でも、これとまったく同じことが起きています。

  • お家全体 = Kubernetesクラスター(アプリが動く一大拠点)
  • 玄関のインターホン = APIサーバー(すべての命令やリクエストを受け付ける窓口)

Kubernetesのクラスターを操作するとき、私たちは kubectl というコマンドを使ったり、管理用のプログラムから通信を送ったりします。これらはすべて、APIサーバーという「たった一つの玄関のインターホン」めがけて、「このアプリを動かして!」「今の状態を教えて!」とリクエストを送っているんです。

攻撃者(泥棒)が狙う「インターホンの盲点」

もし、悪意を持った泥棒(攻撃者)があなたの家にやってきて、どうにかして家を機能不全に追い込もうと企んだとします。泥棒は力づくでドアを壊す代わりに、こんなイタズラを思いつきました。

「1秒間に1万回の勢いで、インターホンを連打し続けよう!」

さて、どうなるでしょうか?

あなた(APIサーバー)は、鳴りやまないインターホンの対応に追われ、玄関から一歩も動けなくなってしまいます。その結果、本当は荷物を届けに来た大切な宅配業者さん(正当な開発者やシステム)が来ても、まったく対応できなくなってしまいますよね。

これが、KubernetesのAPIサーバーに対する DoS(Denial of Service:サービス妨害)攻撃 のメカニズムです。APIサーバーがパンクしてしまうと、クラスター全体の管理ができなくなり、システム全体がストップしてしまうのです。

—

2. なぜ「無限にお願い」ができてしまうのか?

初期設定のままのKubernetesは、いわば「誰が何回インターホンを押しても、すべて無限に対応しようとするお人好しな執事」が住んでいるような状態です。

開発者がちょっとしたプログラムのミス(無限ループするスクリプトなど)を書いてしまったり、悪意あるユーザーが大量のゴミデータを作成するリクエストを送り続けたりすると、APIサーバーのCPUやメモリはあっという間に枯渇してしまいます。

ここで必要になるのが、「我が家に入っていいのはここまで!」「1人が使えるおもちゃの数には制限があります!」というルール作りです。

—

3. 防犯の切り札!「ResourceQuota」と「LimitRange」

Kubernetesには、この「無限のお願い」を防ぐための強力な防衛機能が備わっています。それが ResourceQuota と LimitRange です。

難しく考えず、それぞれ次のようにイメージしてください。

  • ResourceQuota(リソースクォータ):
  • 「このお部屋(Namespaceという空間)全体で使える、メモリやCPU、作れるコンテナの合計はここまでね!」という全体の上限枠です。
  • LimitRange(リミットレンジ):
  • 「お部屋の中の、1つひとつの家具(個別のコンテナ)の大きさには、これ以上大きくなってはいけないという個別の上限と下限を決めます!」というルールです。

これらをしっかりと設定しておけば、たとえ誰かが暴走して大量のリクエストを送ろうとしても、APIサーバーが「おいおい、これ以上は我が家のルール違反だよ!」と、自動でピシャリと跳ね返してくれるようになります。

—

4. 実務で使える!リソース制限の設定ファイル例

それでは、実際にKubernetesの世界でどのようにこの防衛策を設定するのか、設定ファイルのサンプルを見てみましょう。

実務の現場では、開発チームごとに「Namespace(名前空間)」という部屋を分けて管理することが多いです。ここでは、development(開発用)という部屋を守るための設定を書いてみます。

設定例 1: ResourceQuota(部屋全体の総量制限)

apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-resource-quota
  namespace: development # 適用するお部屋の名前を指定します
spec:
  hard:
    pods: "10"             # この部屋で作れるアプリ(Pod)の最大数は合計10個まで!
    requests.cpu: "4"      # お部屋全体で予約できるCPUの合計は「4コア」まで!
    requests.memory: 8Gi   # お部屋全体で予約できるメモリの合計は「8ギガバイト」まで!
    limits.cpu: "8"        # お部屋全体で使えるCPUの最大値は「8コア」まで!
    limits.memory: 16Gi    # お部屋全体で使えるメモリの最大値は「16ギガバイト」まで!

この設定をしておけば、たとえうっかりミスや不正な操作で「100個のアプリを一気に作ってくれ!」と言われても、APIサーバーは「最大10個までしか作れません!」と拒否してくれます。これでAPIサーバーのメモリがパンクするのを防げますね。

設定例 2: LimitRange(個別の大きさ制限)

apiVersion: v1
kind: LimitRange
metadata:
  name: dev-limit-range
  namespace: development # 同じく開発用のお部屋に適用します
spec:
  limits:
    - type: Container
      default:
        cpu: "500m"        # 何も指定がない場合、自動的にCPUを「0.5コア」使う設定にします
        memory: 512Mi      # 何も指定がない場合、自動的にメモリを「512メガバイト」使う設定にします
      defaultRequest:
        cpu: "200m"        # 最低限確保するCPUは「0.2コア」にします
        memory: 256Mi      # 最低限確保するメモリは「256メガバイト」にします
      max:
        cpu: "2"           # 1つのコンテナが勝手に使えるCPUは最大でも「2コア」まで!
        memory: 2Gi        # 1つのコンテナが勝手に使えるメモリは最大でも「2ギガバイト」まで!

「うちは小さいアプリしか動かさないのに、ものすごく重い処理をする怪しいプログラムが勝手に置かれてしまった…」という事故を防ぐため、個々のコンテナのサイズに「お行儀よくしてね」とリミットをかけるのがこの設定です。

—

5. 一歩ずつ、安全なクラスターを作っていこう!

今回は、KubernetesのAPIサーバーに対するDoS攻撃のメカニズムと、それを防ぐ ResourceQuota や LimitRange について学びました。

セキュリティの世界の基本は、「何も制限しない状態を作らないこと」です。「自分たちは大丈夫」「社内の人間だから変なことはしないだろう」という油断が、思わぬシステム障害やインシデントを招いてしまいます。

最初は難しく感じるかもしれませんが、こうして一つひとつ「お家の防犯」の仕組みを理解していけば、自信を持って安全なインフラを構築できるようになりますよ。

日々の開発やインフラ構築の現場で、ぜひこの設定を思い出して取り入れてみてください。一歩ずつ、確実にセキュリティのスキルを磨いていきましょう!

コメント

タイトルとURLをコピーしました