LXCで学ぶコンテナ入門 -軽量仮想化環境を実現する技術

第12回 LXCの設定 [2]

この記事を読むのに必要な時間:およそ 9 分

今回は前回紹介できなかったセキュリティ,ネットワーク系の設定を説明していきたいと思います。

セキュリティ機能

ケーパビリティ

コンテナがrootで実行されている場合でも,コンテナ内では一部の特権を認めたくない場合はあるでしょう。このような場合,Linuxカーネルの持つケーパビリティの機能を使ってコンテナの特権を制御できます。

ケーパビリティはcapabilities(7)にあるようにCAP_SYS_MODULEというようなCAP_で始まる大文字で表されます。LXCではこの冒頭のCAP_を除いた文字列を小文字で指定します。たとえばCAP_SYS_MODULEの場合はsys_moduleと指定します。

ケーパビリティの指定は以下のどちらかで行います。各設定ともに,スペース区切りで一行に複数の値を指定できます。

lxc.cap.drop
コンテナ内で削除したいケーパビリティを指定します。
lxc.cap.keep
コンテナ内で保持したいケーパビリティを指定します。指定したケーパビリティ以外は全て削除されます。

lxc-createでコンテナを作成する際にincludeされる各ディストリビューションの標準設定ファイルでは,lxc.cap.dropでコンテナに与えると問題になることの多いケーパビリティを削除しています。たとえばUbuntuコンテナ用の設定ファイルでは以下のように設定されています。

lxc.cap.drop = sys_module mac_admin mac_override sys_time

セキュリティ系の機能とはいえ,コンテナを実用的に使えるようにしながら,ケーパビリティの指定でセキュリティを確保するのは難しいため,どちらかというとコンテナを運用する際に起こる問題を解消するためにケーパビリティを指定する方が多いでしょう。

AppArmor

ホストOSでAppArmorが利用できる環境では,コンテナで使うAppArmorプロファイルが指定できます。設定は使用したいプロファイルをlxc.aa_profileに指定するだけです。

lxc.aa_profile = lxc-container-default-with-mounting

ホストOS環境がUbuntuの場合,LXCパッケージをインストールするとAppArmor関連のファイルも同時にインストールされ,以下のプロファイルが使用できるようになります。

lxc-container-default
lxc.aa_profileでプロファイルを指定しない場合はこのプロファイルが使われます
lxc-container-default-with-nesting
lxc-container-defaultに,コンテナ内でコンテナを動作させる場合に必要な権限が追加されます
lxc-container-default-with-mounting
lxc-container-defaultに,ファイルシステムをマウントするための権限が追加されます
unconfined
デフォルトで指定されるlxc-container-defaultを無効にしたい場合に指定します

もちろん自分で作成した独自のプロファイルも使えます。

SELinux

ホストOSでSELinuxが利用できる環境では,AppArmorと同様にコンテナが使うSELinuxのコンテキストが指定できます。

lxc.se_context = system_u:system_r:lxc_t:s0:c62,c86,c150,c228

今のところ,多くのディストリビューションでSELinuxを有効にしてLXCのパッケージを作成しているようです。しかしコンテナに対してSELinuxを使うように設定しているディストリビューションは今のところないようです。

Seccomp

SeccompはLinuxカーネルに実装されている,実行できるシステムコールを設定できるフィルタリング機能です。

LXCではlxc.seccompにフィルタリングを記述したファイルを指定して利用します。1.0.5からlxc-createでコンテナを作成する際にincludeされる,各ディストリビューションの標準設定ファイルでLXCが標準で準備するフィルタリングが適用されるようになりました。

lxc.seccomp = /usr/share/lxc/config/common.seccomp

このcommon.seccompファイルは以下のような内容です。

2
blacklist
[all]
kexec_load errno 1
open_by_handle_at errno 1
init_module errno 1
finit_module errno 1
delete_module errno 1

このファイルの1行目はバージョン番号を表しており,現在は1か2が指定できます。

2行目はポリシーのタイプを指定します。

バージョン1の場合はSeccompのポリシーはホワイトリストのみとなるので,whitelistのみが指定できます。そして3行目以降に実行可能なシステムコールの番号を書きます。

たとえば以下のように書くと,コンテナ内では103番のシステムコール(syslog)のみが実行可能になります。

1whitelist
103

バージョン2の場合は先にあげたcommon.seccompのようにblacklistを指定して,ポリシーとしてブラックリストの指定ができます。

そしてアーキテクチャをブラケット"[]"で指定し,その後の行の一行にシステムコール名をテキストで書くとともに,そのシステムコールが呼ばれた際の処理を記述します。

先にあげたcommon.seccompの場合は,"[all]"で全てのアーキテクチャを指定し,システムコールのkexec_load, open_by_handle_at, init_module, finit_module, delete_moduleが呼ばれた場合は全てエラー番号1を返しています。

LXCのマニュアルにはこれ以上の情報がなく,アーキテクチャや処理として何が書けるかがわかりません。

LXCのソースコードを見る限り,以下が指定できるようです。

  • アーキテクチャ
    • all
    • x86
    • x86_64
    • arm
  • 処理
    • kill
    • errno
    • allow
    • trap

処理はlibseccompのマニュアルであるseccomp_rule_add(3)の説明で挙げられている有効なアクションに対応しているようです。カーネル付属文書のprctl/seccomp_filter.txtにも解説があります。

著者プロフィール

加藤泰文(かとうやすふみ)

2009年頃にLinuxカーネルのcgroup機能に興味を持って以来,Linuxのコンテナ関連の最新情報を追っかけたり,コンテナの勉強会を開いたりして勉強しています。英語力のない自分用にLXCのmanページを日本語訳していたところ,あっさり本家にマージされてしまい,それ以来日本語訳のパッチを送り続けています。

Plamo Linuxメンテナ。ファーストサーバ株式会社所属。

Twitter:@ten_forward
技術系のブログ:http://tenforward.hatenablog.com/

コメント

コメントの記入