Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

第6章 Docker SELinux セキュリティーポリシー

Docker SELinux セキュリティーポリシーは libvirt セキュリティーポリシーに類似しており、libvirt セキュリティーポリシーに基づいています。

libvirt セキュリティーポリシーは、仮想マシンを分離するための 2 つの方法を定義した一連の SELinux ポリシーです。通常、仮想マシンはネットワークの特定の部分にアクセスできないようにされます。具体的には、個々の仮想マシンは相互のリソースへのアクセスが拒否されます。Red Hat は libvirt-SELinux モデルを Docker に拡張しています。Docker の SELinux ロールおよび Docker の SELinux タイプは libvirt に基づいています。たとえば、デフォルトで Docker は /usr/var/ およびその他の場所にアクセスできますが、svirt_sandbox_file_t でラベル付けされたものには完全なアクセスがあります。

https://www.mankier.com/8/docker_selinux: Docker の SELinux ポリシー全体について説明しています。これは専門用語を使って説明されており、詳細情報が記載されています。

svirt_sandbox_file_t

system_u:system_r:svirt_lxc_net_t:s0:c186,c641
^      ^           ^          ^     ^--- unique category
|      |           |          |----  secret-level 0
|      |           |--- a shared type
|      |---SELinux role
|------ SELinux user

ファイルに "svirt_sandbox_file_t" のラベルが付けられると、デフォルトですべてのコンテナーがこのファイルを読み取ることができます。ただし、これらのコンテナーが "svirt_sandbox_file_t" 所有権を持つディレクトリーに書き込む場合、独自のカテゴリー (この場合は "c186,c641) を使用して書き込みを実行します。同じコンテナーを 2 回起動すると、2 回目には新たなカテゴリー (初回のカテゴリーとは異なるカテゴリー) が取得されます。このカテゴリーシステムにより、コンテナーは相互に分離されます。

各種のタイプはプロセスおよびファイルに適用できます。

6.1. libvirt SELinux

libvirt SELinux: RH は Docker 用に libvirt SELinux を拡張しています。libvirt SELinux の Docker への拡張は、そのほぼすべてが RH によって提供された機能です。

6.2. MCS (マルチカテゴリーセキュリティー)

MCS (マルチカテゴリーセキュリティー): これはマルチレベル認証に似ています。各コンテナーには起動時に固有 ID が付与され、コンテナーが書き込む各ファイルにはその固有 ID が継承されます。コンテナーのファイルは、いわばコンテナーの DNA から逃れることができません。これはオプトインシステムですが、その使用は得策と言えます。この機能を使用しないと、コンテナー間を分離することができません。コンテナーとホスト間の分離は、この機能の使用にかかわらず可能ですが、コンテナーを相互に分離することはできません。つまり、(MCS を使用しない場合は) あるコンテナーが別のコンテナーのファイルにアクセスできる可能性があります。

https://securityblog.redhat.com/2015/04/29/container-security-just-the-good-parts/: この情報は、後に MCS に組み込む MCS サンプルを構築する際に使用します。

6.3. Docker SELinux セキュリティーモデルの活用

コンテンツの適切なラベル付け: デフォルトでは Docker は /usr のすべて、および /etc のほとんどにアクセスできます。これ以上のアクセスを付与する必要がある場合は、ホスト上のコンテンツを再度ラベル付けする必要があります。/usr や /etc にあるものへのアクセスを制限する必要がある場合も、アクセスを制限するコンテンツを再度ラベル付けする必要があります。なお 1 つまたは 2 つのコンテナーのみにアクセスを制限する場合は、オプトインの mcs システムを使用する必要があります。

重要なブール値およびその他の制限: Docker における「特権」は実際の特権を意味するものではありません。特権付きの Docker プロセスも任意のソケットファイルにアクセスできません。selinux ブール値の docker_connect_any を使用すると、特権付きの Docker プロセスは任意のソケットファイルにアクセスできます。Docker は特権付きで実行されている場合でも、有効なブール値によって制限されます。

docker_connect_any: 上記の『重要なブール値およびその他の制限』を参照してください。

https://github.com/rhatdan/docker-selinux: dwalsh の github リポジトリーです。この機能はユーザーが利用できるように man ページに記載する必要があります。

カーネル機能の制限: Docker は "docker run" の一部として (1) "--cap-add=" と (2) "--cap-drop=" の 2 つのコマンドをサポートします。これらにより、カーネル機能をコンテナーに追加したり、コンテナーからドロップしたりできます。root 権限は数多くの機能グループに分割されます (ファイルの所有権を変更する "cap-chown" など)。デフォルトの Docker 機能一覧は非常に限られています。

http://linuxmanpages.net/manpages/fedora21/man7/capabilities.7.html: この情報は機能の詳細情報を必要とするユーザー向けです。これらの機能はすべてコンテナーの分離に関連するものです。これらの機能を適切な方法 (本書で説明されている方法) で使用するなら、システムにカーネルの脆弱性がない限り、攻撃者はシステム上で root アクセスを利用することはできません。すべての機能をドロップする場合、root は権限がない状態となり、機能をオフにして無効にした root アカウントを所有する攻撃者は何の影響も与えることはできず、保護対象外のものしか操作できません。

seccomp によるカーネル呼び出しの制限

http://man7.org/linux/man-pages/man2/syscalls.2.html: これは期待を起こさせる機能です。seccomp は各種の機能よりも詳細化されています。この機能を使用すると、コンテナーが実行する実際のカーネル呼び出しを制限することができます。これは、(たとえば) コンテナーが "cd" を呼び出すことを防ぐことができるため、一般的なセキュリティー上の理由からも期待できる機能であると言えます。ほとんどすべてのカーネルの不正利用は、カーネル呼び出しに伴って生じます (カーネルのほとんど使用されていない部分に対して実行されるのが通例)。seccomp を使用すると数多くのカーネル呼び出しをドロップでき、ドロップされたカーネル呼び出しは攻撃ベクトルとして悪用できません。

Docker ネットワークセキュリティーおよびルーティング: デフォルトで、Docker は各コンテナーの仮想イーサネットカードを作成します。各コンテナーには独自のルーティングテーブルと iptables があります。このほかにも、特定ポートの転送を要求する場合に Docker は特定のホストの iptables ルールを作成します。Docker デーモンは自らプロキシー機能の一部を実行します。アプリケーションをコンテナーにマップすると、アプリケーションごとにネットワークアクセスを制限できるため、柔軟性を確保することができます。

シナリオ: 特定の種類のインターネットトラフィックを他のインターネットトラフィックから分離するにはコンテナー化されたファイアウォールを使用します。読者の演習例として、特定の種類のトラフィックを正式なネットワークから分離するシナリオを想定することができるかもしれません (配偶者または雇用者の監視下に置かれるトラフィックなど)。

cgroup: これはコントロールグループのことです。これらは Docker の実行内容において中心的な役割を担っています。元々 cgroup は cpu などのリソースに対してのみアクセスを制御するものでした。プロセスを cgroup に入れてからカーネルに対して「その cgroup には cpu の最大 10 パーセントを割り当てる」ように指示できます。これは一種の SLA またはクォータの提供方法です。デフォルトで、Docker は各コンテナーに固有の cgroup を作成します。Docker デーモンホストに既存の cgroup ポリシーがある場合は、その既存の cgroup ポリシーを使用して指定コンテナーのリソース消費を制御できます。

コンテナーのフリーズおよびフリーズ解除: ある時点の状態にあるコンテナーをフリーズし、その時点からコンテナーを再起動することができます (コンテナーの cpu を 0% に指定すると効果的に実行できます)。cgroup は Docker が DDoS 攻撃に対して提供する保護機能になります。マシン上でサービスをホストし、このサービスに cgroup の優先順位を指定できます。これにより、サービスの cpu パーセントが10% を割らないようにし、かつ他のサービスがセキュリティー侵害の危険にさらされても、それらのサービスが最低 10% の cpu レベルを維持するこのサービスに影響を与えないようにします。そのため、必須のプロセスがどのような悪意ある方法で攻撃されたとしても、それらのプロセスが cpu の一部を制御できなくなる状況を避けることができます。/sys/fs/cgroup は仮想ファイルシステムです。デフォルトでは、コンテナーは /sys/fs/cgroup にアクセスできません。