こんにちは!国内外でサイバーセキュリティの最前線に立ち、日々システムをクラッカー(悪意ある攻撃者)の手から守っているCISSPのセキュリティオフィサーです。
突然ですが、みなさんはご自宅の「予備の鍵」をどこに保管していますか?
「まさか、玄関の植木鉢の下や、郵便受けの裏に隠してはいませんよね?」
実は、今大人気のシステム管理ツール「Kubernetes(クーバネティス、以下K8s)」を使っている開発現場で、これと全く同じ「危ない鍵の隠し方」をしてしまっているケースが後を絶ちません。
今回は、K8sの中で大切なパスワードやAPIキー(これらを「シークレット」と呼びます)を、泥棒から完璧に守り抜くための方法を解説します。小難しいセキュリティ用語が出てきても、身近な防犯の仕組みに例えて丁寧に紐解いていきますので、一歩ずつ対策を学んでいきましょう!
—
1. なぜ標準の「Kubernetes Secret」は植木鉢の下の鍵なのか?
K8sには、標準機能として Secret という「パスワードを保存するための専用の箱」が用意されています。これを聞くと、「専用の箱なんだから安全だろう」と思いますよね。
しかし、ここに大きな落とし穴があります。
Base64は「暗号」ではなく「ただの並び替え」
標準の Secret にパスワードを登録するとき、データは「Base64(ベースロクヨン)」という形式に変換されます。
これは一見すると YWRtaW4= のような意味不明な文字列に見えるため、暗号化されているように錯覚してしまいます。
ですが、これは「日本語をローマ字表記に変えただけ」のようなものです。知識がある人なら、一瞬で元のパスワード(この場合は admin)に戻せてしまいます。泥棒にしてみれば、「ちょっと紙を裏返したら、そこに暗号の答えが書いてあった」というレベルの、非常に簡単な仕掛けなのです。
すべてのデータが集まる「etcd」という名の物置
K8sの裏側には、システム全体のあらゆる設定情報を保管する etcd(エトセディー)というデータベース(物置)があります。
標準の Secret を使うと、先ほどの「Base64で変換しただけのパスワード」が、そのままこの物置に放り込まれます。
もし攻撃者が何らかの方法でこの etcd にアクセスできてしまったら、あなたの家の「すべての部屋の鍵」が一瞬で盗まれてしまうことになるのです。
—
2. 泥棒(攻撃者)が狙う「3つの侵入ルート」
プロのハッカーや泥棒は、力任せに玄関を破るようなことはしません。もっと賢く、泥臭いルートを狙ってきます。K8sの環境において、彼らがシークレットを盗み出す主なルートは以下の3つです。
1. 物置(etcd)の直接ハッキング:
暗号化されていない etcd から、直接パスワードのデータを引っこ抜く。
2. コンテナの「環境変数」を覗き見る:
多くの開発者は、プログラムにパスワードを渡すために「環境変数」を使います。しかし、攻撃者がコンテナに一瞬でも侵入すると、env という簡単なコマンドを実行するだけで、画面にパスワードが丸見えになってしまいます。
3. ハードディスクの「残骸」を漁る:
サーバーのハードディスク(ストレージ)に一時的に書き込まれたパスワードのファイルを、サーバーが破棄された後に復元して盗み出す。
「じゃあ、一体どうすればいいの?」と不安になりますよね。
そこで登場するのが、「外部のプロの金庫番(シークレットマネージャー)」を雇うという方法です!
—
3. 解決策:プロの金庫番を雇い「必要なときだけ使い捨ての鍵」を渡してもらう
標準の Secret が頼りないなら、世界最高峰の頑丈な金庫を使えばいいのです。
具体的には、「HashiCorp Vault(ボルト)」や「AWS Secrets Manager」といった、セキュリティ専用の超強力な金庫サービスを利用します。
そして、ここからがプロの知恵です。
「金庫からパスワードを持ってきて、K8sの中にずっと置いておく」のでは、結局そこを狙われてしまいますよね。
そこで、「必要なときだけ、その瞬間だけ使える『使い捨ての鍵』をメモリ(脳内)にだけ覚えさせて、使い終わったら綺麗さっぱり忘れる」という仕組みを作ります。これを「動的シークレット注入(Dynamic Secret Injection)」と呼びます。
この仕組みを使えば、万が一サーバーのハードディスクを盗まれても、そこには鍵のデータ(足跡)が一切残っていないため、泥棒は手も足も出なくなります。
—
4. 【実践】External Secrets Operator (ESO) で安全に鍵を届ける
では、実際にこの「プロの金庫番」から安全に鍵を受け取る仕組みを、K8sの上に構築してみましょう!
今回は、現場で非常によく使われている External Secrets Operator(ESO) というツールを使って、AWS Secrets Manager(外部の金庫)から安全にパスワードを引っ張ってくる設定例(YAML)をご紹介します。
まずは、金庫の場所と、そこに入るための身分証明書を指定する「ストア」を設定します。
設定例1:金庫の場所を教えてあげる設定(SecretStore)
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-secrets-manager-store
namespace: default
spec:
provider:
aws:
service: SecretsManager
# どの地域のAWS金庫を使うかを指定します(例:東京リージョン)
region: ap-northeast-1
auth:
# 金庫を開けるための鍵(認証情報)を安全に渡すための設定です
jwt:
serviceAccountRef:
name: my-safe-service-account
次に、「この金庫の中にある、あのパスワードを持ってきて!」とお願いする設定を作ります。
設定例2:特定のパスワードを安全に取り出す設定(ExternalSecret)
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: my-database-secret
namespace: default
spec:
# 30秒ごとに金庫の中身が更新されていないか確認に行きます(常に最新の鍵に保ちます)
refreshInterval: "30s"
# 先ほど設定した「金庫の場所(SecretStore)」を指定します
secretStoreRef:
name: aws-secrets-manager-store
kind: SecretStore
# 取り出した鍵を、K8sの中で一時的にどういう名前で扱うかを決めます
target:
name: k8s-dynamic-db-secret
creationPolicy: Owner
# 実際に金庫(AWS)に保管されているデータの名前と、取り出したい項目を指定します
data:
- secretKey: db_password # K8s内での変数名
remoteRef:
key: production/database/credentials # AWS Secrets Manager上の金庫の箱の名前
property: password # その箱の中にある「password」という項目を指定
この設定(マニフェスト)を適用すると、ESOという執事のようなシステムが裏側で動いてくれて、AWSの頑丈な金庫から自動的にパスワードを安全に持ってきてくれます。
—
5. さらに強力な防犯:メモリの中だけで鍵を扱う「メモリ内保護」
ここまでの対策で、かなり安全になりました。しかし、最高峰のホワイトハッカーを目指すなら、もう一歩踏み込んでみましょう。
「いくら安全に持ってきても、コンテナの中に一時ファイルとしてパスワードが保存されたら、それが漏れるかもしれない…」
その心配、大正解です!
これを防ぐために、「ハードディスクには一切書き込まず、パソコンのメモリ(脳内・一時記憶領域)の上だけで鍵を扱う」という高度な設定を行います。
K8sでは、一時的なメモリ空間である emptyDir(ミディアム:Memory)という仕組みを使って、コンテナの中に「脳内専用の引き出し」を作ることができます。
設定例3:ファイルに痕跡を残さない「メモリ共有」のポッド設定
apiVersion: v1
kind: Pod
metadata:
name: secure-web-app
namespace: default
spec:
containers:
- name: web-container
image: nginx:alpine
# 脳内専用の引き出し(メモリ)を、アプリから見える場所にマウント(接続)します
volumeMounts:
- name: in-memory-vault
mountPath: /run/secrets/app # アプリはこのフォルダからパスワードを読み取ります
readOnly: true # 泥棒に書き換えられないように「読み取り専用」にします
# ここで「絶対にハードディスクに書き込まない、メモリだけの引き出し」を定義します
volumes:
- name: in-memory-vault
emptyDir:
medium: Memory # これが「ハードディスクではなく、メモリ(RAM)の上に作れ!」という魔法の命令です
この設定を行うことで、コンテナが動いている間だけメモリ上にパスワードが存在し、コンテナが停止したり再起動したりした瞬間に、パスワードのデータは宇宙の彼方へ完全に消え去ります。泥棒が後からサーバーのストレージを盗み見ても、そこには1文字のパスワードすら残っていません。
—
まとめ:セキュリティは「めんどくさい」を乗り越えた先にある安心
今回は、Kubernetesにおけるシークレット管理の危険性と、外部の金庫(VaultやSecrets Manager)を使った「動的シークレット注入」、そして「メモリ内保護」の仕組みについて解説しました。
最後に、今回学んだ防犯ポイントをおさらいしましょう!
- 標準の
Secret(Base64)は、植木鉢の下の鍵と同じ。過信は禁物! - プロの金庫番(外部マネージャー)と連携して、鍵は外で一括管理する。
- 鍵は「必要なときだけ使い捨て」を徹底する(動的注入)。
- サーバーのハードディスクに足跡を残さず、メモリ(Memory)の上だけで鍵を扱う。
セキュリティの対策は、最初は少し設定が面倒に感じるかもしれません。しかし、泥棒に家に入られてから後悔しても遅いのです。
「うちのシステムは大丈夫かな?」と気になった方は、ぜひ今回ご紹介したYAML設定を参考に、一歩ずつ安全なシステムづくりを進めてみてくださいね。
一歩ずつ、安全な開発ライフを一緒に歩んでいきましょう!
コメント