ブログ

SysdigによるKubernetesネイティブのネットワークセキュリティ

Google Cloudとコンテナの継続的なセキュリティ

本文の内容は、2020年11月17日にMateo Burilloが投稿したブログ(https://sysdig.com/blog/kubernetes-native-network-security/)を元に日本語に翻訳・再構成した内容となっております。

マイクロサービスとKubernetesは、ネットワークセキュリティにに関する考え方を完全に変えました。幸いなことに、Kubernetesネットワークセキュリティポリシー(KNP)は、この問題に正しい抽象度で対処するためのネイティブメカニズムです。

ネットワークポリシーの実装は、開発者と運用者が協力して適切なルールを定義する必要があるため、難しいものです。しかし、最良のアプローチは、Kubernetesネイティブコントロールを使用したネットワークセキュリティのためのゼロトラストフレームワークを採用することです。

SysdigがKubernetesネイティブのネットワーク可視性を提供する最新のSysdig Network Policy機能でこのギャップをどのように埋めているかをご覧ください。また、ネットワークのセグメンテーションを必要とするコンプライアンス要件(NIST、PCIなど)への対応にも役立ちます。

Kubernetesではコンテキストが王様

メタデータのエンリッチメントがないKubernetesの通信は意味不明です。

セキュリティやネットワークポリシーについて考え始める前に、まず、マイクロサービスがどのように相互に通信しているかを深く可視化する必要があります。

Kubernetesの世界では、ポッドは短命で、ホスト間を飛び回り、刹那的なIPアドレスを持ち、スケールアップしたりスケールダウンしたりします。これらはすべて素晴らしく、私たちが愛する柔軟性と反応性を与えてくれます。しかし、L3/L4 の物理的な通信層(IP とポートだけで見ると、以下のようになります)を見ると、以下のようになります。

0.png

つまり、すべての接続情報を持っているが、正しく集約されておらず、セグメント化されていないということです。さすがに、古典的なファイアウォールのルールを設定しようとしても、うまくいきません。イメージ名、イメージタグ、コンテナ名などの属性に応じて、異なるコンテナをグループ化することはできますが、これは手間がかかり、エラーが発生しやすく、情報はすべて動的で常に変化していることを覚えておいてください。

ネットワーク通信やセキュリティをKubernetesレベルで推論するために必要なメタデータはすでにすべて揃っているのに、なぜ車輪を再発明するのでしょうか?Kubernetes APIには、ネームスペース、サービス、デプロイメントなどに関するすべての最新情報が含まれています。また、それらのエンティティ(KNP)に割り当てられたラベルに基づいてポリシーを作成するツールも提供されています。

1.png

Kubernetes ネットワークポリシーの作成

開発者チームは運用チームと会い、アプリの1つに究極のネットワークポリシーを作成しました。

1時間の会議の後、開発者はこのようにアプリを定義しました:

2.png
  • "example-java-app"は2つのmongoDBデータベースをクエリします。
  • "example-java-client"アプリからのリクエストを受信します。

そして、これが彼らが考え出したネットワークポリシーです。

通常のメタデータでポリシーを開始します。これがNetworkPolicyです:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: generated-network-policy
  namespace: example-java-app 

次にネットワークルールです。"example-java-app"が8080番ポートでクライアントアプリからのリクエストを受け付けるように、ingressルールから始めます。

spec:
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              app: raw
              chart: raw-0.2.3
              heritage: Helm
              release: namespaces
          podSelector:
            matchLabels:
              app.kubernetes.io/instance: example-java-app
              app.kubernetes.io/name: example-java-app-jclient
      ports:
        - port: 8080
          protocol: TCP 

次に、アプリがデータベースに接続できるようにするためのegressルール: mongodbとredisです。

egress:
    - to:
        - namespaceSelector:
            matchLabels:
              app: raw
              chart: raw-0.2.3
              heritage: Helm
              release: namespaces
          podSelector:
            matchLabels:
              app.kubernetes.io/instance: example-java-app
              app.kubernetes.io/name: example-java-app-mongo
      ports:
        - port: 27017
          protocol: TCP
    - to:
        - namespaceSelector:
            matchLabels:
              app: raw
              chart: raw-0.2.3
              heritage: Helm
              release: namespaces
          podSelector:
            matchLabels:
              app.kubernetes.io/instance: example-java-app
              app.kubernetes.io/name: example-java-app-redis
      ports:
        - port: 6379
          protocol: TCP 

最後に、example-java-app-javaappという名前のポッドに適用されることを指定して終わります:

podSelector:
    matchLabels:
      app.kubernetes.io/instance: example-java-app
      app.kubernetes.io/name: example-java-app-javaapp
  policyTypes:
    - Ingress
    - Egress 

うわー、こんなシンプルなアプリにしては長いYAMLですね。通常のアプリのネットワークポリシーは数千行にもなります。

そして、これはKubernetesのネットワークポリシーの最初の注意点です。あなたはそれらを作成するために、まだ別のドメイン固有の言語を学ぶ必要があります。すべての開発者ができるわけではありませんが、それらに喜んでいるわけではありませんし、OPSチームはそれらを作成するためにあなたのアプリについて十分に知っているわけではありません。彼らは一緒に働く必要があります。

このネットワーク ポリシーを本番環境に導入してみましょう!

ポリシーを適用したら、アプリが動かなくなる😱。

Kubernetes-native-network-security-04-this-is-fine.gif

そして、これもKubernetesのネットワークポリシーを作成するプロセスの注意点です。トラブルシューティングには複数の関係者が関与する必要があり、プロセスが遅くなります。手作業でネットワークポリシーを作成する際に、いくつかのサービスやよくあるKNPの落とし穴を忘れてしまうことは本当に簡単です。

何を見逃したのか?

  • external serviceへの接続(IP 192.229.173.207)を忘れていました。
  • Cassandraデータベースへの非推奨の接続がありましたが、完全には削除されていませんでした。
  • DNSを許可するのを忘れていたので、サービスはお互いに話すことができましたが、サービス名をIPアドレスに解決することはできませんでした。

もちろん、チームが一斉に見つけたわけではありません。数時間に及ぶ試行錯誤でした。Cassandraの依存関係を完全に削除し、以下のようなEgressルールを追加することで解決しました。

外部IPへのトラフィックを許可するルール:

[...]
spec:
[...]
  egress:
  [...]
    - to:
        - ipBlock:
            cidr: 192.229.173.207/32
            except: []
[...] 

DNS解決のためのトラフィックを許可するルール。

[...]
spec:
[...]
  egress:
  [...]
    - to:
        - namespaceSelector: {}
      ports:
        - port: 53
          protocol: UDP
[...] 

そして最終的に、この更新されたポリシーを適用した後、すべてが期待通りに動作しています。そして、私たちのチームは、アプリネットワークが安全に保護されていることを安心しています。

Kubernetesネットワークポリシー作成の課題

なぜこの処理が人を喜ばせなかったのか、簡単に立ち止まって分析してみましょう。

Kubernetesのネットワークポリシーは些細なものではない

OK、それはそれらの使用を開始するのは簡単です。あなたがCalicoのように、それらをサポートするCNIをデプロイしたと仮定して、KNPは、Kubernetesのボックスから出てくる。しかし、まだ、彼らは多くの実装の詳細と注意点があります。

  • 彼らは許可のみであり、明示的に許可されていないすべてのものは禁止されています。
  • CNI はエンティティ (ポッドやネームスペース) のラベルに基づいており、名前ではないため、最初は少し誤解を招く可能性があります。
  • 少なくともクラスター内では、明示的に DNS トラフィックを有効にする必要があります。
  • などなど、、

それらは、学び、習得するためのもう1つのポリシー言語です。

必要な情報はチームに分散しています

開発者は通常、アプリケーションが機能レベルで何をすべきかを非常に正確に把握しています。データベースとの通信、外部フィードからのデータの取得などです。しかし、本番クラスターにKNPを適用して管理しているわけではありません。

運用チームは、Kubernetes を利用していますが、アプリケーションが内部でどのように振る舞っているのか、そして適切に機能するために実際に必要なネットワーク接続については、より限定的な可視性を持っています。

現実には、マイクロサービスに最適なネットワークポリシーを生成するためには、両方の利害関係者の意見が必要です。

KNP の学習曲線と、異なるスコープを持つチーム間での情報の行き来は、従来から痛手でした。一部の組織では、非常に広範なポリシー(マイクロサービスが同じネームスペース内にあれば相互に通信可能)に落ち着いていますが、これは何もないよりはマシで、誰もが従うことができるほどシンプルですが、間違いなく最も正確な施行ではありません。

SysdigでKubernetesのネットワークポリシーを作成

自分のアプリケーションが何をしているかを自分の言語で記述するだけで、誰かがそれを KNP (または将来的に使用する他のポリシー言語) に翻訳してくれるとしたらどうでしょうか?

Sysdig がどのようにして正確なネットワークポリシーを作成するのに役立つのかを見てみましょう。

本日、Sysdigは新しいKubernetesネットワークポリシー機能を発表しました。

  • アプリとサービス間のすべてのネットワークトラフィックを可視化し、通信を識別するのに役立つ視覚的なトポロジーマップを提供
  • ベースラインのネットワークポリシーは、必要な宣言状態に合わせて直接調整・修正することができます
  • トポロジー・ベースラインに基づいた KNP の自動生成とユーザー定義の調整

ハンズオン!

Sysdigの新しいKubernetesネットワークポリシー機能を使ってexample-java-app用の正確なポリシーを数分で作成する方法を見てみましょう。

ネットワークポリシーを作成するには、Sysdigのインターフェイス -> ポリシー -> ネットワークセキュリティポリシーにジャンプしてください。

3.png

Kubernetesネットワークポリシーを作成するための情報収集

まず、ポリシーを作成するポッドのセットを選択します。最初に、クラスタ、およびアプリが存在するネームスペースから始めます。

4.png

次に、ポリシーを適用するポッドの所有者、またはポッドのグループを選択します。ポッドは、Service、Deployment、StatefulSet、DaemonSet、またはJobでグループ化できます。

ここでは、Deploymentの観点からインフラストラクチャーを見てみます。

5.png

Sysdigがexample-java-appからネットワーク接続を理解するには、3時間分のデータがあれば十分です。

6.png

Sysdigが実際にネットワークデータを収集するのを待つ必要はありません。Sysdigエージェントはしばらくの間、このクラスターにデプロイされているので、Sysdigはアクティビティ監査から既存のデータを使用することができます。

これらのパラメータを選択した直後に、Sysdigは私たちのアプリデプロイのために観測されたネットワークトポロジーマップを表示します。

7.png

ここにはいくつかの興味深いキーがあります。

このマップには、現在のすべての通信(コネクターとポート)が表示されています。cassandraデータベースや外部IPのように、最初のアプローチで見逃したものも含まれています。

通信はKubernetesのメタデータレベルで表示されていることに注意してください。クライアントアプリケーションがサービスにリクエストをプッシュし、それがデプロイメントポッドに転送されているのがわかります。

色分けされたセキュリティポリシーを提案しています。未解決のIP、Kubernetesエンティティと照合できないエンティティはデフォルトで除外され、赤で表示されます。

すっきりとしていてシンプルで、必要な関連情報がすべて含まれています。

Kubernetesのネットワークポリシーをいじる

さて、アプリケーションの知識を持った開発者としては、いじりたくなるような細かい部分がいくつかあります。

  • 特定の外部IPを許可したい。
  • 特定の外部IPを許可したいのですが、今後許可したくないcassandraサービスへの接続がまだあります。

これは、インターフェイスのIngressとEgressタブから行います。

Ingress / Egressテーブルは、トポロジー・マップで見つかった情報を拡張して詳細に表示します。

8.png
9.png

追加情報は、個々の通信を識別するのに役立ちます。例えば、以下のようになります。例えば、"どのプロセスがegress接続を開始しているか?"など。

これらは実行可能です:

  • テーブルから許可したい通信を選択することができます。
  • 未解決のIPを見て、それを許可するかどうかを決めることができます。

信頼できるサービスに属しているため、外部IPを許可するためにIP/マスクの組み合わせを追加しました。

私たちは、その通信を必要としなくなったので、cassandraデプロイメントの行のチェックを外しました。

10.png

Sysdigは、私たちのIPがクラスタの外部にあるネットワークに属していることを自動的に検出し、そのようにフラグを立てます。

ネットワーク・トポロジー・マップは自動的に更新され、変更が反映されます:

11.png

外部IPへの接続は赤色ではなくなりましたが、cassandraへの接続は赤色になっていることに注意してください。

Kubernetesネットワークポリシーの生成

これでポリシーの見た目が思い通りになったので、Kubernetes Network PolicyのYAMLを生成します。

"Generated Policy"タブをクリックするだけで、その場で生成されます:

12.png

これで、このポリシーの成果物をDevOpsチームのための私のアプリケーションと一緒に添付することができるようになりました。

Kubernetesネットワークポリシーの適用

上のワークフローを見ればわかるように、Sysdigは観測されたネットワークの挙動とユーザーの調整を集約して最適なポリシーを生成するのを支援しています。

しかし、実際にこのポリシーを適用しているわけではありません。

それはKubernetesのコントロールプレーンとCNIプラグインに任せています。そして、これにはいくつかの利点があります。

  • これは、すぐに使えるKubernetesの機能を活用したネイティブなアプローチです。
  • ネットワーク通信、ホストのiptables、TCP/IPスタックに直接手を加えないようにしています。
  • 移植性があります。このポリシーをすべての同一のアプリケーション/ネームスペースに適用することができ、OpenShiftやRancherのようなほとんどのKubernetesフレーバーで動作します。

この機能の何がそんなにエキサイティングなのでしょうか?

まず、KNPがどのように動作するのかという低レベルの詳細を理解する必要がありませんでした。視覚的なフローを使ってアプリケーションのネットワークの挙動を記述することができれば、Sysdigが翻訳をしてくれます。

トポロジーマップは、サービス/アプリ/ネームスペース/タグをまたいだ全ての通信にネットワークの可視性を提供してくれました。そのため、任意のサービスを含めることを忘れることはありません。

また、ゼロから始める必要はありません。ネットワークポリシーをベースライン化することで、時間を節約できる10%のリフトを実行するだけです。その後、SysdigがYAMLを自動生成します。

Devopsチームとセキュリティチームは、サインオフしてポリシーをチェックするだけで済みます。

Kubernetesのネイティブコントロールを活用し、ポリシーの定義と適用を切り離します。 そのため、邪魔にならず、パフォーマンスへの影響を意味するものではありません。 また、Sysdigへの接続が失われた場合でも、ポリシーは有効であり、ネットワーク通信は維持されます。

最後に、これらのネットワークポリシーはKubernetesのネイティブポリシーなので、Istioや他のサービスメッシュにも拡張することができます。

まとめ

Kubernetesネットワークのセキュリティ要件に対応するために、Sysdig SecureはSysdig Network Policy機能を実現しました。

この機能を使用すると、以下のことが可能になります:

  • マイクロサービスとその通信を自動的に可視化し、Kubernetesメタデータを使用して物理層のノイズをすべて抽象化します。
  • サービスに最小特権のマイクロセグメンテーションを適用します。
  • 入力から導き出されるKNPを自動的に生成してくれるので、これまでのKNPの専門知識は必要ありません。

この機能を今日、確認することができます、無料トライアルを開始してください。

Sysdigに関するお問い合わせはこちらから

最近の投稿

カテゴリー

アーカイブ

ご質問・お問い合わせはこちら

top