こんにちは!インフラ構築やアプリ開発を任されるようになって、「Kubernetes(K8s)」という言葉を耳にする機会が増えたのではないでしょうか。「コンテナを上手に管理できて便利そうだな」と思って触り始めたものの、覚えることが山ほどあって、頭がパンクしそうになっていませんか?
今回は、そんなKubernetesのセキュリティで、初心者が一番最初にハマりやすい、そして攻撃者にとっては「お宝の山」になりやすい「匿名認証の設定ミス」と「権限(RBAC)の不備」について、身近な防犯の例えを交えながら、優しく紐解いていきたいと思います。
一歩ずつ、一緒に安全な設定を学んでいきましょう!
—
家の鍵と泥棒に例えるKubernetesのセキュリティ
突然ですが、あなたが新しく買ったマイホームを想像してみてください。
頑丈な玄関ドアがあって、ちゃんとした鍵(認証)をかけなければ中に入れないようになっていますよね。さらに、家の中に入れたとしても、子供部屋には入れるけれど、絶対に開けてほしくない「秘密の金庫(機密情報)」がある部屋には、ちゃん内側の鍵(認可・RBAC)がかかっています。
- 認証(Authentication): 「あなたは誰ですか?」を確認すること(合鍵を持っているか)。
- 認可・RBAC(Authorization / Role-Based Access Control): 「あなたは何をしていい人ですか?」を確認すること(その部屋に入る権限があるか)。
Kubernetesもこれと全く同じです。しかし、初期設定のままだと、うっかり「合鍵を持っていない謎の訪問者(匿名ユーザー)」に対して、家の中を自由に出入りさせたり、最悪の場合は「すべての部屋の合鍵」を渡してしまったりする設定ミスが起きることがあるのです。
—
狙われる盲点:system:anonymous とは何者か?
Kubernetesの心臓部である「APIサーバー」は、外からのリクエストをいつも待ち受けています。このとき、ログインパスワードや証明書を出さずにやってきた「名無しさん」の通信に対して、Kubernetesはデフォルトで system:anonymous という特別なユーザー名を与えます。
「名無しさんなんだから、何もできないようにしておけばいいのでは?」と思いますよね。まさにその通りで、通常は何の権限も持っていません。
しかし、次のようなシチュエーションで悲劇が起きます。
1. 管理者のうっかりミス: 「テスト環境だから、とりあえず誰でもアクセスできるように設定を緩くしよう」と、匿名ユーザーを許可してしまう。
2. 過剰な権限付与(ClusterRoleBinding): 誰でもアクセスできる system:anonymous に対して、なぜか「クラスタ全体の神様(管理者権限)」を紐づけてしまう。
これが揃ってしまうと、「世界中のどこから来た誰ともわからない泥棒が、あなたのKubernetesクラスタの最高管理者になってしまう」という、セキュリティ事故に直結してしまいます。
—
攻撃者はどうやってこの不備を突くのか?(実録の仕組み)
攻撃者は、インターネット上に公開されているKubernetesのAPIサーバー(通常はポート 6443 など)を常にスキャンしています。
もしあなたが設定をミスしていると、攻撃者はわざわざログインしなくても、次のようなリクエストをAPIサーバーに投げつけるだけで、クラスタの情報を丸裸にできてしまいます。
実際に攻撃者が送るリクエストのイメージを見てみましょう(※セキュリティ教育目的の解説です)。
# 認証情報を一切つけずに、KubernetesのAPIサーバーへ「Podの一覧を教えて!」と要求する
curl -k https://<あなたのクラスタのIP>:6443/api/v1/pods
もし、ここで「そんな権限はありません(403 Forbidden)」と返ってくれば安全ですが、もし不備があると、動いているアプリケーションのリストや、内部の機密情報(環境変数に書かれたパスワードなど)が、JSON形式でベターッと返ってきてしまいます。
さらに最悪なケースでは、次のような「クラスタ管理者(cluster-admin)」の権限が、うっかり system:anonymous に紐づけられている設定ファイル(マニフェスト)が存在することがあります。
# 【絶対にやってはいけない危険な設定の例】
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dangerous-anonymous-binding # 誰でもアクセスできる人に最強の権限を与えている
subjects:
- kind: User
name: system:anonymous # ここが匿名ユーザーを指定している
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin # クラスタの神様権限
apiGroup: rbac.authorization.k8s.io
こんな設定がサーバーに残っていると、攻撃者はこのAPI経由で勝手に新しいコンテナ(仮想サーバー)を作り出し、そこに仮想通貨のマイニングプログラムを仕込んだり、踏み台として他の社内システムへ攻撃を仕掛けたりします。まさに「合鍵を玄関のポストに挿しっぱなしにしていた」状態です。
—
どうやって防ぐ?今日からできる実践的な対策
「うわ、怖いな……うちの環境は大丈夫かな?」と不安になったそこのあなた、大丈夫です!これからしっかり対策を覚えて、自分の環境を守れるようになりましょう。
1. APIサーバーの起動オプションで匿名認証を明示的にオフにする
KubernetesのAPIサーバーを起動する際(またはマネージドサービスの設定で)、匿名認証を禁止するフラグを明示的に有効にします。
APIサーバーの設定ファイルや起動引数に、以下の設定が入っているか確認してください。
# APIサーバーのパラメータ設定例
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
apiServer:
extraArgs:
# 匿名認証を拒否する設定(falseにする)
"anonymous-auth": "false"
マネージドサービス(AWSのEKS、GoogleのGKE、AzureのAKSなど)を利用している場合は、デフォルトで匿名認証が無効化されていることが多いですが、自前で構築(オンプレミスやK3sなど)している場合は必ずチェックしましょう。
2. RBACの「棚卸し」を定期的に行う
「誰がどんな権限を持っているか」を定期的に確認することが、セキュリティの基本(ゼロトラストの精神)です。
次のコマンドを使って、system:anonymous や system:unauthenticated (未認証ユーザー)に対して、危険な権限が紐づけられていないかをチェックしてみましょう。
# クラスタ内のClusterRoleBindingを総チェックし、匿名ユーザーに関連するものがないか探す
kubectl get clusterrolebindings -o json | jq '.items[] | select(.subjects[]? | .name == "system:anonymous")'
もしこのコマンドを実行して、何か設定が出力された場合は即座にその設定を削除(あるいは修正)してください!
# 危険なバインディングを削除するコマンドの例
kubectl delete clusterrolebinding dangerous-anonymous-binding
—
監査ログ(Audit Log)で侵入の形跡を見逃さない
「もし攻撃されたらどうやって気づけばいいの?」という疑問には、監査ログ(Audit Log)が答えてくれます。
Kubernetesの監査ログを有効にしておくと、「誰が、いつ、どのAPIにアクセスして、何をしたか」の履歴がすべて記録されます。特に、先ほどお話しした system:anonymous が機密性の高いAPI(シークレットの取得や、Podの作成など)にアクセスした形跡がないかを監視するのがポイントです。
監査ログの設定例(ポリシーファイル)を見てみましょう。
# 監査ログのポリシー設定例
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# system: anonymousユーザーの怪しい動きを「RequestResponse」レベル(詳細)で記録する
- level: RequestResponse
users: ["system:anonymous"]
verbs: ["get", "list", "watch", "create", "update", "delete"]
このようにログを細かく残す設定をしておけば、万が一不正アクセスがあった場合でも、「どのIPアドレスから、いつ、どんなリクエストが来たのか」を後からしっかりと追跡・調査することができます。
—
まとめ
今回は、Kubernetesの匿名認証設定とRBACの不備について、少しドキッとするような攻撃の仕組みから、具体的な防御・監査の方法まで解説しました。
- 認証の油断は大敵: 誰でも通れる「抜け穴(
system:anonymous)」を作らないこと。 - 権限は最小限に: 神様権限(
cluster-admin)を不用意に誰にでも渡さないこと。 - 定期的な点検とログ監視: コマンドや監査ログを使って、自分たちの環境が安全か常に確認すること。
セキュリティと聞くと難しく感じるかもしれませんが、要は「家の鍵をちゃんと閉めて、誰がどこに入れるかを管理する」という現実世界の防犯と同じです。
一歩ずつ、安全で堅牢なインフラストラクチャを作っていきましょう!それではまた次の記事でお会いしましょう。
コメント