不使用环回设备加密环回图像

不使用环回设备加密环回图像

我正在尝试为嵌入式Linux系统设计一个固件更新系统。我的计划是发送一个可以安装在目标系统上的映像,因此我不需要解压整个文件。我还想加密图像,并可以选择压缩它。由于用于创建此映像的构建系统将部署在多台计算机上,因此我还希望构建系统需要最少的设置,即避免需要 root 权限。

losetup我创建了一个工作模型,在其中使用以下方式安装图像文件:

dd if=/dev/zero of=image_file bs=1M count=10
losetup -e aes loop0 image_file
mkfs.ext2 /dev/loop0
losetup -d loop0
mount -t ext2 -o loop,encryption=aes image_file some_working_folder/
# Add files to some_working_folder
umount some_working_folder
# Send encrypted image to the target system

现在,由于这在某些机器上设置起来有点麻烦,并且我想避免创建固定大小的图像。所以我想losetup用其他东西替换命令。我找到了命令virt-make-fs,它可以使用文件系统创建可安装的映像ext2。所以现在我只需要以Linux内核可解密的方式加密图像文件。我尝试过使用 OpenSSL,但我无法找到正确的算法,或者也许我遗漏了一些东西。有人知道怎么做这个吗?基本上我想要像下面的脚本这样的东西。

tar -cf archive.tar some files
virt-make-fs archive.tar image.ext2
# the below command need to be fixed/replaced
openssl enc -aes192 -in image.ext2 -out image.ext2.aes

在目标系统上,我希望能够使用以下命令,或者至少是类似的命令。

# The next command should be done on the target
mount -t ext2 -o loop,encryption=aes image.ext2.aes /mnt/upgrade
# work with files in /mnt/upgrade

所以,只是为了澄清:如何在不成为 root 的情况下创建加密的可安装映像文件?

如果我正在尝试重新发明轮子,或者是否有其他成熟的解决方案来解决这个问题,请随时发表评论。尽管有更好的解决方案,我仍然对解决加密问题的命令感兴趣。


编辑:正如指出的那样,cryptoloop 是不安全的,请参阅http://lwn.net/Articles/67216/。所以我可能也会寻找另一种解决方案。我找到了 util aespipe,我也许可以使用它。


编辑2:我深入研究了Linux内核的AES模块中的源代码,我得出的结论是,可能是密码的散列导致了问题。 AES 模块均aespipe使用 AES-256-CBC 加密。据我所知,Linux 内核使用给定的密码作为密钥,并对aespipe传入的密码进行哈希处理。由于“无root”部分对我来说非常重要,我已经开始寻找其他解决方案,我当前的计划是在开发计算机上使用如下所示的解决方案:

tar -cf - file0 file1 ... | gzip -c | aespipe -e aes256 > arhive_file

然后在目标系统上运行

rm -rf /tmp/update ; mkdir -p /tmp/update
aespipe -d -e aes256 < archive.mbl | gzip -cd | tar -C /tmp/update -xf -

答案1

尽管 cryptloop 的安全性很弱,但根据

您可以使用用户模式 ​​FS 创建器,例如:buildroot genext2fs.sh 或 android make_ext4fs。与 aespipe 工具结合使用,无需 root/超级用户权限即可在主机上创建加密映像。

但是你需要用以下命令修补lostup(至少或安装)循环aes并为目标的 Linux 内核激活 cryptoloop(作为模块或内置),以便能够直接挂载此类加密映像。

以下显示了在加密的 ext4 文件系统映像的情况下如何执行此操作(对于 ext2 FS,您只需将前 2 个命令替换为 buildroot genext2fs.sh[3]):

HOST $ make_ext4fs -s -l 512M -a data yourimage.simg folder/
HOST $ simg2img yourimage.simg yourimage.img
HOST $ cat yourimage.img | aespipe -e aes256 > yourimage.crypt

TARGET # modprobe cryptoloop #in case of cryptoloop as module.
TARGET # losetup.patched -e aes-256 /dev/loop0 yourimage.crypt
TARGET # mount -t ext4 /dev/loop0 /mnt/uncrypt

答案2

请使用 dmcrypt,它是 Linux 中事实上的标准磁盘加密子系统。

在开发人员机器上,安装地穴安装配置它允许以非 root 用户身份安装。这很麻烦,因为您必须在/etc/cryptmount/cmtab.

upgrade {
    keyformat=luks
    dev=/home/bob/upgrade/image.enc
    dir=/mnt/upgrade
}

安装和卸载:

cryptmount -m upgrade
cryptmount -u upgrade

或者,设置 sudo 规则以允许开发人员无需密码cryptsetup即可运行。losetup

Cmnd_Alias CryptLoop = cryptsetup luksOpen * *, cryptsetup remove *, losetup * *
bob ALL=(ALL) NOPASSWD: CryptLoop

答案3

如果我没记错的话,出于安全考虑,加密支持已从mount/中删除losetup,转而使用 dmcrypt。因此我假设你必须losetup在不加密的情况下使用,并在其上放置一个 DM 加密设备。

losetup /dev/loop0 /image/clearfile.img
losetup /dev/loop1 /image/cryptfile.img
cryptsetup create cr_loop /dev/loop1
dd if=/dev/loop0 of=/dev/mapper/cr_loop bs=100M

然后cryptfile.img是加密的。您可以通过重复losetupcryptsetup(然后安装解密的设备)来分发它并使其可用。

您可以添加要用于调用的密码(等等),cryptsetup以避免更改默认值时出现问题。或者使用 LUKS 代替。但在这种情况下,加密文件必须比明文图像稍大(5 MiB 应该足够了);文件系统可能比设备小一点,但这并不重要。

相关内容