コンテナはセキュアと思われがちですが、そんな訳はないです。セキュリティは既存のオンプレミスやIaaSと同じ考え方ですが、コンテナ独自のノウハウがあります。業界で標準的に使われるようになってきたコンテナオーケストレータ Kubernetes を使用して、どのように運用するのが良いのかを考えます。
OSC 2020 Online/Fall で発表 #osc20on
myzkstr.comみやざきさとるコンテナ環境をセキュアに運用する方法
View Slide
myzkstr.comみやざきさとる宮﨑悟[email protected]@s_miyazasatoru.miyazaki.31 Solaris/ZFS/Solaris Zoneがすき フリーランスのエンジニア 北海道函館市からリモートワーク 主な仕事 某WordPress仮想マシン コンテナセキュリティ製品評価 技術コラム掲載
アジェンダ話すこと: コンテナセキュリティとは コンテナをセキュアに運用するためには コンテナセキュリティの怖い話話さないこと: コンテナ/Kubernetesの詳細※SpeakerDeckで資料公開中2020-10-24OSC2020 Online/Fall #osc20on 3
本資料でのコンテナの定義 コンテナ=アプリケーションコンテナとする アプリケーションコンテナ=Docker(もしくはDocker互換のコンテナ)を想定 コンテナのオーケストレーションサービスとしてKubernetesを想定 ホスト=コンテナが動作するマシンのことKubernetesのNodeに相当2020-10-24OSC2020 Online/Fall #osc20on 4
2020-10-24OSC2020 Online/Fall #osc20on 5
コンテナはセキュア? コンテナ内のアプリケーションを非特権ユーザで動作させる コンテナホスト上で非特権ユーザでプロセスが動作 コンテナ内で1アプリケーションのみ動作させる コンテナ内で余計なプロセスを動作させない 複数のコンテナやコンテナホスト間をつなぐネットワークは、分離もしくは暗号化可能 コンテナ外部からの通信は、必要なポートのみ接続される2020-10-24OSC2020 Online/Fall #osc20on 6
コンテナは(デフォルトでは)セキュアと言えない コンテナ内のアプリケーションを特権ユーザでも動作可能 コンテナホスト上で特権ユーザでプロセスが動作 コンテナ内でsystemdを起動可能 複数プロセス起動可能 ホストの特権機能もprivilegedオプションで使用可能 複数のコンテナやコンテナホスト間をつなぐネットワークは、デフォルトではフラットなネットワークで暗号化されない コンテナ外部への通信は、制限されない2020-10-24OSC2020 Online/Fall #osc20on 7
OSC2020 Online/Fall #osc20on 2020-10-24 8
コンテナをセキュアにするには コンテナのセキュリティポリシー ホストの堅牢化 コンテナイメージの検査 起動したコンテナの動作を監視・制御 機密データの扱い DevSecOpsサイクルの維持2020-10-24OSC2020 Online/Fall #osc20on 9
コンテナ環境で必須なセキュリティポリシー 攻撃者からホストへのアクセス防止 意図しないコンテナ起動防止 ホスト/コンテナの不要な通信防止 コンテナで使用するリソース制限 ホスト/コンテナの脆弱性の排除 CIS benchmarkなど業界標準セキュリティベンチマークの適用2020-10-24OSC2020 Online/Fall #osc20on 11
サービスで扱うデータで変わるもの 会員情報 匿名情報 個人情報を除いた、アクセス情報、購買情報など 個人情報/ペイメントカード情報 業界セキュリティ基準(GDPR/PCI-DSS/HIPPAなど)への準拠 データ保管時の暗号化 暗号鍵の外部管理 通信の暗号化(外部/コンテナ間)2020-10-24OSC2020 Online/Fall #osc20on 12
コンテナホストを堅牢化するために 自分でKubernetes環境を作成する ホストをクローズドな環境に配置 KubernetesやDocker APIのアクセス元を制限 Kubernetesのアカウント・ロールを設定 Kubernetesへアクセスする際のアカウント管理 Managed Kubernetesの使用 Kubernetes、ホスト設定の確認2020-10-24OSC2020 Online/Fall #osc20on 14
ホストをクローズドな環境に配置 コンテナホストをクローズドネットワークに接続 ベアメタル、仮想化環境 クラウドサービス(IaaS/CaaS/KaaS) SSHなどでアクセスせず、APIのみでアクセス2020-10-24OSC2020 Online/Fall #osc20on 15
ホストをクローズドな環境に配置 コンテナホストの構築は、Ansible/Terraform などで構築 Kubernetes コントローラの導入 ワーカーノードの追加 監視/ログ収集ツール/セキュリティソフトの導入 コンテナを動かすため最低限のソフトウェアで構成 Core OSなどのベースOS2020-10-24OSC2020 Online/Fall #osc20on 16
Kubernetes/Docker APIのアクセス元を制限 APIのアクセス元を制限し、公開状態にしない IPアドレス指定 クラウドプロバイダによる認証 IdP(Identity Provider)/IDaaSによる認証2020-10-24OSC2020 Online/Fall #osc20on 17
個人単位でアカウントを発行 もう令和なんだから、共用アカウントとか使用しない ロールを定義 ネームスペース サービス アクセス権限 Kubernetsアカウントへのロール割当2020-10-24OSC2020 Online/Fall #osc20on 18Kubernetesのアカウント・ロールを設定
Kubernetesへアクセスする際のアカウント管理 Kubernetesアカウントと外部アカウントの紐付け クラウドプロバイダ IdP(Azure AD/G Suiteなど)、IDaaS もう令和なんだから、共用アカウントなんか使用しない2020-10-24OSC2020 Online/Fall #osc20on 19
Kubernetes、ホスト設定の確認 CSPM(Cloud Security Posture Management)を使用する クラウド上のセキュリティ状態を検査する Kubernetesとホストの設定を検査し、設定ミスを検知 クラウドプロバイダの設定ミスも検知 CIS benchmarkの実行 Kubernetes環境の設定変更を検知2020-10-24OSC2020 Online/Fall #osc20on 20
コンテナイメージ内の脆弱性 ライブラリやソフトウェアの脆弱性は日々発見され続ける 開発段階でコンテナイメージの脆弱性を確認 デプロイしたコンテナイメージの脆弱性を確認 コンテナイメージは脆弱性が見つかるたびに更新/対処する コンテナ内で動作させるアプリケーションの脆弱性の対処 コンテナイメージの脆弱性を視覚化 脆弱性をレベル分けし、危険度が高いものだけを表示2020-10-24OSC2020 Online/Fall #osc20on 22
コンテナの脆弱性スキャン コンテナホストに対する脆弱性スキャン コンテナイメージに対する脆弱性スキャン コンテナのレイヤ単位でスキャンが可能 実行中コンテナに対する脆弱性スキャン 継続的スキャン2020-10-24OSC2020 Online/Fall #osc20on 23
静的スキャンツール コンテナ内に含まれるライブラリパッケージから、いくつかの基準で脆弱性を検知 NVD/CVE/OSベンダーなどの脆弱性情報 言語ライブラリ(Python/Node.js/Rubyなど)の脆弱性情報 脆弱性の脅威度によってレベル分け 既存のマルウェアの検知 鍵情報などが埋め込まれていないか2020-10-24OSC2020 Online/Fall #osc20on 24
継続的スキャン コンテナ静的スキャンを、開発中からデプロイ後まで実施 実行中コンテナのイメージに脆弱性があるか CI/CDの一部に含むことで、脆弱性の素早い対処が可能 シフトレフト障害対応を開発に寄せること(シフトレフト)で、開発から運用までの人的コストを下げる2020-10-24OSC2020 Online/Fall #osc20on 25
特権ユーザでのコンテナアプリケーション実行(1)2020-10-24OSC2020 Online/Fall #osc20on 27 コンテナ内でアプリケーションのrootユーザ権限実行→コンテナ外でもroot権限で実行される Docker rootless(非特権ユーザでのコンテナ実行)で回避可能 Podmanは、デフォルトでコンテナ内のUIDは、ホストからは別UIDとして扱う KuberentesのPod Security Policyでrootユーザでの実行を禁止(runAsUser)
特権ユーザでのコンテナアプリケーション実行(2)2020-10-24OSC2020 Online/Fall #osc20on 28 --privileged オプション付きでコンテナ起動→コンテナホストの特権操作がコンテナで可能 KubernetesのPod Security Policy によりprivilegedオプションをつけたコンテナ起動を禁止(privileged/allowedCapabilities/defaultAddCapabilities)
ローカルボリュームをマウントしてコンテナ起動2020-10-24OSC2020 Online/Fall #osc20on 29 /var や /etc などのディレクトリを読書き可能でマウントしてコンテナ起動→/var以下のdockerソケットにアクセスすることで、コンテナから別のコンテナを起動可能 KubernetesのPod Security Policy によりマウント可能なディレクトリ(allowedHostPaths)を指定 KubernetesのPod Security Policy によりマウントできるVolume Plugin(volumes)を指定可能
不要なコンテナ外への通信2020-10-24OSC2020 Online/Fall #osc20on 30 外部からPodへの通信は制御するが、Podから外部への通信は制限されない→不要なファイルをダウンロードされる可能性→内部の不正なPod/コンテナから通信される可能性 KubernetesのServiceリソースにより、Service配下のPodの通信先を制御 Firewall による制御
Kubernetesで設定できるセキュリティポリシー特権(privileged)コンテナの実行 privilegedホスト名空間の使用 hostPID, hostIPC使用可能なホストネットワークとポート hostNetwork, hostPortsPodで使用可能なFSGroupの割当て fsGroup使用可能なボリュームタイプ volumes使用可能なホストファイルシステム allowedHostPathsRead Only rootファイルシステムの使用 readOnlyRootFilesystemコンテナのユーザID/グループID runAsUser, runAsGroup, supplementalGroupsルート権限への昇格を制限する allowPrivilegeEscalation,defaultAllowPrivilegeEscalation2020-10-24OSC2020 Online/Fall #osc20on 31
Kubernetesで制御不可能な意図しないコマンド実行2020-10-24OSC2020 Online/Fall #osc20on 32 使用できるコマンドの制限 使用するsystem callの制限 イメージに含まれていないファイル/イメージと異なるファイルを実行しない 設定ファイルを変更してプロセス再起動
セキュリティソフトウェアによるランタイム監視2020-10-24OSC2020 Online/Fall #osc20on 33 ランタイム監視=実行中のコンテナの監視 ランタイム監視に求められること 実行中コンテナの脆弱性検知 ファイルインジェクションの検知 起動時から変更されたファイルの実行阻止 コンテナ内で実行可能・不可能なコマンド/system callの設定 コンテナ間・コンテナ外への不正な通信の禁止(Firewall)
機密データの分離 セキュリティレベルが違うデータを分離 会員情報/匿名情報 個人情報/ペイメント情報 リソースで分離 Kubernetes コントローラ Node Namespace2020-10-24OSC2020 Online/Fall #osc20on 35
機密データ保管時の暗号化 暗号化機能付きのDBに保管 DB機能で、暗号化/復号を行う DBへの通信経路を暗号化する必要あり 暗号化してPVに保管 コントローラ/ネームスペース/ホスト/PVでデータを分離 データを公開鍵暗号方式で暗号化して保管 暗号化するサービスと復号するサービスで鍵を分離2020-10-24OSC2020 Online/Fall #osc20on 36
暗号鍵の扱い 暗号鍵はKubernetesのSecurityリソースで管理 Secret自体はただのbase64エンコードされた文字列 YAMLファイルで管理するのはセキュアではない KMS(鍵管理システム=Key Management System)の併用 Hashicorp Vault/クラウドプロバイダのKMS/pgpなどで暗号化 鍵をSecretに配置するリソース/ソフトウェアとの併用 ExternalSecretリソース/kubesec/SealedSecretリソースなど2020-10-24OSC2020 Online/Fall #osc20on 37
機密データを使用したPodを破棄 機密データを不用意に再使用しない Podを停止することで機密データを削除 Pod上のアプリケーションでメモリ上の機密データ削除2020-10-24OSC2020 Online/Fall #osc20on 38
機密データを含む通信の暗号化 KubernetesはNode間の通信を暗号化可能 Pod間の通信は暗号化も認証もされない 解決策 アプリケーション側で経路を暗号化 既存の経路暗号化されるソリューションを使用gRPCIstio2020-10-24OSC2020 Online/Fall #osc20on 39
gRPC(https://grpc.io/) Google社が開発したRPC(Remote Procedure Call) 実装 Web経由のAPIなどで使用 経路としてhttp/2を使用→TLS暗号化済み セッション開始時に認証も可能 TLS用の証明書管理が必要2020-10-24OSC2020 Online/Fall #osc20on 40
Istio(https://istio.io/) Istioはサービスメッシュをコントロールするソフトウェア Istioコントルール配下のPodに、Proxyをサイドカーパターンで配置 Proxy間の通信をmTLSで暗号化 Pod間の通信をIstioコントローラで制御可能 Istio Ingressで、Istioとの連携も可能2020-10-24OSC2020 Online/Fall #osc20on 41
セキュリティはプロセス コンテナホスト自体の脆弱性チェック 定期的なイメージ再作成 イメージ検査 テスト(アプリケーション、ペネトレーション、負荷など) デプロイ 未知のマルウェア、インジェクションなどへの対応 コンテナの寿命を短くする ランタイム監視の実施 障害発生時のエスカレーション2020-10-24OSC2020 Online/Fall #osc20on 43
DevSecOpsの実践 一貫した開発・セキュリティ・運用が必要 シフトレフト バグを運用でカバーすると高コスト バグを開発で出し切る 運用、セキュリティコストの削減 DevSecOpsの自動化 CI/CDの考え方の導入+セキュアな考え方2020-10-24OSC2020 Online/Fall #osc20on 44
Development ベースOSの選定 言語、ライブラリ、パッケージの選定 セキュリティ基準に則った開発 アプリケーションの静的解析 ペネトレーションテスト2020-10-24OSC2020 Online/Fall #osc20on 45
Security セキュリティ基準の策定 CIS/NIST GDPR/PCI-DSS/HIPS DevとOpsに対するセキュリティ対策支援 開発のセキュリティ基準 コンテナセキュリティの方針決定 開発環境→デプロイ→本番環境のすべてをセキュアにする2020-10-24OSC2020 Online/Fall #osc20on 46
Operations イメージアップデートとデプロイ 脆弱性スキャンの反映 動的スキャナとの組み合わせ ログ/障害監視 障害検知時のエスカレーション2020-10-24OSC2020 Online/Fall #osc20on 47
コンテナイメージの脆弱性スキャン スキャンにより脆弱性が見つかった場合 ベースイメージ、パッケージ、使用ライブラリの更新 イメージの再作成→脆弱性検査 新コンテナイメージのデプロイ ローリングアップデート カナリアデプロイ ブルー/グリーンデプロイ 脆弱性は日々発見される定期的に脆弱性スキャン実施する必要がある2020-10-24OSC2020 Online/Fall #osc20on 48
アプリケーションの脆弱性 アプリケーションの脆弱性 SQLインジェクション CSR/CSRF ファイルのインジェクション コマンド実行 アプリケーション脆弱性の対応 アプリケーションで使用するライブラリは、最新のものを選択 脆弱性を意識したアプリケーション開発 ペネトレーションテストの実施2020-10-24OSC2020 Online/Fall #osc20on 49
CI/CDツールと静的イメージスキャンの組み合わせ CI/CDツール Gitlab GitHub Actions Jenkins Circle CI Travis CI アプリケーションのテスト/脆弱性スキャン イメージ作成後に静的イメージスキャン2020-10-24OSC2020 Online/Fall #osc20on 50
ルーチンワークは自動化する CI/CDツールで出来ることは自動化する アプリケーションテスト アプリケーション静的解析 イメージの静的スキャン コンテナ群へのペネトレーションテスト デプロイ リリース中のコンテナイメージに対する脆弱性スキャン Wazuhなど、脆弱性検査及び監視を行うツールもある2020-10-24OSC2020 Online/Fall #osc20on 51
人間は、人間に出来ることだけ行う コード、テストの作成 レヴュー セキュリティ設計 リリースのOK/NG インシデント発生時の対応2020-10-24OSC2020 Online/Fall #osc20on 52
人間の脆弱性も考える セキュリティは一番弱いところ(=人間)から狙われる ソーシャルハック最強 アカウント管理を厳格にする? 厳格にしすぎると、逆に回避策を考えるのが人間 パスワードマネージャなどのツールに任せる もしくはパスワードを使用しない ゼロトラストの採用も考慮する2020-10-24OSC2020 Online/Fall #osc20on 53
Docker APIが外部に公開されてた例(1) コンテナ環境を対象としたマルウェアKinsing(日本語化記事) 間違って設定されたオープン状態のDocker APIポートを攻撃対象 セキュリティ対策の無効化とログのクリア 多数のアプリケーション(クリプトマイナーを含む)を停止/削除 競合する悪意のあるコンテナを強制終了/イメージを削除 Kinsingマルウェアのダウンロードと実行 Kinsing自体の拡散2020-10-24OSC2020 Online/Fall #osc20on 55
Docker APIが外部に公開されてた例(2) 攻撃者が悪意あるイメージをホスト上に直接ビルド(日本語化記事) 公開されているDocker APIを使用 コンテナイメージを攻撃対象のホストでビルド 作成されたイメージはどこのレジストリにも保存されない→確認/対応しにくい イメージの名前/IDをランダムに生成 クリプトマイニングを実行2020-10-24OSC2020 Online/Fall #osc20on 56
公開されたイメージ内にマルウェア実行するスクリプト DzMLTによるクリプトマイニング(日本語訳) DockerHub上に存在するイメージに含まれた イメージ自体にマルウェアは含まれない イメージのENTRYPOINTでsshdを起動しバックドアとする GitHubからマルウェアをダウンロードして実行 クリプトマイニングを実行2020-10-24OSC2020 Online/Fall #osc20on 57
セキュリティよくわからない 自分で学ぶ ThinkITで連載してます(ダイマ)https://thinkit.co.jp/series/9523 金で解決する セキュリティに強い人材を確保・育成する セキュリティコンサルタントを雇う 商用のコンテナセキュリティツールを使う2020-10-24OSC2020 Online/Fall #osc20on 59
商用コンテナセキュリティ製品 Aqua Security イメージスキャン、ランタイムスキャン、監視、L3FW 日本販社あり Prisma Cloud イメージスキャン、ランタイムスキャン、監視、L7FW 日本販社あり sysdig イメージスキャン、ランタイムスキャン、監視 日本販社あり2020-10-24OSC2020 Online/Fall #osc20on 60
最後に この資料は、コンテナのセキュリティを考える為のきっかけ セキュリティ的な考え方はオンプレミス・IaaSと変わらない でも、コンテナのセキュリティには違う部分もあります 自分で答えを見つけよう2020-10-24OSC2020 Online/Fall #osc20on 61