如何保护 /dev/sdX 免遭意外格式化?

Kam*_*Cuk 31 linux block-device

我经常处理格式化 USB 驱动器,这些驱动器注册为 /dev/sdX。这包括执行mkfsfdisk以及mount其他通常以 root 身份执行的命令。然而,我担心我可能会不小心输错一个字母,并格式化我的硬盘。

理想情况下,我希望将/dev/sdX*设备设置为“只读”模式,这样任何fdisk mkfs wipefs设备都会失败,除非通过手动命令将设备切换到“读写”模式。

我以为chmod ugo-w /dev/sdX会像那样工作。然而令我惊讶的是,chmod 0000 /dev/sdc1接下来的mkfs /dev/sdc1作品完全没问题。

如何防止所有用户(包括 root 用户)修改硬盘驱动器及其分区表、对硬盘驱动器进行分区以及以通过已安装的文件系统以外的方式写入分区?如果我愿意,如何使用此方法启用对驱动器的写入?

我知道我可以使该设备归用户所有。然而,这需要我在用户和 root 之间切换才能发出类似chrootormount或 之类的命令umount,这是一个安全漏洞。我不希望所有 USB 存储设备都归用户所有。我正在寻找更好的解决方案。理想情况下,我希望保留 root 用户身份,但不会格式化错误的光盘。

mar*_*elm 38

考虑使用/dev/disk/by-{path,id}/

\n

/dev/disk/by-path/具有到块设备的符号链接,其中符号链接的名称描述设备的“硬件路径”(子系统、总线、控制器、端口等)。我的系统上经过编辑的列表显示了一个 NVME 设备、一个SATA 设备和一个 USB 驱动器(以及每个驱动器上的第一个分区):

\n
/dev/disk/by-path\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 pci-0000:00:14.0-usb-0:1:1.0-scsi-0:0:0:0 -> ../../sdc\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 pci-0000:00:14.0-usb-0:1:1.0-scsi-0:0:0:0-part1 -> ../../sdc1\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 pci-0000:00:17.0-ata-2 -> ../../sda\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 pci-0000:00:17.0-ata-2-part1 -> ../../sda1\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 pci-0000:02:00.0-nvme-1 -> ../../nvme0n1\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 pci-0000:02:00.0-nvme-1-part1 -> ../../nvme0n1p1\n
Run Code Online (Sandbox Code Playgroud)\n

/dev/disk/by-id工作原理类似,但具有子系统、设备品牌/型号和序列号。我确实似乎有很多三星存储:

\n
/dev/disk/by-id\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ata-Samsung_SSD_860_EVO_500GB_XXXXXXXXXXXXXXX -> ../../sda\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ata-Samsung_SSD_860_EVO_500GB_XXXXXXXXXXXXXXX-part1 -> ../../sda1\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 nvme-Samsung_SSD_980_PRO_1TB_XXXXXXXXXXXXXXX -> ../../nvme0n1\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 nvme-Samsung_SSD_980_PRO_1TB_XXXXXXXXXXXXXXX-part1 -> ../../nvme0n1p1\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 usb-Samsung_Flash_Drive_FIT_XXXXXXXXXXXXXXXX-0:0 -> ../../sdc\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 usb-Samsung_Flash_Drive_FIT_XXXXXXXXXXXXXXXX-0:0-part1 -> ../../sdc1\n
Run Code Online (Sandbox Code Playgroud)\n

假设您的目标是不混淆插入的 USB 驱动器和您的 (sata/nvme) 系统驱动器,这些名称可能会有所帮助。您可以只使用这些命令的名称,并且应该按预期工作:

\n
fdisk /dev/disk/by-id/usb-Samsung_Flash_Drive_FIT_XXXXXXXXXXXXXXXX-0:0\nmke2fs /dev/disk/by-id/usb-Samsung_Flash_Drive_FIT_XXXXXXXXXXXXXXXX-0:0-part1\n
Run Code Online (Sandbox Code Playgroud)\n

希望这足以引起您的注意并中止:

\n
mke2fs /dev/disk/by-id/nvme-Samsung_SSD_980_PRO_1TB_XXXXXXXXXXXXXXX-part1\n
Run Code Online (Sandbox Code Playgroud)\n

  • 我提倡将其作为最佳实践,并且几乎总是使用它。 (7认同)
  • 如果目标设备是分区并且分区表是GPT,您可以为它们设置良好的、唯一的分区名称(partlabels)。然后你就可以通过`/dev/disk/by-partlabel/uniquename`。因为即使使用最复杂的“/dev/disk/by-id/usb-Samsung_Flash_Drive_FIT_XXXXXXXXXXXXXXXX-0:0-partN”,当您键入时,您仍然可能会以某种方式摸索分区号... (2认同)
  • @frostschutz 这也非常有用!然而,OP 正在谈论格式化 USB 驱动器,因此他们可能无法控制这些驱动器上的现有分区标签。这就是为什么我重点关注名称中包含子系统 (USB) 的方法。 (2认同)

meu*_*euh 18

rm /dev/sda /dev/sda1 如果您想防止意外引用这些设备,一个简单的策略是在启动后等等。mknod /dev/sda1 b 8 1如果需要的话,您总是可以使用等等重新创建索引节点,但umount /dev/sda1没有它也可以工作,因为它可能在某处有适当的信息。

但这确实是一个良好卫生的问题;最好不要以 root 身份登录,也不要 su 到 root,或者如果您必须仅在一个红色背景的终端中这样做,请不要复制粘贴到其中,为重复任务编写脚本并确保它们检查参数并进行其他健全性检查。


fro*_*utz 12

嗯,有blockdev --setro一个块设备是只读的(--setrw用于读写)。

\n
# blockdev --setro /dev/sdx3\n# mkfs.ext4 /dev/sdx3\nmke2fs 1.47.0 (5-Feb-2023)\n/dev/sdx3 contains a vfat file system\nProceed anyway? (y,N) y\n/dev/sdx3: Operation not permitted while setting up superblock\n# wipefs -a /dev/sdx3\nwipefs: /dev/sdcx3: failed to erase vfat magic string at\n  offset 0x00000052: Operation not permitted\n
Run Code Online (Sandbox Code Playgroud)\n

那么你可以让块设备只读,甚至对于 root 来说也是如此吗?是的。嗯,有点。

\n

然而,它不是很可靠。例如,如果内核因任何原因重新读取分区表。即使分区实际上没有更改,重新读取后从/dev/sdx3技术上讲也是一个新设备,从未设置过此 ro 标志。

\n

因此,至少您需要一些 udev 规则来始终管理和维护您的只读标志。(如果在任何地方有一个标志默认使块设备只读,我不知道它。)

\n

此外,任何已经在写入模式下使用该设备的设备都可以继续这样做。因此,这不会影响已安装的文件系统...直到这些文件系统出于任何原因尝试重新打开设备(在重新安装时更改安装标志或其他方式时)。

\n

当然,使分区只读并不会阻止在偏移处向主设备写入某些内容 - 反之亦然。有多个块设备指向完全相同的存储区域是正常的。您必须确保将所有这些设置为只读,而不仅仅是一个。

\n

所以这是可能的,是的,只是不太实际。

\n

设置此标志可能会导致其他程序出现错误,并且此类错误可能会导致不同类型的数据丢失。通常,您希望写入成功或丢失任何应该写入的内容。

\n

因此,这种方法完全有可能造成比它解决的问题更多的问题。最后,您仍然想要格式化您的 USB 记忆棒,为此您必须使其可写,并且为此您必须能够识别和使用正确的设备名称,而不是将其与错误的名称混淆。

\n

您可以检查/dev/disk/by-*/* 是否有更合适的名称,例如/dev/disk/by-id/usb-Flash\xe2\x80\xa6不太可能指内部驱动器。

\n


jof*_*fel 11

这不是一个真正的解决方案,但您可以将危险的突击队隐藏在包装 shell 脚本后面,这些脚本检查危险设备的命令行参数。

可能还有一些方法可以使用 SELinux、AppArmor 等安全系统来限制 root 的访问。

  • 这有点像将“ls”别名为“ls -i”——它可能会鼓励鲁莽行为,然后在使用没有这些包装器的系统时让您陷入困境。 (7认同)
  • 这是最安全的答案,但不是大多数勒德分子想要的。 (2认同)

Cri*_*gie 6

您正在寻找一种技术解决方案\n以\nxc2\xa0防止您在计算机上做坏事。

\n

我们许多人学会避免这些问题的一种方法是做错事然后丢失数据。我们学会放慢速度并仔细检查事情。

\n

如果你能够从别人的错误中吸取教训,那就太好了。我从自己的错误中学到了很多东西。

\n

技术解决方案可能会像现在一样在您的计算机上正常工作。改进应对危险行为的方法将对您将来在任何计算机上有所帮助。

\n

Unix 是一种能完成小工作的小工具。就像锋利的刀子、剪刀和凿子一样,它\xe2\x80\x99 取决于用户如何处理它们。

\n

对工具感到满意,但永远不要自满。

\n

  • 好吧,遗憾的是,我认为这不是我问题的答案;)我担任 Linux 管理员大约 20 年了。不用担心,我已经执行了 rm -rf /` 3 次,无数次格式化错误的硬盘,丢失和错误配置的 raid。“您正在寻找一种技术解决方案来防止您在计算机上做坏事。” 是的。 (6认同)
  • @KamilCuk 是的,我完全明白你从那里来的。问题是当这个安全网消失时,因为你使用的是另一台计算机。这就像习惯性地摇动汽车的变速杆,因为一旦你启动它,它就会向前滚到车库墙上。我曾经做过一次,现在有时我发现自己甚至在自动驾驶汽车上也会进行同样的安全检查。但我又开始工作了吗?没有永不。我不摇动变速杆的那一天就是它挂档的那一天。或者你会用安全剪刀替换所有剪刀以避免被割伤吗? (4认同)
  • 这有什么问题吗?你可以说,那些让日常工作和日常工作以及超级危险的“摧毁一切”命令很容易意外混淆的 UI 设计很糟糕。格式化 SD 卡或拇指驱动器是常规操作。擦除启动分区则不然。当你想要前者时,希望后者不容易发生是完全合理的。 (3认同)
  • 投反对票是可以的——如果读者认为这个答案不好,那就去吧。 (2认同)
  • 这是最好的答案。“如何避免输错一个字母以及错误地格式化错误的驱动器?” “始终仔细检查你正在做的事情。” (2认同)