こんにちは!インフラや開発の現場に飛び込んだばかりの頃は、Kubernetes(K8s)なんて聞くだけで、なんだか宇宙船の操縦席みたいに難しく感じてしまいますよね。
「コンテナ?」「ポッド?」と覚えることが山積みの中、セキュリティの話まで出てくると、頭がパンクしそうになる気持ち、痛いほどよく分かります。
でも、安心してください。今回はKubernetesの心臓部の一つである「Kubelet(キューブレット)」という仕組みに潜む、ちょっと怖い「鍵の閉め忘れ」のトラブルと、その対策について、身近な例えを使いながら一歩ずつ優しく紐解いていきます。
現場で明日からすぐに使える設定のコツも紹介するので、一緒にリラックスして学んでいきましょう!
—
1. 家の鍵に例えて理解する「Kubelet」の役割と危険な状態
まずは、Kubernetesの世界を「ひとつの大きなお屋敷(クラスター)」に例えてみましょう。
- マスターノード(司令塔): お屋敷の主人。全体のスケジュールや指示を出します。
- ワーカーノード(働き者の部屋): 実際にアプリケーションが動く個別の部屋(サーバー)です。
- Kubelet(お部屋の執事): ワーカーノードの部屋一つひとつに必ず配置されている「執事」のようなプログラムです。
この執事(Kubelet)は、主人の命令を聞いて部屋の電気をつけたり、新しい荷物(コンテナ)を受け取ったりする、とっても働き者です。
困った執事の「おしゃべり癖」
さて、ここで問題になるのが、この執事の「誰が来ても、尋ねられたら何でもペラペラ答えてしまう」というおしゃべり癖です。
昔のKubernetesや、初期設定のままのKubeletには、「読み取り専用ポート(デフォルトではポート10255)」というものがありました。これは、「まあ、細かい身分証の確認はいいから、部屋の中の様子を知りたい人が来たら、誰にでも教えてあげよう!」という、とってもオープン(=ガバガバ)な窓口です。
もし、泥棒(悪意ある攻撃者)がこの窓口を見つけたらどうなるでしょうか?
「ねえ、この部屋で今どんなアプリが動いてるの?」「機密情報が入っていそうな環境変数はある?」と聞くだけで、執事は親切丁寧に、部屋の中の機密データをすべて教えてしまうのです。
これが、今回お話しする「Kubeletの未認証アクセス脆弱性」の正体です。物理的な世界で言えば、「オートロックを信じきって、部屋の裏口の鍵を全開にしたまま出かけている状態」と言えます。
—
2. 攻撃者はどうやって「鍵の閉め忘れ」を見つけるのか?
レッドチーム(攻撃側)の視点に少しだけ立ってみましょう。と言っても、難しいハッキングツールを使うわけではありません。彼らはインターネットの海を「全自動の双眼鏡」で覗き見しています。
例えば、攻撃者は次のようなシンプルなコマンド(あるいはスキャンツール)を使って、世界中のサーバーから鍵の開いている執事を探します。
# ネット上のサーバーに対して、Kubeletの読み取り専用ポート(10255)に話しかけてみる例
curl -X GET http://<ターゲットのIPアドレス>:10255/pods/
もし、このサーバーの設定が甘ければ、JSON形式でそのノードで動いているすべてのポッド(アプリケーション)の情報、コンテナの名前、さらには内部で使っている機密性の高い環境変数(データベースのパスワードなど)が、画面にドバッと表示されてしまいます。
「えっ、URLを叩くだけでそんなことが分かっちゃうの!?」と驚かれたかもしれませんが、本当なんです。だからこそ、初期設定のまま放置しないことが何よりも大切なんですね。
—
3. 一歩ずつ実践!Kubeletのセキュリティを鉄壁にする設定
それでは、この「おしゃべりな執事」をしっかり教育し、ちゃんとした身分証(認証)を確認してからしか情報を出さないように設定を変更していきましょう。
Kubernetesの現場で私たちが必ず行うべき対策は、大きく分けて以下の2つです。
1. おしゃべり窓口(読み取り専用ポート10255)を完全に閉鎖する
2. 正面の通用口(ポート10250)で「匿名お断り(匿名認証の無効化)」と「身分証の強制(TLSクライアント認証)」を行う
実際のKubeletの設定ファイル(通常は /var/lib/kubelet/config.yaml や、kubeadmを使う場合はClusterConfigurationなど)を次のように修正します。
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
# 【対策1】危険な読み取り専用ポートを完全に無効化(0に設定)する
readOnlyPort: 0
# 【対策2】認証と認可の仕組みをしっかり有効化する
authentication:
anonymous:
enabled: false # 名乗らない怪しい訪問者は一切シャットアウトします
webhook:
enabled: true # 司令塔(APIサーバー)に「この人入れて良い?」と都度確認します
x509:
clientCAFile: "/etc/kubernetes/pki/ca.crt" # 正しい身分証(証明書)の基準を設定
authorization:
mode: Webhook # 司令塔に権限の有無を判断させます
設定変更のポイント解説
readOnlyPort: 0: これが一番の特効薬です。誰もがタダで中身を覗き見できた「窓口」そのものをシャッターを下ろして閉めてしまいます。anonymous.enabled: false: 「名無しさんお断り」の設定です。身分を明かさないアクセスはすべて門前払い(HTTP 401 Unauthorized)にします。
この設定を適用した後に、先ほどの curl コマンドでポート 10255 や認証なしのアクセスを試すと、しっかりとエラーが返ってくるようになります。これで一安心ですね!
—
4. まとめ:セキュリティは「日々の点検」がすべて
今回は、Kubeletの未認証アクセスについて、執事の例えを交えながら分かりやすく解説してきました。
- Kubeletの未認証ポートは、家の鍵の閉め忘れのようなもの
- 古い設定やデフォルトのまま運用すると、機密情報が丸見えになってしまう
readOnlyPort: 0の設定と、匿名認証の無効化(anonymous.enabled: false)でしっかりと守りを固めよう
セキュリティの対策と聞くと、「なんだか難しそう…」と身構えてしまうかもしれませんが、一つひとつの設定が「誰にどの範囲の権限を渡すか」という、人間関係のルール作りととてもよく似ています。
ぜひご自身のプロジェクトや開発環境でも、Kubeletの設定ファイルを開いて、ポートや認証の具合をチェックしてみてくださいね。「一歩ずつ、確実に安全な環境を作っていこう!」その積み重ねが、あなたを頼もしいエンジニアへと育ててくれますよ。
それでは、また次回のセキュリティ解説でお会いしましょう!
コメント