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

LXCは単に仮想環境を構築するためだけでなく、権限を分離してセキュリティを高めるという目的にも利用可能だ。前回はLXCの基本について紹介したが、今回はLXCを使用した権限分離の例や、テンプレートをカスタマイズする例を紹介する。
LXCを利用した権限の分離
LXCにはさまざまなLinuxディストリビューション環境を構築するためのテンプレートが用意されているため、仮想環境を構築するためのツールという認識を持っている人も少なくないだろう。しかし、LXCの核となっているのはLinux上のさまざまなリソースを管理する機能であるcgroupsであり、これを利用した権限の分離にLXCを利用することも可能だ。
たとえば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が停止さされてしまうため注意したい。