无需root即可将tar转换为cpio?

无需root即可将tar转换为cpio?

我有一个 tarball,其中包含许多带有 root:root 所有者和/或特殊设备 inode 的文件。cpio创建 cpio 存档时仅接受文件系统中存在的路径。我不想sudo将 tar 转换为 cpio,同时我想保留所有权限、所有者和特殊 inode。

有一些干净的方法来处理这个问题吗?

编辑1:

我相信这fakeroot可以被视为某种干净的方式。然而它并没有按预期扩展 - 速度差异接近 1,000 倍:

[user@computer root]$ ls -l ../fanbox.tar
-rw-rw-r-- 1 user user 56555520 May 22 03:33 ../fanbox.tar
[user@computer root]$ time tar -x --delay-directory-restore -f ../fanbox.tar
tar: dev/null: Cannot mknod: Operation not permitted
tar: dev/random: Cannot mknod: Operation not permitted
tar: dev/urandom: Cannot mknod: Operation not permitted
tar: Exiting with failure status due to previous errors

real    0m0.255s
user    0m0.062s
sys 0m0.193s
[user@computer root]$ rm -rf *
[user@computer root]$ time fakeroot tar -x --delay-directory-restore -f ../fanbox.tar

real    3m49.381s
user    0m0.812s
sys 0m2.760s
[user@computer root]$ 

根据time命令的输出,我猜这是因为fakeroot和之间的通信faked

作为参考,当我在脚本中fakeroot更改时,2M tarball 和 50M tarball 之间没有太大区别。sudo bash而且我认为问题在于 tarball 中的文件数量,而不是大小:我在包含两个 5M 二进制文件的 ~10M tarball 上使用了相同的脚本,并且脚本并不那么慢。

答案1

您可以使用fakeroot。顾名思义,它通过使用LD_LIBRARY_PATH/LD_PRELOAD库包装器拦截多个系统调用来伪造 root 用户,让进程相信它正在以 root 身份运行。创建它的目的是为了构建和打包应用程序而无需 root,包括使用make install通常以 root 身份运行的应用程序。它特别适合创建档案。

在此期间,分叉守护进程faked将运行以记住所有伪造的文件所有权或子进程认为它们创建的特殊文件的信息。因此,所有操作都必须在同一个“实例”中完成,否则faked将退出并忘记它所记住的内容。

$ fakeroot
# tar xf ...
# find foo ... | cpio -o ...
# exit
$ 

faked显示的交互的其他示例:

$ mknod /tmp/vaporware b 8 0
mknod: /tmp/vaporware: Operation not permitted
$ fakeroot
# mknod /tmp/vaporware b 8 0
# ls -l /tmp/vaporware
brw-r--r-- 1 root root 8, 0 May 18 08:33 /tmp/vaporware
# exit
$ ls -l /tmp/vaporware
-rw-r--r--. 1 user user 0 May 18 08:33 /tmp/vaporware

答案2

尝试使用 bsd tar (不是 GNU tar)——魔法@就是在你的 tarball 文件名之前加上一个:

bsdtar --format=cpio -cf - @root.tar.gz > root.cpio

答案3

您可以将其用作lxc-usernsexec提取和重新创建存档的环境。

lxc-usernsexec
mkdir tmp
cd tmp
tar xf ../archive.tar
find . -print0 | cpio -0o > ../archive.cpio
exit

这假设您已正确设置 Linux 容器,以便$HOME/.config/lxc/default.conf存在(并且/etc/subuid设置/etc/subgid正确)。欲了解更多信息,请参阅

https://wiki.debian.org/LXC#Unprivileged_container

关于 Debian Buster 的说明:

$ lxc-usernsexec 
Failed to find subuid or subgid allocation

这似乎是一个错误,但以下脚本修复了此问题:

#!/bin/bash

ARGS=()

while read -ru6 what equals rest
do
        [ ".$what" = ".lxc.idmap" ] || continue
        [ ".$equals" = ".=" ] || continue
        ARGS+=(-m "${rest// /:}")
done 6<"$HOME/.config/lxc/default.conf"

exec /usr/bin/lxc-usernsexec "${ARGS[@]}" -- "$@"

相关内容