TenForward

技術ブログ。はてなダイアリーから移転しました

LXDでコンテナごとに異なるユーザ権限でコンテナを起動する

$ lxc version
Client version: 3.0.1
Server version: 3.0.1

な環境の Ubuntu 18.04 上で試してます。

以下で何の前提もなく書いてるサブ ID のお話は、私の連載

に書いていますのでそちらをどうぞ。

LXD でコンテナを起動すると、デフォルトでは非特権コンテナが起動します。

$ lxc launch ubuntu:18.04 c1
Creating c1
Starting c1
$ lxc list
+------+---------+--------------------+-----------------------------------------------+------------+-----------+
| NAME |  STATE  |        IPV4        |                     IPV6                      |    TYPE    | SNAPSHOTS |
+------+---------+--------------------+-----------------------------------------------+------------+-----------+
| c1   | RUNNING | 10.56.2.183 (eth0) | fd42:dce3:4ae3:1cb3:216:3eff:fe25:e3c3 (eth0) | PERSISTENT | 0         |
+------+---------+--------------------+-----------------------------------------------+------------+-----------+

誰の権限で起動しているか確認してみます。

$ ps auxf
  : (snip)
root     13607  0.0  0.1 530556  7344 ?        Ss   13:31   0:00 [lxc monitor] /var/lib/lxd/containers c1
100000   13626  0.1  0.2 159436  8816 ?        Ss   13:31   0:00  \_ /sbin/init
  : (snip)

このように uid: 100000 のユーザで起動しています。

ここでもうひとつコンテナを起動します。

$ lxc launch ubuntu:18.04 c2
Creating c2
Starting c2
$ ps aux
  : (snip)
root     14507  0.0  0.1 529148  7264 ?        Ss   13:34   0:00 [lxc monitor] /var/lib/lxd/containers c2
100000   14532  1.4  0.2  77420  8660 ?        Ss   13:34   0:00 /sbin/init
  : (snip)

こちらも uid: 100000 のユーザで起動します。

このようにデフォルトでは同一ホスト上で起動するコンテナはすべて同じユーザ権限で起動します。マルチテナントで、コンテナごとにユーザが異なる場合、セキュリティを考えると異なるユーザ権限でコンテナが実行されている方が望ましいでしょう。

LXD ではこれを制御する設定 security.idmap.isolated があります。デフォルトではこれは false ですので、コンテナもしくはプロファイルで true としておくと、異なる uid/gid の範囲を使ってコンテナを起動します。

この辺りは、公式の userns-idmap あたりに詳しいです。

/etc/subuid, /etc/subgid の設定

デフォルトではコンテナには 65536 個の ID を割り当てるので、Ubuntu でユーザを登録すると、subuid/subgid として 65536 個の ID を使えるように設定されています(LXDはコンテナをrootユーザから起動するのでrootに対して)。

$ cat /etc/sub{u,g}id | grep root
root:100000:65536
root:100000:65536

十分なサブ ID が確保されていない場合、

Error: Failed container creation: Not enough uid/gid available for the container.

みたいなエラーでコンテナを作成できません。

コンテナごとに異なる ID の範囲を割り当てる場合、コンテナごとに 65536 必要ですから、sub{u,g}id でも必要な個数設定しておく必要があります。

とりあえずサブ ID はユーザごとに異なっている必要もありませんので、ケチケチ設定する必要もないので、適当に 200000 個くらい設定しましょう。(LXD がどういう計算しているかわからないけど、コンテナ 2 つ起動するから 131072 とか設定すると上記エラーが出ます)

$ cat /etc/sub{u,g}id | grep root
root:100000:200000
root:100000:200000

このあと、LXD を再起動しておきます。(サブ ID のマップを起動時に読み込むから)

$ sudo systemctl restart lxd

もう一つ気をつけること。ドキュメントにも書かれていないと思います。この辺りで発言があります。

/etc/sub{u,g}id に設定する ID の個数ですが、設定した最初の 65536 個(security.idmap.sizeの設定)は security.idmap.isolated を設定していないコンテナ専用です。

つまり先の例のように設定した場合、100000 〜 165535 までの ID は security.idmap.isolated を設定していないコンテナが使いますので、security.idmap.isolated を設定したコンテナを起動したい場合は、さらに 65536 個の ID が必要です。

ですので、ID の個数として /etc/sub{u,g}id に 65536 を設定してある環境で、ひとつもコンテナが起動していないところに、security.idmap.isolated を設定したコンテナを起動しようとしても失敗します。

少なくとも 131073 以上の設定が必要です。まあ、ケチることはないので先の例のように多めに確保しておきましょう。

profile の設定

default プロファイルの設定を変えてもいいですが、同じ ID 範囲で起動するコンテナを起動したい場合のためにそれは置いておいて、新しいプロファイルを作ります。

$ lxc profile copy default secure
$ lxc profile set secure security.idmap.isolated true
$ lxc profile show secure
config:
  security.idmap.isolated: "true"
  : (snip)

コンテナの起動

$ lxc launch ubuntu:18.04 c1 --profile=secure
Creating c1
Starting c1
$ lxc launch ubuntu:18.04 c2 --profile=secure
Creating c2
Starting c2
$ ps aux
  : (snip)
root     17072  0.0  0.1 604544  7324 ?        Ss   14:03   0:00 [lxc monitor] /var/lib/lxd/containers c1
165536   17093  0.2  0.2 159472  8892 ?        Ss   14:03   0:00  \_ /sbin/init
  : (snip)
root     17935  0.0  0.1 529148  7196 ?        Ss   14:03   0:00 [lxc monitor] /var/lib/lxd/containers c2
231072   17953  0.2  0.2 159420  8840 ?        Ss   14:03   0:00  \_ /sbin/init
  : (snip)

はい、違うユーザ権限で起動していますね。