CodeZine(コードジン)

特集ページ一覧

コンテナベースの開発パイプラインでセキュリティを実装する際の勘所とは?【デブサミ2020夏】

【A-8】コンテナベースの開発パイプラインへ“セキュリティ”を実装してみよう

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加
2020/09/01 12:00

 軽量なイメージ、ポータビリティ、充実したツールセット、豊富なエコシステムなどの特徴を持つことから、コンテナをベースとした開発は今非常に普及しつつある。このように開発において便利に活用できるコンテナだが、その一方で本番環境での運用においては、セキュリティ面で問題になることも多い。またライフサイクルコンテナも特殊であることから、それをどう継続的に見ていくかも課題の1つである。そこでコンテナにはどういう特性があり、どのようにしてセキュリティを実装していけばよいのか。その勘所などについて、マクニカネットワークスでコンテナ系の開発を担当している技術部 主席エンジニア 野原峰彦氏が解説した。

コンテナがもたらすメリットとは

マクニカネットワークス株式会社 技術部 主席エンジニア 野原峰彦氏
マクニカネットワークス株式会社 技術部 主席エンジニア 野原峰彦氏

 「コンテナは普及しつつあるステージにある」

 こう語り、野原氏のセッションはスタートした。

 Dockerをはじめとするモダンなコンテナアーキテクチャは、「非常に軽量」「ポータビリティ性が高い」などの特徴がある。軽量であることから、起動も非常に高速で、開発やテストの高速化が可能になる。またポータビリティの高さは、依存関係を含めてパッケージングされているため、これにより「環境依存による不具合を削減できる」と野原氏は言う。

 これにコンテナオーケストレーターを加えると、デプロイメントのコードがYamlやJSONになり自動化しやすくなる。オートヒーリングにより運用の簡略化、さらにはスケールアウト・スケールインの自動化などが可能になる。「従来、人の手でやっていた作業を自動化して効率化することが可能になる。Docker社がBuildやShip、Runに納めることができると言っていることが実現する」と野原氏は説明する。

 また、コンテナはDevOpsとの親和性が非常に高い。例えば、Flickrは「早期にリリースし、頻繁にリリースする」ということを実践していた。これを可能にしていたのが、「DevとOpsが協力しようという取り組みだった」と野原氏は話す。それを可能にするために、Flickrではキーとなる10項目を挙げている。これらの項目はツールやテクノロジーによるものと、企業文化によるものに大別されている。

 ツールやテクノロジーによる取り組みとしては、「1.インフラの自動化」「2.一元管理されたバージョンコントロール」「3.ビルドからデプロイまでのオペレーションの自動化」「4.機能の無効化/有効化」「5.明確な指標の共有」「6.通知の自動化」が挙げられる。

 これを現在に置き換えると、インフラの自動化であればInfrastructure as Code(IaC)、一元管理されたバージョンコントロールであればGitや成果物管理の仕組み、ビルドからデプロイまでのオペレーションであればCI/CDツール、機能の無効化/有効化であればブルー・グリーンやカナリアリリース、Circuit Breakerなどの方法が該当するわけだ。

 一方、企業文化による取り組みについては「リスペクト」「信頼」「問題発生時のあるべき対処」「責任追及の排除」といった項目を挙げている。

 「つまり、DevOpsは開発から運用までのプロセスにおいて無駄を排除したり、効率化したりする活動で、特定のプロセスや手法ではないということ。そしてDevOpsは、多くのケースにおいて継続的改善を行うために取り入れることが多い」と野原氏は指摘する。つまり、DevOpsとはビジネス課題に対して迅速なアクションを取ることができるチームをつくることであるというわけだ。

 DevOpsによってもたらされる主なメリットは、無駄の排除や業務の効率化が実現すること。「新しいサービスを市場にいち早く投入できることで、先行サービスの優位性が得られます。また、より多くのフィードバックも得られるため、品質の改善やエクスペリエンスの改善ができ、競争力強化につながります」(野原氏)

 DevOpsでは、ツールを使って次のようなモダンな開発環境を構築することが求められる。ビジネス要件に対して開発者がコードをコミットしGitにアップ、そのコミットしたコードに対してCI/CDツールが動いてビルド・テストをする。その結果に問題があれば通知を開発者に送り、開発者は修正したコードをGitに入れる。CI/CDツールでのテスト結果に問題がなかった場合は、デリバリ/デプロイを行う。デリバリされたプログラムは、ユーザーからフィードバックを受け、それが新たなビジネス要件になるのだ。

 だが、このようには簡単にことは進まない。CI/CDツールでは動いたのに本番環境では動かないなどの問題が発生するという。「なぜか環境依存の問題はすごく多い」と野原氏は指摘する。この問題を解決できる手法としてコンテナ化は非常に有効であるそうだ。

 コンテナ環境ではカナリアリリースも容易に自動でできる。例えば、Webアプリケーションを2つのコンテナにトラフィックを半々に分けて提供する仕組みを構築していたとする。新しいバージョンのWebアプリケーションを開発者がコミットすると、CIツールがそれをフックしてコンテナにデプロイする。新しいバージョンのコンテナにトラフィックの10%を振り分けるようトラフィック比率を変更し、一定時間経過後にエラーレートを確認。そこで問題がなければ、古いバージョンを消去し、従来通り新しいバージョンを2つのコンテナにトラフィックを振り分けてユーザーに提供するという仕組みが完成する。こういったことができるのもコンテナが軽量だからだ。

コンテナだとカナリアリリースも容易
コンテナだとカナリアリリースも容易

セキュリティを担保するのは難しい

 だが「コンテナは便利だが、セキュリティ面で気をつければならないことがある」と野原氏は続ける。

 「コンテナはカーネルを共有するが、そのカーネルを共有しているところがきちんと独立しているか。コンテナ専用OS、例えばRPMのパッケージがインストールできないなどのセキュリティをどう確保していくか。さらにコンテナはライフサイクルが特殊なので、その辺をどう継続的に見ていくかなどの課題があります」(野原氏)

 Dockerを使うときは、まずDockerファイルを記述する。このDockerファイルの1行1行はDockerのイメージレイヤとして、sha256:ハッシュ値のディレクトリに収納される。そして、これらのディレクトリを集めたものが1つのコンテナのイメージになる。

 「こういった環境で、ホストからセキュリティを提供するようなケースでは、ホストで見つかった脆弱性を、sha256:ハッシュ値のディレクトリからイメージにひも付きけることは難しい」(野原氏)

 また、Dockerは重複排除の機能があるため、同じsha256のハッシュ値を持つディレクトリであれば、1つを残して排除されることになる。つまり、このときにつけた脆弱性がイメージとしてその1つだけにひも付いているのかどうか、人の手で探すのは困難であると言うのだ。それだけではない。Dockerはスケールアウト・スケールインの動きも独特であることも影響する。

 「例えば、クラウドネイティブでアプリケーションの特定のアドレスや特定の機器にひも付かず動くという前提でつくってほしいと言われるとします。このような考え方はコンテナオーケストレーターにも取り入れられているため、Kubernetesの環境で、4ノードのクラスタの中に3つのコンテナをデプロイしたとします。明示的に指定しなければどこにデプロイされるか分かりません。このような環境でスケールアウトする場合は、今動いているのにプラスしていけばよいが、スケールインする場合は、どこのクラスタにどのコンテナが残るか分かりません。こういった動きをするコンテナに対して、特定のノードや特定のアドレスの形のセキュリティのアプローチは通用しないのです」(野原氏)

 コンテナ環境は設定変更やバージョンアップの方法が通常のアプローチと異なる。従来の仮想マシンであれば、問題が起きるとログインをして修正をして、その仮想マシンを運用し直せばよかった。

 だが、コンテナは元のイメージをリビルドして、入れ替えるというアプローチのライフサイクルになる。したがって、セキュリティのアプローチも変わってくる。コンテナは画一的なイメージの利用を前提としているため、そこで想定されない動きがないことを監視していくアプローチに変えなければならない。

 コンテナの実行環境の構成にも注意が必要になる。インフラはもちろん、Runtimeや関連ツールのバージョン、docker.sockに対する権限、ホストディレクトリのマウント状況、環境変数でコンテナに渡すクリアテキストのパスワード、イメージの脆弱性、ランタイム挙動の監視などのコンテナの構成、さらにはKubernetesやetcd、CoreDNSなどのコンポーネントのバージョンや設定など、コンテナオーケストレーターも脆弱性を持ちうるので見ていかなければならない。

 例えば、環境変数の部分。MySQLのイメージを動かすときに、「docker run -e MYSQL_ROOT_PASSWORD」といった環境変数を渡す方法を採用していたとする。この場合「docker inspect」やKubernetesであれば「kubectl describe」というコマンドで、ホストから簡単にパスワードが見えてしまう。

 Dockerfileの記述においても注意が必要だ。パスワードを入れるのは論外だが、JSON Web Tokenのファイルをコピーして、何か処理をし、その後削除するというプログラムでも、コンテナからは見えなくなっているがレイヤには残っているので、ファイルシステムから見えてしまうという問題がある。そのほかにも便利なイメージを使いたいという開発者の気持ちを悪用し、Docker Hubにマイニングスクリプトが仕掛けるという例もあるそうだ。

起動時の環境変数が見える
起動時の環境変数が見える

DevSecOpsを実現するためのツールとは

 つまり、「コンテナ環境のセキュリティは従来とは異なるアプローチが必要になる」と野原氏。ではどのような方法があるのか。その最適解は「NIST SP.800-190というコンテナに特化したガイドラインに準拠したコンテナセキュリティツールを使うことをお勧めする」と野原氏は言う。

 どのようなツールを使って環境をセキュアにしていけばよいのか。野原氏はGitHubとCircleCI、JFrog Artifactory、JFrog Xray、Twistlock(現在の名称はPrisma Cloud Compute)を紹介する。CircleCIはGitHubとシームレスに連携するCI/CDツール。

 JFrog Artifactoryは10年以上の実績がある成果物管理システムで、27種のパッケージ管理やリポジトリのプロキシ機能、アクセス制御などを提供する。JFrog XrayはArtifactoryのオプションとして使え、Artifactory上のデータにセキュティ(脆弱性診断とライセンスチェック)とそれに連動するアクセス制御を提供する。TwistlockはKubernetesのノードやコンテナホストにエージェント導入することで、コンテナの脆弱性、マルウェア検知・コンプライアンスを静的にスキャン。また、実行環境においても機械学習ベースのランタイム監視を行うほか、CIツールへの組み込みも可能。

 Dockerのイメージやサーバレス、IaC(TerraformやAWS CloudFormation、Kubernetesのマニュフェストも含まれる)のスキャンができる。もちろん、NISR SP800-190に準拠している。これらのツールを組み合わせていくのだが、この際に注意すべきポイントが2つある。「シフトレフトと自動化」である。

 つまり、なるべくDev側でチェックするようにすることと、人手を介さないように自動化することだ。シフトレフトされた側だけではなく、運用環境でのセキュリティの自動化を検討していかなければならない。こうすることで、DevOpsを継続しつつ、計画以外のすべてのところでセキュリティを担保することができるそうだ。

 実際に今回紹介した構成とほぼ同じ環境で2種類のデモを実施。最後に野原氏は、「正しいツールを組み合わせて使うことで、運用環境、開発環境に効率的にセキュリティを自動適用できるようになります」とセッションを締めた。

よりセキュアにかつ不便の少ない環境構築例
よりセキュアにかつ不便の少ない環境構築例

関連リンク

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • CodeZine編集部(コードジンヘンシュウブ)

    CodeZineは、株式会社翔泳社が運営するソフトウェア開発者向けのWebメディアです。「デベロッパーの成長と課題解決に貢献するメディア」をコンセプトに、現場で役立つ最新情報を日々お届けします。

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5