はじめに
最近のDockerやKubernetesの発展により、コンテナを利用したサービスやシステムの構築が盛んになっています。 しかし、環境を構築することがまず優先されてしまい、セキュリティに対する意識が薄くなっているそうです。
確かに、コンテナ技術を使ってサービスを構築するにあたり、セキュリティのことは気にはなりつつも、まずはDockerやKubernetesをどう使うかを優先してしまいがちです。
しかし、あらかじめコンテナ技術に対するセキュリティリスクと対策について概要だけでも知っておくことで、Docker、Kubernetesを使うときの考え方・意識が変わるはずです。
そこで、本記事にて「コンテナのセキュリティ対策とはどういうものが必要か?」という疑問を元に、基本的なことをまとめてみました。
ここに書かれていることが全てではありませんが、こういう対策が必要なんだな、程度に読んでイメージを掴んでいただけたら幸いです。
コンテナ技術のセキュリティリスクとは
コンテナは元をたどれば単なる実行プロセスです。そのため基本的にはプロセスのセキュリティ対策と同様の対策が必要になります。何もかも新しいセキュリティの対応が必要、というわけではありません。
ただし、コンテナ技術特有のリスクもあります。例えば、コンテナにマルウェアを仕込みDockerHubに紛らわしい名前でプッシュしておくことで、不特定多数の環境にばらまく、という攻撃などが考えられます。インターネットにあるコンテナイメージをスキャンせずに使うと上記のような攻撃を受けるリスクが上がってしまいます。
ここでは、下記の2種類の軸に沿ってリスクと対策について説明していきます。
- コンテナのライフサイクルから見えるリスクと対策
Dockerfile作成、ビルド、コンテナイメージ、レジストリ、コンテナ、デプロイ - コンテナ周りのコンポーネントから見えるリスクと対策
オーケストレータ、ネットワーク、ストレージ、ホストOS
コンテナのライフサイクルから見えるリスクと対策
コンテナのライフサイクルは、下記の図のようになっています。順番を優先するために、プロセス関連(Dockerfile作成、ビルド、デプロイ)と、成果物関連(コンテナイメージ、コンテナレジストリ、コンテナ)の項目を混在させています。
① Dockerfile作成
このフェーズでのリスクはまず、root権限でコンテナを実行していることで侵入者にroot権限を悪用されてしまうことが考えられます。これには、一般ユーザにてコンテナプロセスを実行する、Dockerfileの脆弱性スキャンを実施する、といった対策が必要になります。
また、リスクとして、Dockerfileに暗号化していないシークレット情報(IDやパスワードなど)を直接記載してしまうことで、第三者に情報を奪われてしまうこともあります。これは、Dockerfileにシークレット情報を直接書くのではなく、シークレット管理ツールを利用することで回避できます。
シークレット管理ツールには、”Vault"というものや”aqua”というものがあるようです。これは実行中のコンテナに、パスワードやSSHの鍵などの秘密情報を注入できる機能を備えています。
② ビルド
コンテナのメリットはコンテナイメージをあらゆる環境で実行し動かすことができる点です。つまり一度ビルドしたコンテナイメージを使い続けることになります。そのため、セキュリティの観点ではビルド時に注意して対策を練ることが重要になってきます。
対策としては、ビルドの前に自動的にセキュリティテスト実施する仕組みを導入したり、ビルドされたイメージに署名をつけ改ざんに対する防御をすることなどが考えられます。
③ コンテナイメージ
コンテナイメージに関するリスクとしては、内部ファイルのアップデート不足によって脆弱性のあるアプリケーションなどがそのままになってしまっていたり、マルウェアが埋め込まれたイメージをベースとして利用してしまうことが考えられます。
こういったリスクに対しては、まずは定期的にコンテナイメージをアップデートする仕組みを導入し、利用するベースイメージの提供元、作成者、既知の脆弱性の有無、各ツールやライブラリ・ランタイム・OS等のバージョンなどをしっかりと確認することが重要です。信頼されているイメージのみを使うことでリスクをかなり軽減できます。
先述したツールには、イメージスキャンや結果のレポーティング、結果に対してのアクション設定などの機能が備わっており、セキュリティ対策を万全にするためには利用を検討しても良いと思われます。こうしたツールを組み合わせることで、「ビルドの段階でマルウェアが発見されたらイメージをレジストリにpushせずに警告メールを管理者に送る」といった仕組みも作ることができます。
また、レポートにはホストやコンテナ上で発生するセキュリティイベントなどが記録されるため、セキュリティインシデントが発生した時の監査証跡として利用することもできます。
④ コンテナレジストリ
コンテナイメージの取得先としてDockerHubを利用することもできますが、AWSやGitlabを利用して専用のコンテナレジストリを用意することもできます。こういう時に気をつけるべきは、レジストリとの通信の盗聴や、古いイメージのまま使ってしまうことによる脆弱性の発生です。レジストリの通信を暗号化したり、古いイメージを定期的に削除する仕組みを導入する対策が必要です。
また、レジストリへのアクセス権限を適切に設定し、認証を設けることで、不正アクセスを防ぐことができます。セキュリティレベルを高くするために、重要機密を扱うコンテナイメージと通常コンテナイメージのレジストリを分離するといった対策も有効です。
⑤ コンテナ
実行されたコンテナに対するセキュリティリスクとしては、ランタイムソフトウェア(Dockerだとcontainerd、など)の脆弱性や、コンテナに組み込んだアプリケーションの脆弱性が考えられます。どちらに対しても脆弱性スキャンが必須です。
また、マイクロサービスで利用されるアプリケーションはそれぞれにAPIがある可能性があるため、その分エンドポイントが増えることになります。そのため、各APIの発行を必要最小限に制限し、SSO認証を取り入れるなどして、統制を敷くことが重要です。
すでに実行中のプロセスであるため、監視を強化するのも有効な手立てです。疑わしいプロセスの振る舞いを検知し、通知したり、ブロックすることで被害を最小限に抑えることができます。
⑥ デプロイ
デプロイのフェーズでは、デプロイ自身にリスクがあるというよりは、いかに素早くセキュリティ対策を利用環境にデプロイできるかどうかです。
自動的なCI/CDの仕組みを導入し、セキュリティパッチを必要な環境に素早く適用できるようにします。 例えば、イメージのスキャンによって脆弱性を検知したらコンテナイメージを改修してレジストリに上げる。このレジストリへのpushをトリガーに、自動的にビルドとデプロイが実施される、というイメージです。
コンテナ周りのコンポーネントから見えるリスクと対策
コンテナ周りでセキュリティリスクがある部分は、オーケストレータ、ネットワーク、ストレージ、ホストOSです。
オーケストレータ
オーケストレータはKubernetesなどのコンテナ管理アプリケーションのことを指します。コンテナのデプロイやスケーリング、管理などを司る部分であるため、セキュリティ対策が非常に重要になります。
リスクとしては、甘い権限設定による特権アクセスや、設定不備によるクラスタ侵入や認証情報盗難などがあります。
特権アクセスに対してはこれまでと同様、最小権限をユーザに付与することが対策となります。設定不備に対しては、設定のスキャンや事前テストを導入することで、不備に気づかないままデプロイしてしまうことを避けられます。
また、セキュリティの対策というよりも、影響の範囲を狭めるという意味で、機密度レベルに応じたコンテナやロールをグループ化することも有効です。オーケストレーションレベルでお互いの通信を制限できるため、セキュリティインシデントがあったとしても、そのグループ内に影響を閉じ込めることができます。
そのほか、大規模なサービスの開発になると、複数のクラスタ利用や複数のクラウド環境(AWS、GCP、Azure)/オンプレミス環境を組み合わせることがあります。そういう場合には、各環境にまたがったセキュリティ対策を実施するために、Rancherのような個々のクラスタや環境の操作・管理を統一して行うツールが必須になるでしょう。
ネットワーク
コンテナのネットワーク設定はデフォルトでは外部との通信はできませんが、利用する上で少なからず外部向けのポートを設定するかと思います。また、内部通信は自由にできるようになっているため、一度悪意あるユーザに不正に侵入されてしまうと無制限にコンテナにアクセスできてしまう可能性があります。
コンテナ技術に関係なく一般的なネットワークセキュリティの対策としてできることは、F/Wやホワイトリストの利用、Develop/Test/Production環境の分離、ファイルシステムに対するRead-Onlyモードの適用などです。 ただし、コンテナは起動する場所があらかじめ決まっているわけではないため、F/WやホワイトリストにIPアドレス・ポートを利用するとネットワーク構成が複雑化してしまいます。コンテナのネットワーク周りの設定のために生まれたEnvoyやIstioといったサービスディスカバリを使うことでシンプルなネットワーク構造を保つことができます。
また、コンテナ特有の対策としては、ロードバランサやプロキシとして稼働するコンテナのみに公開ポートを設定する、内部でのコンテナ間の通信にVPNや専用のI/Fを使う、などです。
ストレージ
ストレージは、永続ボリュームであれ、共有ディスクであれ、あらゆるデータが格納される場所です。そのため、最小限のアクセス権限設定と通信時の暗号化を実施し、データ漏洩や盗聴を防ぐ必要があります。
まずは使っているストレージのセキュリティ機能を利用して、SSLによる暗号化やアクセス制限を実施します。その上でコンテナツール側(Docker、Kubernetes、Rancherなど)のセキュリティ対策を実施することで万全の体制を整えることができます。
コンテナツール側の対策としては、NFSやEBSを利用するときのストレージプラグインの脆弱性チェックや、コンテナ側からのアクセス制限、などです。例えば、Kubernetesでは永続ボリュームを設定するときに、マウントするストレージに対してReadWriteOnce、ReadOnlyMany、ReadWriteManyの設定が選べます。
ホストOS
コンテナはホストとカーネルを共有しているため、ホスト側のセキュリティ設定をしっかり実施しておく必要があります。
ホストOS自身への対策としては、定期的なOSアップデート確認および適用は必須です。
また、下記のようなホストOSのセキュリティ機能を利用して、コンテナプロセスの動きを制限することも可能です。
- SELinuxでMAC(強制アクセス制御)を使い、他の空間のリソースは使えないようにする
- Cgoupsを使ってプロセスのリソース使用量(CPU、メモリ、ディスクIO、ネットワークなど)を制限し、1つのコンテナにDoS攻撃を受けてリソースが圧迫されても、同じホスト上の別のコンテナがリソース不足になることを防ぐ
- Capabilityにて一部のroot権限が必要な機能のみをコンテナプロセスに与える
別の観点として、ホストOSからのコンテナの設定として下記の対策も有効です。
- コンテナに特化したホストOSを利用する
- コンテナが呼べるカーネルコールを制限する
- DockerやKubernetesのAPIコマンドの範囲をローカルネットワークのみなどに制限する
まとめ
以上が、コンテナを使う上でのセキュリティリスクと対策の基本事項になります。
様々な観点からセキュリティ対策を実施していかないといけませんが、全てを人がやろうとすると開発/運用スピードが落ちたり、抜け漏れが出てきたりしてしまいます。 そうならないためにも、スキャンやアップデート、脆弱性情報の更新などはCI/CDプロセスに組み込むなどして自動化させることが重要です。 これにより、「DevOpsサイクルの鈍足化」および「セキュリティ対応の抜け漏れ」を防止できます。
参考資料
SP 800-190, Application Container Security Guide | CSRC
DevSecOpsも実現できる。コンテナアプリを脅威から簡単・確実に守る方法:コンテナセキュリティ、5つの勘所とは? - @IT
DevOps/マイクロサービスに欠かせないコンテナセキュリティ – 導入前に知っておきたいリスクと対策 – Nissho Electronics USA Corporation
- 作者: Adrian Mouat,Sky株式会社玉川竜司
- 出版社/メーカー: オライリージャパン
- 発売日: 2016/08/17
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る