今回は前回紹介できなかったセキュリティ、
セキュリティ機能
ケーパビリティ
コンテナがrootで実行されている場合でも、
ケーパビリティはcapabilities(7)にあるようにCAP_
というようなCAP_
で始まる大文字で表されます。LXCではこの冒頭のCAP_
を除いた文字列を小文字で指定します。たとえばCAP_
の場合はsys_
と指定します。
ケーパビリティの指定は以下のどちらかで行います。各設定ともに、
- lxc.
cap. drop - コンテナ内で削除したいケーパビリティを指定します。
- lxc.
cap. keep - コンテナ内で保持したいケーパビリティを指定します。指定したケーパビリティ以外は全て削除されます。
lxc-create
でコンテナを作成する際にincludeされる各ディストリビューションの標準設定ファイルでは、lxc.
でコンテナに与えると問題になることの多いケーパビリティを削除しています。たとえばUbuntuコンテナ用の設定ファイルでは以下のように設定されています。
lxc.cap.drop = sys_module mac_admin mac_override sys_time
セキュリティ系の機能とはいえ、
AppArmor
ホストOSでAppArmorが利用できる環境では、lxc.
に指定するだけです。
lxc.aa_profile = lxc-container-default-with-mounting
ホストOS環境がUbuntuの場合、
- 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が利用できる環境では、
lxc.se_context = system_u:system_r:lxc_t:s0:c62,c86,c150,c228
今のところ、
Seccomp
SeccompはLinuxカーネルに実装されている、
LXCではlxc.
にフィルタリングを記述したファイルを指定して利用します。1.lxc-create
でコンテナを作成する際にincludeされる、
lxc.seccomp = /usr/share/lxc/config/common.seccomp
このcommon.
ファイルは以下のような内容です。
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行目はバージョン番号を表しており、
2行目はポリシーのタイプを指定します。
バージョン1の場合はSeccompのポリシーはホワイトリストのみとなるので、whitelist
のみが指定できます。そして3行目以降に実行可能なシステムコールの番号を書きます。
たとえば以下のように書くと、
1whitelist
103
バージョン2の場合は先にあげたcommon.
のようにblacklist
を指定して、
そしてアーキテクチャをブラケット"[]"で指定し、
先にあげたcommon.
の場合は、[all]
"で全てのアーキテクチャを指定し、kexec_
, open_
, init_
, finit_
, delete_
が呼ばれた場合は全てエラー番号1を返しています。
LXCのマニュアルにはこれ以上の情報がなく、
LXCのソースコードを見る限り、
-
アーキテクチャ
- all
- x86
- x86_
64 - arm
-
処理
- kill
- errno
- allow
- trap
処理はlibseccompのマニュアルであるseccomp_
ネットワーク
LXCのネットワーク設定の基本的な設定項目を説明した後、
インターフェースの指定 ~lxc.network.link
コンテナにはホストの物理的なインターフェースを割り当てることもできますし、
このときにコンテナが使うホスト上のインターフェースを指定します。
lxc.network.link = eth0
このように設定すると、
UbuntuのLXCパッケージの/etc/
では以下のように設定されており、lxcbr0
に接続されます。
lxc.network.link = lxcbr0
コンテナ起動時のインターフェースの動作 ~lxc.network.flags
lxc.
にup
と指定すると、
lxc.network.flags = up
コンテナでネットワークを使う場合は通常行う設定ですね。
仮想インターフェースのMACアドレス ~lxc.network.hwaddr
コンテナに仮想インターフェースを割り当てる際の、
lxc.network.hwaddr = 00:16:3e:d0:e3:9d
このように設定するとそのままの値が設定されますし、x
という文字を使うとその部分はランダムな値となります。
lxc.network.hwaddr = 00:16:3e:xx:xx:xx
UbuntuのLXCパッケージの/etc/
には以上のようなx
を使った値が設定されています。これを使うとテンプレートにMACアドレスを指定して、
ネットワークタイプの設定 ~lxc.network.type
コンテナに対して設定するネットワークインターフェースのタイプをlxc.
で設定します。この設定には以下の6つの値が設定できます。
none
この値を設定するとコンテナ用に新しいネットワーク名前空間を作成しません。つまりホストのネットワークをそのまま使います。
ただしシステムコンテナの場合で、
アプリケーションコンテナでホストのネットワークインターフェースを使いたいような場合に使えるでしょう。
empty
コンテナ内にループバックインターフェースのみを作成します。
lxc.network.type = empty
lxc.network.flags = up
以上のように設定して起動したコンテナ内のネットワークインターフェースは以下のようにloのみとなります。
# lxc-attach -n ct01 -- ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
veth
第6回で紹介したvethを使ってペアのインターフェースを作り、
vethペアのホスト側のインターフェース名は自動的に付与されます。lxc.
を使うと、
UbuntuでLXCパッケージを入れてデフォルトのまま使用するとコンテナは以下のように設定されます。
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = lxcbr0
lxc.network.hwaddr = 00:16:3e:d0:e3:9d
lxc.
は/etc/
で
lxc.network.hwaddr = 00:16:3e:xx:xx:xx
と設定されており、lxc-create
時に"x"が置き換えられます。
このように設定してコンテナを起動すると、
# lxc-attach -n ct01 -- ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 8: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 00:16:3e:d0:e3:9d brd ff:ff:ff:ff:ff:ff
このとき、
# ip link show :(略) 9: vethA50BP0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master lxcbr0 state UP mode DEFAULT group default qlen 1000 link/ether fe:08:b1:76:81:63 brd ff:ff:ff:ff:ff:ff
ここでlxc.
を使って名前を指定してみます。
lxc.network.veth.pair = veth_gihyo
# ip link show :(略) 13: veth_gihyo: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master lxcbr0 state UP mode DEFAULT group default qlen 1000 link/ether fe:79:92:23:dc:35 brd ff:ff:ff:ff:ff:ff
以上のように指定した名前でホスト側のvethインターフェースが作成されています。
macvlan
第6回で紹介したmacvlanインターフェースをlxc.
に指定したネットワークインターフェースに作成し、
第6回で説明したようにmacvlanにはモードが存在しますので、lxc.
で指定します。
macvlanのモードを使った実例はあとで紹介します。
vlan
Linuxカーネルの持つVLANを扱う機能を使い、lxc.
で指定されたネットワークインターフェース上にVLANインターフェースを作成し、
タグVLANのIDはlxc.
で指定します。
phys
lxc.
で指定したネットワークインターフェースを直接コンテナに割り当てます。指定したインターフェースはコンテナのネットワーク名前空間に割り当てられますので、
ホスト上や他のコンテナで使っていないネットワークインターフェースの場合に指定できます。
コンテナのIPアドレスの指定
システムコンテナを起動する場合は、/etc/
や、/etc/
以下の設定ファイルなどで、
しかし、
このような場合はコンテナの設定ファイルにアドレスの指定を行います。
たとえば、
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = lxcbr0
lxc.network.hwaddr = 00:16:3e:fb:c0:12
lxc.network.ipv4 = 10.0.3.200/24 10.0.3.255
lxc.network.ipv4.gateway = 10.0.3.1
以上のようにlxc.
で"アドレス/ネットマスク"とブロードキャストアドレスをスペース区切りで指定し、lxc.
でゲートウェイのアドレスを指定します。
lxc.
には"auto"という値も設定できます。このときは、lxc.
で指定したインターフェースの最初のアドレスを使います。
この設定を行って、
# lxc-execute -n apache01 -- /usr/sbin/apache2ctl start & # lxc-ls --fancy NAME STATE IPV4 IPV6 AUTOSTART ---------------------------------------------- apache01 RUNNING 10.0.3.200 - NO # curl -I http://10.0.3.200/ HTTP/1.1 200 OK Date: Tue, 14 Oct 2014 08:16:18 GMT Server: Apache/2.4.7 (Ubuntu) Last-Modified: Tue, 02 Sep 2014 11:11:28 GMT ETag: "2cf6-502132e500350" Accept-Ranges: bytes Content-Length: 11510 Vary: Accept-Encoding Content-Type: text/html
以上のようにlxc.
で設定した10.
ここで紹介したIPv4の例と同様にlxc.
, lxc.
でIPv6のアドレスも設定できます。
macvlanを使ったコンテナ
第6回でmacvlanの各モードについて説明をしました。そのときはそれぞれのモードを実際に設定したときにどのような動きになるかの紹介はしませんでしたので、
第6回で説明した通り、
macvlanをコンテナで使用するには先に説明した通り、lxc.
でmacvlan
を指定します。
では、
ここの例では、
$ ip -4 addr show eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 192.168.122.26/24 brd 192.168.122.255 scope global eth0 valid_lft forever preferred_lft forever
コンテナの設定は以下のようになります。
lxc.network.type = macvlan
lxc.network.flags = up
lxc.network.link = eth0
ではコンテナを起動してみましょう。
$ sudo lxc-start -n ct01 -d $ sudo lxc-ls --fancy NAME STATE IPV4 IPV6 AUTOSTART ----------------------------------------------- ct01 RUNNING 192.168.122.224 - NO
ご覧のように、
$ sudo lxc-attach -n ct01 -- ip -4 addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
5: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
inet 192.168.122.224/24 brd 192.168.122.255 scope global eth0
valid_lft forever preferred_lft forever
$ sudo lxc-attach -n ct01 -- ip route (ルーティングテーブルの確認)
default via 192.168.122.1 dev eth0
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.224
確かに192.
$ sudo lxc-attach -n ct01 -- ping -c 1 192.168.122.1 (デフォルトゲートウェイへの疎通確認) PING 192.168.122.1 (192.168.122.1) 56(84) bytes of data. 64 bytes from 192.168.122.1: icmp_seq=1 ttl=64 time=0.207 ms : (略) $ sudo lxc-attach -n ct01 -- curl -I http://gihyo.jp/ (外部のWebサーバにアクセス) HTTP/1.1 200 OK Server: nginx Date: Wed, 15 Oct 2014 11:26:08 GMT : (略)
コンテナから外部への通信も問題なく行えています。
第6回のmacvlanの説明では、
privateモード
先ほどの例の環境でもう1つコンテナを起動してみましょう。ネットワークの設定を、lxc.
以外は同じにしたct02
という名前のコンテナを起動してみます。
$ sudo lxc-ls --fancy NAME STATE IPV4 IPV6 AUTOSTART ----------------------------------------------- ct01 RUNNING 192.168.122.224 - NO ct02 RUNNING 192.168.122.9 - NO
お互いに向けてpingを実行します。
$ sudo lxc-attach -n ct01 -- ping 192.168.122.9 (ct01からct02に向けてping) PING 192.168.122.9 (192.168.122.9) 56(84) bytes of data. From 192.168.122.224 icmp_seq=1 Destination Host Unreachable :(略) $ sudo lxc-attach -n ct02 -- ping 192.168.122.224 (ct02からct01に向けてping) PING 192.168.122.224 (192.168.122.224) 56(84) bytes of data. From 192.168.122.9 icmp_seq=1 Destination Host Unreachable :(略)
お互いに通信ができません。そうです、
ここで起動した2つのコンテナct01
とct02
は両方ともprivateモードに設定されているのです。lxc.
でmacvlan
を指定した場合のデフォルトのモードはprivateとなります。
もちろん、
lxc.network.macvlan.mode = private
第6回で説明したように、
$ sudo lxc-attach -n ct01 -- ping 192.168.122.26 (ct01からホストに向けてping) PING 192.168.122.26 (192.168.122.26) 56(84) bytes of data. From 192.168.122.9 icmp_seq=1 Destination Host Unreachable :(略) $ sudo lxc-attach -n ct02 -- ping 192.168.122.26 (ct02からホストに向けてping) PING 192.168.122.26 (192.168.122.26) 56(84) bytes of data. From 192.168.122.224 icmp_seq=1 Destination Host Unreachable :(略)
bridgeモード
ホストOS上の同じインターフェースに属するmacvlanインターフェースを持つコンテナ同士の通信を行いたい場合はbridgeモードに設定します。
lxc.network.macvlan.mode = bridge
上記の設定を行ってコンテナを起動します。
$ sudo lxc-ls --fancy NAME STATE IPV4 IPV6 AUTOSTART ----------------------------------------------- ct01 RUNNING 192.168.122.224 - NO ct02 RUNNING 192.168.122.9 - NO
pingを実行してみましょう。
$ sudo lxc-attach -n ct01 -- ping 192.168.122.9 (ct01からct02に向けてping) PING 192.168.122.9 (192.168.122.9) 56(84) bytes of data. 64 bytes from 192.168.122.9: icmp_seq=1 ttl=64 time=0.102 ms :(略) $ sudo lxc-attach -n ct02 -- ping 192.168.122.224 (ct02からct01に向けてping) PING 192.168.122.224 (192.168.122.224) 56(84) bytes of data. 64 bytes from 192.168.122.224: icmp_seq=1 ttl=64 time=0.054 ms :(略) $ sudo lxc-attach -n ct01 -- ping 192.168.122.26 (ct01からホストに向けてping) PING 192.168.122.26 (192.168.122.26) 56(84) bytes of data. From 192.168.122.224 icmp_seq=1 Destination Host Unreachable :(略) $ sudo lxc-attach -n ct02 -- ping 192.168.122.26 (ct02からホストに向けてping) PING 192.168.122.26 (192.168.122.26) 56(84) bytes of data. From 192.168.122.9 icmp_seq=1 Destination Host Unreachable :(略)
以上のようにct01
とct02
の間で通信ができます。各コンテナとホスト間の通信はprivateモードと同じくできません。
複数のネットワークインターフェースの割り当て
コンテナには複数のネットワークインターフェースを割り当てることができます。
ホストOSにlxcbr0
eth0
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = lxcbr0
lxc.network.hwaddr = 00:16:3e:25:09:xx
lxc.network.type = macvlan
lxc.network.flags = up
lxc.network.link = eth0
lxc.network.hwaddr = 00:16:3e:25:09:xx
複数のインターフェースを定義する場合は、
コンテナ内にも複数のインターフェースが起動するような設定を行います。ここではct01
はUbuntuコンテナでしたので、/var/
/etc/
)
auto eth1
iface eth1 inet dhcp
そしてコンテナを起動すると、
$ sudo lxc-start -n ct01 -d $ sudo lxc-ls --fancy NAME STATE IPV4 IPV6 AUTOSTART ----------------------------------------------------------- ct01 RUNNING 10.0.3.127, 192.168.122.247 - NO ct02 STOPPED - - NO
図で示すと図1のようになります。コンテナ用の隔離したネットワークを構成したりするのに使えますね。

コンテナ内でインターフェースの情報を見ると以下のようになります。設定ファイルに書いた順にeth0
がvethインターフェース、eth1
がmacvlanインターフェースになっています。
$ sudo lxc-attach -n ct01 -- ip -4 addr show :(略) 18: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 10.0.3.127/24 brd 10.0.3.255 scope global eth0 valid_lft forever preferred_lft forever 20: eth1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default inet 192.168.122.247/24 brd 192.168.122.255 scope global eth1 valid_lft forever preferred_lft forever
まとめ
今回はセキュリティとネットワークに関する主な設定を紹介し、
ネットワーク関係の設定で紹介できていない設定項目についてはman lxc.
をご参照ください。
前回と今回でLXCでコンテナを起動する際の基本的な設定を紹介しました。もう少し進んだ使いかたをする際の設定については、
さて、
次回は筆者と同じくPlamo Linuxのメンテナをつとめており、
その後も田向さんにRPM系の代表的なディストリビューションであるFedoraでのLXCの使いかたの紹介をしていただく予定です。
お楽しみに。