LXCを使った権限分離とテンプレートのカスタマイズ

図3 cgroupsによるリソースのグルーピング

 LXCは単に仮想環境を構築するためだけでなく、権限を分離してセキュリティを高めるという目的にも利用可能だ。前回はLXCの基本について紹介したが、今回はLXCを使用した権限分離の例や、テンプレートをカスタマイズする例を紹介する。

LXCを利用した権限の分離

 LXCにはさまざまなLinuxディストリビューション環境を構築するためのテンプレートが用意されているため、仮想環境を構築するためのツールという認識を持っている人も少なくないだろう。しかし、LXCの核となっているのはLinux上のさまざまなリソースを管理する機能であるcgroupsであり、これを利用した権限の分離にLXCを利用することも可能だ。

図1 cgroupsによるリソースのグルーピング
図1 cgroupsによるリソースのグルーピング

 たとえばLXCに含まれている「lxc-sshd」テンプレートでは、ホストと同一の環境をベースに制限された権限でsshdを実行させる環境を構築できる。

lxc-sshdテンプレートを使う

 lxc-sshdテンプレート(以下、sshdテンプレート)は、以下のような環境を持つコンテナを作成するテンプレートだ。

  • コンテナ内の/libや/bin、/usr、/sbin、/etc/sysconfig/network-scripts、/etc/rc.dといったディレクトリはホストのものをそのままリードオンリーでマウントして使用する
  • /etcや/root、/var、/homeなどは独自に作成したものを使用する
  • 初期状態のコンテナ内ではsshとinit、dhclientのみが稼動している

 sshdテンプレートで作成されたコンテナのファイルシステムは、/homeや/etcなど一部を除き、そのままホストのファイルシステムが用いられる。つまり、ホストとほぼ同じ環境がコンテナ内で利用可能となる。また、ホストと共有しているディレクトリについてはリードオンリーになっているため、基本的にはコンテナ内部から変更できない。こういった特性から、このコンテナは外部に公開するSSHサーバーを構築する際に、権限を分離するために利用できる。さらに、このコンテナのテンプレートファイル(/usr/share/lxc/templates/lxc-sshd)はシンプルなものになっており、これをベースにカスタマイズを行うことで権限分離を行った独自のサーバー向けテンプレートを作成できる。

sshdテンプレートを使ったコンテナの作成

 それでは、実際にsshdテンプレートを使ってコンテナを作成する例を見てみよう。なお、以下ではホスト環境としてCentOS 6.5を使用している。ほかのディストリビューションを利用している場合でも同様の手順で再現できると思われるが、パッケージ名やツール名などが異なる場合があるのでそちらについては適宜読み替えて欲しい。

 なお、LXCバージョン1.0.0~1.0.3に含まれるsshdテンプレートにはバグがあり、そのままではコンテナを作成できない。LXC 1.0では一部コマンドがリネームされているのだが、それが反映されていないためだ。LXC 1.0.4以降を利用するか、もしくはsshdテンプレートファイル(/usr/share/lxc/templates/lxc-sshd)内の「/usr/libexec/lxc/lxc-init」という部分をすべて「/usr/sbin/init.lxc」に置き換えることで対処できる。

 さて、sshdテンプレートでは、テンプレート固有のオプションとしてコンテナ内でのrootユーザーがSSH経由でログインする際に使用するSSH公開鍵を指定する「-S」オプションが用意されており、コンテナの作成時にこのオプションで使用するSSH公開鍵を指定する。このようなコンテナ固有のオプションは、「--」オプションの後に指定する形となる。

 次の例は、「sshd01」という名前のコンテナを作成し、使用する公開鍵として「~hylom/.ssh/id_rsa.pub」を指定する場合の実行例だ。

# lxc-create -n sshd01 -t sshd -- -S ~hylom/.ssh/id_rsa.pub 
Generating public/private rsa key pair.
Your identification has been saved in /var/lib/lxc/sshd01/rootfs/etc/ssh/ssh_host_rsa_key.
Your public key has been saved in /var/lib/lxc/sshd01/rootfs/etc/ssh/ssh_host_rsa_key.pub.
The key fingerprint is:
70:87:8b:55:a9:09:d2:ce:45:ab:01:be:8d:7b:d3:8c root@fedora20.localdomain
The key's randomart image is:
+--[ RSA 2048]----+
|    .. .. ..     |
|   ...o .+.      |
|    .+oo=o.      |
|     +oBoo       |
|    o + S        |
|     . +         |
|    . E o        |
|     . .         |
|                 |
+-----------------+
Generating public/private dsa key pair.
Your identification has been saved in /var/lib/lxc/sshd01/rootfs/etc/ssh/ssh_host_dsa_key.
Your public key has been saved in /var/lib/lxc/sshd01/rootfs/etc/ssh/ssh_host_dsa_key.pub.
The key fingerprint is:
f2:42:87:b6:ed:1f:0b:28:85:d7:b0:51:1b:c1:8a:86 root@fedora20.localdomain
The key's randomart image is:
+--[ DSA 1024]----+
|       .+.       |
|       ..o       |
|   . .o..        |
|  E o..*         |
|   .. O S        |
|     = B         |
|    . + + .      |
|     . o . o     |
|        ..o      |
+-----------------+
Inserted SSH public key from /home/hylom/.ssh/id_rsa.pub into /var/lib/lxc/sshd01/rootfs//root/.ssh

 作成したコンテナはlxc-startコマンドで起動できる。以下では「-d」オプションを使用してバックグラウンドでコンテナを起動し、「-L」オプションでコンソールの出力先を「sshd01_log」というファイルに設定している。

# lxc-start -n sshd01 -d -L sshd01_log

 コンテナの起動後にこのログファイルを確認すると、コンテナのIPアドレスが表示されているはずだ。この場合、「192.168.122.10」がそのIPアドレスとなる。

# cat sshd01_log 
Container IP address:
        inet 192.168.122.10  netmask 255.255.255.0  broadcast 192.168.122.255
        inet6 fe80::78dc:2eff:fe25:3f3d  prefixlen 64  scopeid 0x20<link>

 コンテナにログインするには、コンテナの作成時に登録したSSH鍵を使ってこのIPアドレスに対しSSH接続すれば良い。

$ ssh root@192.168.122.10
The authenticity of host '192.168.122.10 (192.168.122.10)' can't be established.
RSA key fingerprint is 70:87:8b:55:a9:09:d2:ce:45:ab:01:be:8d:7b:d3:8c.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.122.10' (RSA) to the list of known hosts.
Enter passphrase for key '/home/hylom/.ssh/id_rsa': 
-bash-4.2# 

 ログイン後、psコマンドで実行されているプロセスを確認すると、initおよび最小限のプロセスしかコンテナ内では実行されていないことが確認できる。

# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  15116   732 ?        S    13:39   0:00 /usr/sbin/init.
root       100  0.0  1.2 106604 12816 ?        Ss   13:40   0:00 dhclient eth0 -
root       104  0.0  0.1  87176  1320 ?        Ss   13:40   0:00 /usr/sbin/sshd
root       105  0.0  0.4  91808  4328 ?        Ss   13:44   0:00 sshd: root@pts/
root       107  0.0  0.1  17928  1704 pts/0    Ss   13:44   0:00 -bash
root       108  0.0  0.1  26072  1280 pts/0    R+   13:44   0:00 ps aux

 コンテナを停止させるには、lxc-stopコマンドを利用する。

$ lxc-stop -n sshd01 -k

 なお、「-k」オプションはコンテナ内で実行されているプロセスをすべてkillするという意味のオプションだ。ちなみに、コンテナ内でshutdownコマンドを実行すると、ホストOSが停止さされてしまうため注意したい。