序章

Dockerを使用してアプリケーションとサービスをコンテナー化すると、すぐに使用できるセキュリティ上の利点が得られますが、デフォルトのDockerインストールには、セキュリティ関連の構成を改善する余地があります。 インターネットセキュリティセンターは、インターネットセキュリティのベストプラクティスを促進することを使命とする非営利団体であり、Dockerを保護するためのステップバイステップのチェックリストを作成しました。 その後、Dockerチームはセキュリティ監査ツール(Docker Bench for Security)をリリースし、Dockerホストでこのチェックリストを実行し、見つかった問題にフラグを立てました。

このチュートリアルでは、Docker Bench for Securityをインストールし、それを使用して、Ubuntu 16.04ホストでのデフォルトのDockerインストール(公式のDockerリポジトリから)のセキュリティスタンスを評価します。 次に、警告された問題のいくつかを修正します。

私たちの修正は、主に次の2つの構成更新で構成されています。

  • auditdをインストールし、Dockerデーモンとそれに関連するファイルの監査ルールを設定します
  • Dockerのdaemon.json構成ファイルを更新しています

安全なコンテナの作成については詳しく説明しません。このチュートリアルでは、Dockerホストのセキュリティの更新にのみ焦点を当てます。

前提条件

このチュートリアルを完了するには、次のものが必要です。

  • sudoが有効な非rootユーザーのUbuntu16.04サーバー。 これを設定する方法については、 Ubuntu16.04ガイドを使用したサーバーの初期設定をご覧ください。
  • Ubuntu 16.04でDockerをインストールして使用する方法で説明されているように、Dockerは公式のDockerリポジトリからインストールされます。 docker グループに追加して、root以外のユーザーにDockerへのアクセスを許可してください。 これについては、チュートリアルのステップ2で説明しています。

ステップ1— DockerBenchSecurityをインストールする

まず、root以外のユーザーとしてDockerホストにSSHで接続します。

まず、gitを使用してDockerBenchfor Securityスクリプトをサーバーに複製し、次に複製されたリポジトリから直接スクリプトを実行します。

ユーザーが書き込めるディレクトリに移動します。 この例では、スクリプトをユーザーのホームディレクトリにダウンロードします。

  1. cd ~

次に、docker-bench-securityGitリポジトリのクローンを作成します。

  1. git clone https://github.com/docker/docker-bench-security.git

これにより、リポジトリからすべてのファイルがプルされ、ローカルのdocker-bench-securityディレクトリに配置されます。 次に、次の結果のディレクトリに移動します。

  1. cd docker-bench-security

最後に、セキュリティ監査を実行するには、docker-bench-security.shスクリプトを実行します。

  1. ./docker-bench-security.sh
Output
# ------------------------------------------------------------------------------ # Docker Bench for Security v1.3.4 # # Docker, Inc. (c) 2015- # # Checks for dozens of common best-practices around deploying Docker containers in production. # Inspired by the CIS Docker Community Edition Benchmark v1.1.0. # ------------------------------------------------------------------------------ Initializing Tue Jun 5 18:59:11 UTC 2018 [INFO] 1 - Host Configuration [WARN] 1.1 - Ensure a separate partition for containers has been created [NOTE] 1.2 - Ensure the container host has been Hardened [INFO] 1.3 - Ensure Docker is up to date [INFO] * Using 18.03.1, verify is it up to date as deemed necessary . . .

スクリプトはさまざまなテストを実行し、それぞれに対してINFONOTEPASS、またはWARNの結果を返します。 Ubuntu 16.04へのデフォルトのDockerインストールは、これらのテストの多くに合格しますが、セクション1、2、および4にいくつかの警告が表示されます。

このチュートリアルの残りの部分では、Dockerのインストールを保護することでこれらの警告に対処します。

ステップ2—ホスト構成の警告を修正する

監査の最初のセクションでは、強化、パッケージバージョン、監査構成など、ホストのオペレーティングシステムの構成をテストします。 このセクションのテストを見てみましょう。

1.1コンテナ用の個別のパーティションが作成されていることを確認します

適切な分離を確実にするために、Dockerコンテナーとすべての/var/lib/dockerを独自のファイルシステムパーティションに保持することをお勧めします。 これは、ドライブをパーティション分割する機能がない可能性がある一部のクラウドホスティング状況では難しい場合があります。 このような場合、Dockerのデータディレクトリを外部のネットワーク接続ブロックデバイスに移動することで、このテストを満たすことができます。

1.2コンテナホストが強化されていることを確認します

このテストは、ホストの強化を検討することを思い出させるためのメモにすぎません。 強化には通常、ファイアウォールの設定、さまざまなサービスのロックダウン、監査とログの設定、およびその他のセキュリティ対策の実装が含まれます。 サーバーを保護するための7つのセキュリティ対策を読むことで、これを開始できます。

1.3Dockerが最新であることを確認する

このテストでは、Dockerのバージョンが出力されます。 Docker CEリリースノートにアクセスすると、現在の安定版リリースがどのバージョンであるかを確認できます。 最新ではなく、apt-get installを使用してDockerをインストールした場合は、apt-getを再度使用してDockerパッケージをアップグレードできます。

  1. sudo apt-get update
  2. sudo apt-get upgrade

1.4信頼できるユーザーのみがDockerデーモンを制御できるようにする

前提条件のDockerセットアップチュートリアルでは、root以外のユーザーを docker グループに追加して、Dockerデーモンにアクセスできるようにしました。 このテストは、/etc/groupファイルからdockerグループの行を出力します。

Output
docker:x:999:sammy

この行には、dockerグループに含まれるすべてのユーザーが表示されます。 行を確認し、適切なユーザーのみがDockerデーモンの制御を許可されていることを確認してください。 上記の例では、許可されたユーザーsammyが強調表示されています。 このグループからユーザーを削除するには、gpasswdを使用できます。

  1. gpasswd -d username docker

1.5–1.13さまざまなDockerファイルに対して監査が構成されていることを確認します

Dockerのファイル、ディレクトリ、およびソケットの一部の監査を有効にするには、auditdをインストールして構成する必要があります。 Auditdは、カーネルレベルで注目に値するシステム操作をログに記録するLinuxアクセス監視およびアカウンティングサブシステムです。

auditdapt-getと一緒にインストールします。

  1. sudo apt-get install auditd

これにより、auditdデーモンがインストールされて起動します。 次に、Dockerファイルとディレクトリを監視するようにauditdを構成します。 テキストエディタで、監査ルールファイルを開きます。

  1. sudo nano /etc/audit/audit.rules

次のテキストが表示されます。

/etc/audit/audit.rules
# This file contains the auditctl rules that are loaded
# whenever the audit daemon is started via the initscripts.
# The rules are simply the parameters that would be passed
# to auditctl.

# First rule - delete all
-D

# Increase the buffers to survive stress events.
# Make this bigger for busy systems
-b 320

# Feel free to add below this line. See auditctl man page

次のスニペットをファイルの下部に貼り付けてから、保存してエディターを終了します。

/etc/audit/audit.rules
-w /usr/bin/docker -p wa
-w /var/lib/docker -p wa
-w /etc/docker -p wa
-w /lib/systemd/system/docker.service -p wa
-w /lib/systemd/system/docker.socket -p wa
-w /etc/default/docker -p wa
-w /etc/docker/daemon.json -p wa
-w /usr/bin/docker-containerd -p wa
-w /usr/bin/docker-runc -p wa

これらのルールは、指定されたファイルまたはディレクトリを監視(-w)し、それらのファイルへの書き込みまたは属性の変更(-p wa)をログに記録するようにauditdに指示します。

auditdを再起動して、変更を有効にします。

  1. sudo systemctl restart auditd

この時点で、Dockerファイルとディレクトリに疑わしい変更がないか監視するようにauditdを正常に構成できました。 Docker Bench for Securityスクリプトを再実行して、セクション1のテストに合格したことを確認できます。

auditdの詳細については、チュートリアル CentOS7でLinux監査システムを使用する方法を参照してください。 CentOS向けに作成されていますが、監査システムの構成と使用に関するセクションは、Ubuntuにも同様に適用されます。

ホスト構成を確認したので、Dockerセキュリティ監査のセクション2であるDockerデーモン構成に進みます。

ステップ3—Dockerデーモン構成の警告を修正する

監査のこのセクションでは、Dockerデーモンの構成を扱います。 これらの警告はすべて、daemon.jsonというデーモンの構成ファイルを作成することで対処できます。このファイルに、セキュリティ関連の構成パラメーターをいくつか追加します。 最初にこの構成ファイルを作成して保存し、次に構成内のテストと対応する行を1つずつ確認します。

まず、お気に入りのエディターで構成ファイルを開きます。

  1. sudo nano /etc/docker/daemon.json

これにより、空白のテキストファイルが表示されます。 次のように貼り付けます。

/etc/docker/daemon.json
{
    "icc": false,
    "userns-remap": "default",
    "log-driver": "syslog",
    "disable-legacy-registry": true,
    "live-restore": true,
    "userland-proxy": false,
    "no-new-privileges": true
}

ファイルを保存して閉じてから、Dockerデーモンを再起動して、次の新しい構成を取得します。

  1. sudo systemctl restart docker

これで、監査を再実行して、セクション2のすべての警告に対処したことを確認できます。

このファイルに挿入した構成変数は、監査警告と同じ順序で配置されています。 それらのそれぞれを見ていきましょう:

2.1デフォルトブリッジのコンテナ間でネットワークトラフィックが制限されていることを確認します

この警告は、構成ファイルの"icc": falseによって対処されます。 この構成は、Dockerコマンドラインの--link=container_nameまたはDockerCompose構成ファイルのlinks:パラメーターを使用して明示的にリンクされている場合にのみ相互に通信できるコンテナーを作成します。 これの利点の1つは、攻撃者が1つのコンテナを侵害した場合、同じホスト上の他のコンテナを見つけて攻撃するのに苦労することです。

2.8ユーザー名前空間のサポートを有効にする

Linux名前空間は、コンテナーで実行されているプロセスをさらに分離します。 ユーザー名前空間の再マッピングにより、プロセスは、ホスト上の特権の低いユーザーに再マップされている間、コンテナー内でrootとして実行できます。 構成ファイルの"userns-remap": "default"行を使用して、ユーザー名前空間の再マッピングを有効にします。

パラメーターをdefaultに設定します。これは、Dockerが dockremap ユーザーを作成し、コンテナーユーザーが再マップされることを意味します。 dockremapユーザーがidコマンドを使用して作成されたことを確認できます。

  1. sudo id dockremap

次のような出力が表示されます。

Output
uid=112(dockremap) gid=116(dockremap) groups=116(dockremap)

コンテナユーザーを別のホストユーザーに再マッピングする方がユースケースに適している場合は、構成ファイルでdefaultの代わりにユーザーまたはuser:groupの組み合わせを指定します。

警告:ユーザーの再マッピングは強力な機能であり、不適切に構成すると中断や破損を引き起こす可能性があるため、公式ドキュメントを読み、この変更を実装する前にその影響に注意することを強くお勧めします。プロダクション設定。

2.11Dockerクライアントコマンドの認証が有効になっていることを確認します

Dockerソケットへのネットワークアクセスを許可する必要がある場合は、公式のDockerドキュメントを参照して、安全に行うために必要な証明書とキーを設定する方法を確認する必要があります。

詳細は個々の状況に大きく依存するため、ここではこのプロセスについては説明しません。 監査では、このテストにWARNのフラグが付けられますが、デフォルトのローカル専用Dockerソケットへのアクセスは、 docker グループのメンバーシップを要求することで保護されるため、無視しても問題ありません。

2.12集中型およびリモートロギングが構成されていることを確認します

Dockerデーモン構成ファイルでは、"log-driver": "syslog"行を使用して標準のsyslogロギングを有効にしました。 次に、ログを一元化されたsyslogサーバーに転送するようにsyslogを構成する必要があります。 これにより、Dockerホストからログが取得され、ログを変更または削除する可能性のある攻撃者からログが奪われます。

Dockerログのみを転送し、syslogを出荷したくない場合は、ファイルに次のパラメーターを追加することにより、Docker構成ファイルでリモートsyslogサーバーを指定できます。

/etc/docker/daemon.json
    `"log-opts": { "syslog-address": "udp://198.51.100.33:514" }`

必ずIPアドレスを自分のsyslogサーバーのアドレスに置き換えてください。

または、splunkfluentdなどのログドライバーを指定して、他のログ集約サービスを使用してDockerデーモンログを送信することもできます。 Dockerログドライバーとその構成の詳細については、公式のDockerログドライバーのドキュメントを参照してください。

2.13レガシーレジストリ(v1)の操作が無効になっていることを確認します

この警告は、デーモン構成ファイルの"disable-legacy-registry": true行で修正されています。 これにより、安全でないレガシーイメージレジストリプロトコルが無効になります。 このプロトコルのサポートはDockerデーモンからすでに削除されているため、このフラグは非推奨になりつつあります。

2.14ライブリストアが有効になっていることを確認します

デーモン構成で"live-restore": trueを指定することにより、Dockerデーモンが実行されていないときにコンテナーが実行を継続できるようにします。 これにより、ホストシステムの更新中のコンテナの稼働時間やその他の安定性の問題が改善されます。

2.15ユーザーランドプロキシが無効になっていることを確認する

"userland-proxy": false行は、この警告を修正します。 これにより、デフォルトでホストポートのコンテナへの転送を処理するdocker-proxyユーザーランドプロセスが無効になり、iptablesルールに置き換えられます。 ヘアピンNATが使用可能な場合、ユーザーランドプロキシは不要であり、ホストの攻撃対象領域を減らすために無効にする必要があります。

2.18コンテナが新しい特権を取得することを制限されていることを確認します

デーモン構成の"no-new-privileges": true行は、コンテナー内からの特権の昇格を防ぎます。 これにより、コンテナはsetuidまたはsetgidバイナリを使用して新しい特権を取得できなくなります。

Dockerデーモンの構成を更新したので、監査のセクション4に残っている1つの警告を修正しましょう。

ステップ4—コンテンツの信頼を有効にする

監査でフラグが立てられた最後のテストは4.5 Ensure Content trust for Docker is Enabledです。 コンテンツの信頼は、Dockerイメージに署名し、実行する前にそれらの署名を検証するためのシステムです。 DOCKER_CONTENT_TRUST環境変数を使用してコンテンツの信頼を有効にできます。

現在のシェルセッションにこの変数を設定するには、シェルに次のように入力します。

  1. export DOCKER_CONTENT_TRUST=1

このexportコマンドの後に監査を実行すると、コンテンツの信頼が有効になっていることが示され、この警告がクリアされます。 すべてのユーザーとすべてのセッションで自動的に有効にするには、DOCKER_CONTENT_TRUST変数を/etc/environmentファイルに追加します。このファイルは、システム全体の環境変数を割り当てるためのファイルです。

  1. echo "DOCKER_CONTENT_TRUST=1" | sudo tee -a /etc/environment

Docker Contentの信頼の詳細については、公式のDockerContentの信頼に関するドキュメントを参照してください。

この時点で、Docker BenchforSecurityスクリプトによってフラグが立てられたすべての警告に対処しました。 これで、コンテナーを実行するためのより安全なDockerホストができました。

結論

このチュートリアルでは、Docker Bench for Securityスクリプトをインストールし、それを使用してDockerインストールのセキュリティを監査し、auditdとDockerデーモンの構成ファイルをインストールして構成することで警告に対処しました。

このチュートリアルを完了した後、監査スクリプトを実行すると、エラーや警告がほとんど発生しないはずです。また、持続するものを理解し、無視する十分な理由があるはずです。

Dockerセキュリティ構成オプションの詳細については、 Dockerドキュメントを参照し、このチュートリアル全体に含まれているドキュメントの特定のサブセクションへのリンクを確認してください。