web-dev-qa-db-ja.com

非共有名前空間内にファイルシステムイメージをマウントする

私はunshareを使用して、特定のプロセスにローカルなバインドマウントなどを実行していますルートアクセスを必要とせずに 、例:

unshare -mr bash mount --bind a b

(はい、これはちょっとばかげているようです。私の実際のユースケースでは、unshareはバインドマウントを実行するbashスクリプトを実行しています。ここでは実行しなかったので、小さな例です。)

ただし、ループマウントを試行すると、失敗します。

ryan@DevPC-LX ~/stuff/util-linux master $ unshare -mr mount -o loop x.img a
mount: no permission to look at /dev/loop<N>

:/

mknodを使用して偽のループデバイスを作成し(root以外では使用できない特権が必要)、手動でlosetupを実行し(root特権が必要)、その他の多くのものを試しました。動作しません。

もちろん、私はchown myuser /dev/loop*、しかしそれは主要なセキュリティ問題になる可能性があるようです。

さらに、guestmountは私のユースケースには遅すぎます。そしてfuseext2には、書き込みモードでのデータ損失の可能性に関する警告があります(また、速度が遅すぎます)。

これを行う方法はありますか...これですか?まったく?

7
kirbyfan64sos

Unshareを実行するには、個別のマウントスペースを作成するためのルート機能が必要です。

私はあなたが望むことをするように見えるこれを試しました(私は思う):

Ishtar:> mkdir -p /tmp/unshare/home
Ishtar:> cd /tmp/unshare
Ishtar:/tmp/unshare> Sudo unshare -m /bin/bash
Ishtar:/tmp/unshare# mount --rbind /home/packages /tmp/unshare/home
Ishtar:/tmp/unshare# tty
/dev/pts/4
Ishtar:/tmp/unshare# # ls home
BUILD@      RPMS@     build/           linux@    sources/           tmp/
BUILDROOT@  SOURCES@  buildroot/       logs/     specs/
OSbuild/    SPECS@    config-scripts/  perlsrc/  srpms/
OTHER/      SRPMS@    debug@           rpms/     sysvinit-288.spec

したがって、上記のプロセスには、/ home/packagesが@/tmp/unshare/homeにマウントされています。

別のttyウィンドウで、どのユーザーでも、次のことを確認できます。/tmp/unshare/homeの内容:

Ishtar:/> tty
/dev/pts/5
Ishtar:/> ll /tmp/unshare/home
total 0
Ishtar:/> cd tmp/unshare
Ishtar:/tmp/unshare> Sudo
Ishtar:/tmp/unshare# ls home
Ishtar:/tmp/unshare# ll home
total 0
# create file in original "bound" dir from 1st usr above:
Ishtar:/tmp/unshare# touch /home/packages/PACKAGES.DIR 
Ishtar:/tmp/unshare# ll home  #home still empty
total 0
Ishtar:/> tty
/dev/pts/5
# now on other user again
Ishtar:/tmp/unshare# tty
/dev/pts/4
Ishtar:/tmp/unshare# ls home
BUILD@        RPMS@     buildroot/       perlsrc/  sysvinit-288.spec
BUILDROOT@    SOURCES@  config-scripts/  rpms/     tmp/
OSbuild/      SPECS@    debug@           sources/
OTHER/        SRPMS@    linux@           specs/
PACKAGES.DIR  build/    logs/            srpms/
#^^^ see PACKAGES.DIR appear (as created in original dir by another
# user

「pts/4」でユーザー用の「プライベートディレクトリ」をマウントしたら、プログラムで実行するUIDに変更できます。

Ishtar:/tmp/unshare# su astara
Ishtar:/tmp/unshare> whoami
astara
Ishtar:/tmp/unshare> ls home/PACK*
home/PACKAGES.DIR

マウントされていないユーザーのマウントはまだ残っています。

保存するには、スクリプトファイルに「su to other user」を配置し、続いて「unmount/tmp/unshare/home」を配置します(su OTHERUSERが終了すると、再びrootになり、ファイルをアンマウントします。プライベートスペース、)。その後、終了できます。

これはあなたが望むものに近づいていますか? -子環境を設定するには「root」を使用する必要がありますが、子を実行します-そして、新しいマウント名前空間で作成されたマウントにアクセスできるのはその子だけです。

(更新)BTW-気付いたばかりのunshareには--map-root-userがあり、新しい名前空間でオプションを設定するためにrootまたはcapsのいずれかを使用することを明確に許可します。マンページには(このスイッチについて)次のように書かれています。

....This makes it possible to  conveniently
gain  capabilities needed to manage various aspects of the newly
created namespaces (such as configuring interfaces in  the  net-
work  namespace  or mounting filesystems in the mount namespace)
even when run unprivileged.

これにより、rootでなくてもループ開発を管理できるようになります(またはマンページに記載されています)。おそらくCAP_SYS_ADMINは、これを行うために必要な上限です。

2
Astara

明確に理解しているように、ループマウントの作成は2つのステップで構成されます。

  1. ループデバイスのセットアップ
  2. 取り付けます

もちろん、myuser/dev/loop *をchownすることもできますが、それは重大なセキュリティ問題になる可能性があるようです。

これにより、適切なループデバイスを作成できると思います(_/dev/loopcontrol_へのアクセスを許可することにより)。ループデバイスのビューに影響を与える、ある種の名前空間も利用できるかどうかはわかりません。これにより、おそらくこれをより安全に行うことができます。

ただし、ステップ2はまだ実行できません。ユーザー名前空間では、ユーザーが新しいマウントを作成できる新しいマウント名前空間を作成できますが、かなり制限されています— _CAP_SYS_ADMIN_初期名前空間では、ブロックデバイスをマウントする必要があります:user_namespaces(7)のように…

ただし、ブロックベースのファイルシステムのマウントは、初期ユーザー名前空間にCAP_SYS_ADMINを保持するプロセスによってのみ実行できることに注意してください。

ループデバイスは、ファイルに裏打ちされたブロックデバイスであるため、まだ立ち入り禁止です。これは残念なことですが、これが安全に機能する方法があるはずだと思います。しかし、私はそれに多くの複雑さ( 特にsetuid を伴う)があり、それがまだ実装されていない理由だと思います。

だから私が理解する限り、あなたが本当にできることは問題を回避することだけです。イメージからファイルを抽出できるかもしれません(最悪の場合、つまり特定の形式を直接操作するために使用できるツールがない場合は、一時的にマウントしてこれを行うことができますVM )、結果のディレクトリをバインドマウントします。

2
linuxhackerman