LXC(lxc-utils)でのGUI環境のセットアップを扱った前回の記事では最後のほうでIncusも使ってみました。その際、特定ユーザーに制限されたプロジェクトを作成する機能がよくわからず詰まったことがあったので、短いですが学んだことを書いておきます。
公式ドキュメントとしては以下の2つを参照してください。
特定のユーザーにプロジェクトを制限するには - Incus ドキュメント
筆者が使ったのはIncusだけですが、フォーク元であるLXDに関しても大体同じ動作なのではないかと思います。
incus-admin vs incus
Incusを使うにあたっては、使うユーザーをincus-adminというグループに追加することでrootに昇格しなくてもincusの操作を全て行うことができます。実質rootと同等の能力があります。
このincus-adminとは別にincusというグループもあって、こちらはincus-adminより権限が弱いのですがある程度の操作ができるようになる、とだけドキュメントには書いてあります。
- LXDの場合はこの"incus"にあたるグループ名が固定されておらず、sudo snap set lxd daemon.user.group=<user_group>で設定したものになります(参照)(このコマンドはグループの作成後に実行すること)。
が、このincusグループの機能が、今回紹介する"User restricted project"と密接に絡んでいてちょっとわかりづらいです。
"User restricted project"が作成されるタイミング
"User restricted project"というのが正式に確立された用語なのかよくわからないんですが、とりあえずそう表示されることがあるのでそう書いています。
これに関して、最初に上げた参考リンクの1つ目の最後のほうにこんなことが書いてあります。
Incus は特定のユーザーグループ内のすべてのユーザーのために動的にプロジェクトを作成するように設定できます。 これは通常
incusグループのメンバーだがincus-adminグループのメンバーではないユーザーを作ることで実現されます。Incus を使うユーザーアカウントはすべてこのグループのメンバーであるようにしてください。
グループのメンバーが Incus コマンドを発行すると、Incus はこのユーザーのために制限されたプロジェクトを作成し、このプロジェクトに切り替えます。 この時点で Incus が初期化されていない場合、自動的に初期化されます(デフォルト設定で)。
つまり、incusグループに所属していてかつincus-adminに所属していないユーザーがincusコマンド(具体的にはおそらくincus project listなど実質的にincusを使用することになるコマンド)を実行すると、そのタイミングで自動的にそのユーザー専用のプロジェクトが作成されるということです。
このとき、(筆者の知る限り少なくとも)以下のことが実行されます。
- user-XXXX(XXXXは該当ユーザーのUID)という名前のプロジェクトが新たに作成される
- 該当ユーザーがuser-XXXXを使えるように何らかの設定が行われる
- incusbr-XXXX(XXXXは該当ユーザーのUID)という名前のネットワークインターフェースが作成される
多分、上記の「user-」とか「incusbr-」の部分は固定されていて変えられないと思います。
incus project listなどでの表示
実際にこのように自動作成されたプロジェクトを表示するためrootでincus project listを実行すると以下のようになります。(今回はユーザー名がlxder、UIDが1003です)
+-------------------+--------+----------+-----------------+-----------------+----------+---------------+--------------------------------------------+---------+
| NAME | IMAGES | PROFILES | STORAGE VOLUMES | STORAGE BUCKETS | NETWORKS | NETWORK ZONES | DESCRIPTION | USED BY |
+-------------------+--------+----------+-----------------+-----------------+----------+---------------+--------------------------------------------+---------+
| default (current) | YES | YES | YES | YES | YES | YES | Default Incus project | 6 |
+-------------------+--------+----------+-----------------+-----------------+----------+---------------+--------------------------------------------+---------+
| user-1003 | YES | YES | YES | YES | NO | YES | User restricted project for "lxder" (1003) | 3 |
+-------------------+--------+----------+-----------------+-----------------+----------+---------------+--------------------------------------------+---------+
このように"User restricted project for ...."と書いてあります。NETWORKSとNETWORK ZONESはデフォルトでこうなります(が実際には(普通の意味での)ネットワークは使える状態です)。
一方で、上記のlxderユーザーでincus profile listを実行すると、user-1003のほうしか表示されません。
さらに、incus project show user-1003で見てみると、諸々の制限がかかった状態になっていることがわかります。
config:
features.images: "true"
features.networks: "false"
features.networks.zones: "true"
features.profiles: "true"
features.storage.buckets: "true"
features.storage.volumes: "true"
restricted: "true"
restricted.containers.nesting: allow
restricted.devices.disk: allow
restricted.devices.disk.paths: /home/lxder
restricted.devices.gpu: allow
restricted.idmap.gid: "1005"
restricted.idmap.uid: "1003"
restricted.networks.access: incusbr-1003
description: User restricted project for "lxder" (1003)
name: user-1003
used_by:
- /1.0/instances/lm?project=user-1003
- /1.0/profiles/default?project=user-1003
プロジェクトがユーザー限定になる仕組み
このような"User restricted project"がincusグループのユーザー(defaultプロジェクトにアクセスする権限はもたない)に対して許可されているのはどうやっているのかということなのですが、多分参考リンク1つ目に書いてある通り、TLSクライアント証明書を使ってゴチャゴチャした設定を自動でやってくれているんだと思います。というのも、/var/lib/incus/users/1003((最近の)LXDなら/var/snap/lxd/common/lxd-user/users/1003)というフォルダにclient.crtとclient.keyというファイルが生成されているからです。
user-1003を消してしまってその状態でincus project createとかをやろうとすると
Error: Certificate is restricted
と言われることもあります。
先ほどのprojectのところにはUIDなど色々書いてありますが、これはTLS認証の部分とは無関係で、単にprojectの設定をいじるだけではlxderユーザーから見えるようにはなりません。
"User restricted project"を作り直したい
一応、この記事の本題的な部分がここです。
上記みたいに変なエラーが出てきてUser restricted projectが使えなくなってしまった場合、最初の状態(incusコマンドを打てばUser restricted projectが勝手に作成される状態)にリセットするのは意外と難しいです。
(筆者の知る限り少なくとも)以下をやる必要があります。
- incus network delete incusbr-1003でincusbr-1003を消しておく
- これだけを忘れていた場合、syslogにFailed to setup new user: Failed to create network: The network already existsというようなメッセージが出て、User restricted projectの作成が失敗する
- /var/lib/incus/users/1003を消す
- これが必要であることに気付くのが難しかった
- これをやらないとそもそもプロジェクトの再作成が行われない
- 該当ユーザー側で~/.config/incusを消す
- 場合によってはやらなくても大丈夫かも
- user-1003というプロジェクトを消しておく
- 存在した場合でもちゃんとそれを引き継いで設定が行われるが、最初からやり直したいなら消しておくと良さそう
もちろん、TLS云々のところを自分でやってもいいのですが、多くの場合はリセットしてやり直したほうが楽な気がします。使用中のコンテナなどは他のプロファイルに一旦退避させることも可能だと思います。
他に遭遇したエラー(検索用)
こんなエラーにも出くわしました。
---
$ incus profile list
Error: Failed loading project "user-1003": Project not found
- .config/incusを消してもこれが出たので、user-XXXXの部分はハードコードされていると考える根拠の1つになった
---
$ incus project list
Error: Get "http://unix.socket/1.0?project=user-1003": read unix @->/var/lib/incus/unix.socket.user: read: connection reset by peer
- /var/lib/incus/user/1003が存在しない(かつincus project list実行時に前述のネットワークインターフェース重複などでUser restricted projectの作成が失敗する)と出る
---
$ incus project list
You don’t have the needed permissions to talk to the incus daemon (socket path: /var/lib/incus/unix.socket)
- ログインセッションが古い(incusグループに追加した後で改めてログインしないと反映されない)(場合によっては再起動しないと解決しないかも
---
- (LXD)lxc project listはいけるのにlxc listやlxc profile listだと前述の
Error: Certificate is restrictedが出る…正しくprojectをswitchできていない場合があります。lxc project listでuser-1003の後に(current)と付いているのが正しいです。そうでない場合、lxc project switch user-1003などと実行しましょう。
まとめ
だいたいこういう面倒な初期設定を勝手にやってくれる機能は正常系から外れるとものすごく面倒なことになるのでもう少しドキュメントにヒントがあるとありがたいなあと感じます。