背景
NFSv4 エクスポート/共有の場合、デフォルトで有効になっている root_squash オプションにより、NFS はクライアントのルートを匿名 ID に変更するように強制されます。これにより、1 つのシステムのルート アカウントの所有権が他のシステムに移行するのを防ぐことで、セキュリティが強化されます。
Overlayfs を使用すると、ローカルの透過的なファイルシステムを別のファイルシステムの上にマウントできます。残念ながら、実際のユーザーではなく、ルート ユーザーを使用して基礎となるファイルシステムにアクセスするようです。少なくとも、次の実験から私が得た結論はそうです。
Overlayfs を NFS 共有上にマウントする理由は何でしょうか? 信頼性の低いマシンが共有ファイルシステムに書き込めるように見せかけるためです。
テスト設定
まず、ディストリビューションに応じて NFS カーネル サーバーをインストールします。次に、NFSv4 のみをエクスポートすることを確認します (この問題では重要ではないかもしれませんが、セキュリティ上の予防策としては有効です)。
$ sudo cat /proc/fs/nfsd/versions
-2 -3 +4 +4.1 +4.2
そうでない場合は、 を確認して/etc/nfs.conf
設定してくださいvers3=n
。
次に、スパース ファイルに Ext4 ファイルシステムを作成し、それをローカル ファイルシステムにマウントします。これが NFS 共有の基盤となるファイルシステムになります。
$ truncate -s 512M 512BM-ext4.img
$ mkfs.ext4 512BM-ext4.img
$ sudo mkdir /mnt/ext4-file
$ sudo mount -o loop,noacl 512BM-ext4.img /mnt/ext4-file
次に、NFSv4 を使用して、このファイルシステムをネットワーク経由で適切なマシンに共有/エクスポートします。この例では localhost を使用しますが、ローカル ネットワーク上の任意のマシンを使用できます。これを行うには、/etc/exports
次のような行を編集します。
/mnt/ext4-file/ localhost(ro,fsid=123123)
次に、マシン上の NFS サーバーを再起動します。サービス ファイルは OS によって異なる場合があります。
$ sudo systemctl restart nfs-server.service nfs-mountd.service
$ sudo exportfs -v
/mnt/ext4-file localhost(sync,wdelay,hide,no_subtree_check,fsid=123123,sec=sys,ro,secure,root_squash,no_all_squash)
root_squash
およびが有効になっていることを確認しますro
。
これで、目的のクライアントに NFSv4 共有をマウントできるようになります。
$ sudo mount -t nfs -o ro localhost:/mnt/ext4-file /mnt/nfs-share/
$ findmnt /mnt/nfs-share
TARGET SOURCE FSTYPE OPTIONS
/mnt/nfs-share localhost:/mnt/ext4-file nfs4 rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255
そして、この共有の上に overlayfs2 をマウントします。
$ mkdir -p /tmp/overlay/{work,upper}
$ sudo mkdir /mnt/overlay
$ sudo mount -t overlay overlay -o lowerdir=/mnt/nfs-share/,upperdir=/tmp/overlay/upper/,workdir=/tmp/overlay/work/ /mnt/overlay/
私たちの実験では、ファイルシステム内に、ユーザーのみが読み取りと書き込みができ、グループのみが読み取りができるフォルダーを作成します。私は自分のユーザーに属するグループを選択しました。
$ sudo mkdir /mnt/ext4-file/rovanion
$ sudo chown rovanion:rovanion /mnt/ext4-file/rovanion
$ sudo chmod 2750 /mnt/ext4-file/rovanion
$ touch /mnt/ext4-file/rovanion/hi-from-ext4
$ ls -la /mnt/nfs-share/rovanion/
totalt 8,0K
drwxr-s--- 2 rovanion rovanion 4,0K sep 6 14:14 .
drwxr-xr-x 4 root root 4,0K sep 6 14:12 ..
-rw-rw-r-- 1 rovanion rovanion 0 sep 6 14:14 hi-from-ext4
$ touch /mnt/nfs-share/rovanion/hi-from-nfs
touch: cannot touch '/mnt/nfs-share/rovanion/hi-from-nfs': Read-only file system
の内容を一覧表示することはできます/mnt/nfs-share/rovanion
が、NFS 共有が読み取り専用としてマウントされているため、権限があってもファイルシステムにアクセスできません。すべて予想どおりです。
失敗
しかし、ここで問題が発生します。
$ ls -la /mnt/overlay/rovanion/
ls: cannot open directory '/mnt/overlay/rovanion/': Permission denied
$ ls -l /mnt/overlay/
total 28K
drwx------ 2 root root 16K Sep 6 13:04 lost+found
drwxr-s--- 2 rovanion rovanion 4.0K Sep 6 14:14 rovanion
$ whoami
rovanion
$ groups
rovanion sudo
/mnt/overlay/rovanion
権限システムではリストへのアクセスが許可されているはずなのに、リストへのアクセスが拒否されました。
何が起こっているのかについての私の推測では、Overlayfs が基礎となるファイルシステムへのすべてのアクセスを実行し、root
NFS のルート スカッシュによって、グループに属しておらず、他のユーザーがフォルダーを一覧表示nobody
できないため、フォルダーへのアクセスが許可されていないユーザーにマップされるということです。nobody
rovanion
質問
o+rx
そこで質問です。この問題を回避することは可能でしょうか。NFS エクスポート/共有で root_squash を無効にしたり、フォルダーに追加したりせずに、選択されたグループのみがアクセスできるフォルダーに、Overlayfs を介してユーザーがアクセスできるようにします。
答え1
次のセクションOverlayfs に関する Linux カーネルのドキュメント権限モデルについて説明します。
オーバーレイ ファイルシステムでの権限チェックは、次の原則に従います。
1) permission check SHOULD return the same result before and after copy up 2) task creating the overlay mount MUST NOT gain additional privileges 3) non-mounting task MAY gain additional privileges through the overlay, compared to direct access on underlying lower or upper filesystems
これは、各アクセスに対して2つの権限チェックを実行することで実現されます。
a) check if current task is allowed access based on local DAC (owner, group, mode and posix acl), as well as MAC checks b) check if mounting task would be allowed real operation on lower or upper layer based on underlying filesystem permissions, again including MAC checks
チェック (a) により、所有者、グループ、モード、POSIX ACL がコピーされるため、一貫性 (1) が確保されます。その一方で、サーバーによって強制される権限 (たとえば NFS によって使用される権限) が無視される可能性があります (3)。
チェック(b)は、マウントタスクが持っていない下層レイヤーへの権限をタスクが取得しないようにします(2)。これは、一貫性ルール(1)が成立しないセットアップを作成できることも意味します。ただし、通常、マウントタスクはすべての操作を実行するのに十分な権限を持ちます。
強調は私によるものです。私が解釈したところによると、私はそのような状況を作り出すことに成功しました。ルートとして実行されているマウント タスクにはフォルダーを一覧表示する権限がないため、Overlayfs はユーザーによるフォルダーへのアクセスを許可しません。
UID が押しつぶされないように、ファイルへのアクセスが許可されているユーザー (root ではない) として Overlayfs をマウントする場合、ディレクトリを一覧表示してその中にファイルを作成できるでしょうか?
$ unshare --mount --map-root-user
# mount -t overlay overlay -o lowerdir=/mnt/nfs-share/,upperdir=/tmp/overlay/upper/,workdir=/tmp/overlay/work/ /mnt/overlay/
# ls -la /mnt/overlay/
totalt 28K
drwxrwxr-x 1 root root 4,0K sep 6 14:08 .
drwxr-xr-x 7 nobody nogroup 4,0K sep 6 14:09 ..
drwx------ 2 nobody nogroup 16K sep 6 13:04 lost+found
drwxr-s--- 2 root root 4,0K sep 6 14:14 rovanion
# touch /mnt/overlay/rovanion/hi-from-overlay
そして、それは可能です!そして、ファイルはオーバーレイ内にのみ存在します。
$ ls /mnt/ext4-file/rovanion/
hi-from-ext4
$ ls /tmp/overlay/upper/rovanion/
hi-from-overlay
ただし、このソリューションには独自の興味深い影響があります。100% 信頼できないマシンでユーザー名前空間を有効にする必要があり、突然、UID が 0 のように見えるが、外部の世界では通常のユーザー ID にマップされる空間に存在することになります。残念ながら、unshare --mount
これなしでは--map-root-user
不可能のようです。