現場の最前線で戦う諸君、お疲れ様だ。
今日は「暗号技術の選定」という理論の盾と、「Kubernetes NetworkPolicy」という物理的な壁について、本質的な話をしよう。多くのエンジニアが「TLSを使っているから大丈夫」と安堵し、KubernetesのNamespaceを単なる論理的な境界だと誤解しているが、そこにこそ攻撃者が喉から手が出るほど欲しい「横展開(Lateral Movement)」の隙間がある。
1. 暗号化は「何を守るか」で選ぶ:RSA vs ECC vs AES
まず基本だ。暗号技術を「なんとなく」で選ぶのは、家の鍵をその辺のホームセンターで買ったものにするのと同じくらい危うい。
- AES (共通鍵): データそのものを守る「金庫」だ。速度が命なので、大量のデータを暗号化する際はこれ一択。ただし、鍵の管理を誤れば金庫の鍵を全公開するのと同じだ。
- RSA / ECC (公開鍵): 鍵を渡すための「受け渡し用ポスト」だ。RSAは歴史があるが、鍵長が肥大化しすぎる。現代の推奨は間違いなくECC(楕円曲線暗号)だ。同じセキュリティ強度でも鍵が圧倒的に短く、計算リソースを食わない。モバイルやIoTデバイスが混在する現代において、RSAを選ぶ理由は「レガシーシステムとの互換性」以外には存在しない。
実務では、「通信の秘匿はTLS(ECCベース)で行い、DB保存時のデータ暗号化はAES-256-GCMで行う」のが鉄則だ。GCMモードを使う理由は、単なる暗号化だけでなく「改ざん検知」も同時に行えるからだ。
—
2. Kubernetes NetworkPolicy:その「デフォルト拒否」は飾りか?
次に、Kubernetesのネットワークの話だ。多くの環境でNamespaceを分けているが、デフォルトではその間の通信は「全通し」になっている。これでは、バックエンドの1つのPodが侵害された瞬間、クラスタ内の全ての機密データが攻撃者の手に渡る。
攻撃者が狙うのは、「フロントエンドからバックエンドへの正規の通信」を悪用した、あるいは「誤設定されたデバッグ用サービス」を経由した横展開だ。
これを防ぐための唯一の解が「Default Deny」だ。
実装サンプル:デフォルト拒否ポリシー (deny-all.yaml)
まず、そのNamespaceに存在するすべての通信を遮断する。これがなければ、どんなに精巧なラベル制御も無意味だ。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: backend-ns # 適用したい名前空間を指定
spec:
podSelector: {} # 空にすることで、その名前空間の全Podを選択
policyTypes:
- Ingress
- Egress
実装サンプル:最小権限の通信許可 (allow-frontend-to-backend.yaml)
次に、必要な通信のみを明示的に許可する。ここでは「frontend-ns」の特定のPodからのみ、「backend-ns」のAPIへのアクセスを許可する例を示す。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: backend-ns
spec:
podSelector:
matchLabels:
app: backend-api # 許可対象のラベル
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend-ns # 名前空間をラベルで指定
podSelector:
matchLabels:
app: frontend-web # 送信元Podをラベルで厳格に指定
ports:
- protocol: TCP
port: 8080 # 必要なポートのみを開く
—
3. なぜ「ラベル」で制御するのか?
ここがエンジニアとして最も意識すべきポイントだ。IPアドレスで通信を制御しようとするのは、IPが動的に変わるKubernetesにおいては自殺行為だ。
攻撃者は、侵害したPodから kubectl get pods や環境変数を漁り、内部ネットワークの構造をマッピングしようとする。もし君たちが名前空間やPodに正しいラベルを付与せず、漫然と namespaceSelector だけで許可していれば、攻撃者は「同じ名前空間にある踏み台Pod」を経由して、本来通信すべきでないサービスへパケットを投げ込む。
「最小権限の原則」をNetworkPolicyにも適用しろ。
podSelectorを必ず併用せよ。portはanyにせず、必ずアプリケーションがリッスンしているポートのみに限定せよ。
最後に:セキュリティは「設定」ではなく「規律」だ
最後に、開発者諸君に伝えたい。セキュリティはツールを入れて終わりではない。今回紹介したNetworkPolicyも、CI/CDパイプラインの中に組み込み、ラベルの付け忘れをデプロイ前に弾く仕組み(OPA/Gatekeeperなど)とセットで運用して初めて価値を持つ。
「暗号技術でデータを守り、NetworkPolicyでネットワークの境界を死守する」。この泥臭い積み重ねこそが、君たちのシステムを「堅牢」にする唯一の道だ。今日から、君たちのクラスタの Namespace を見直してくれ。そこにまだ「Default Deny」がないなら、今すぐ適用すべきだ。
現場からは以上だ。何かあればいつでも相談してくれ。
コメント