AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-163895

Carlo Wood's questions

Martin Hope
Carlo Wood
Asked: 2024-12-23 07:33:07 +0800 CST

如何使用 udev 和 systemd 自动挂载 USB 驱动器的(加密)分区

  • 8

我有以下要求:

  • 如果插入了特定的 USB 存储设备,系统会自动检测并安装它。安装位置信息/etc/fstab(当然)会显示在这里。
  • 如果 USB 驱动器坏了,必须自动进行彻底清理;从而不会留下任何残留痕迹,例如它曾被安装(或仍然被安装)和/或任何未完成的 systemd 单元。
  • 如果手动编辑了有问题的分区umount,那么所有内容也应该被清理,即使该棒仍然存在;将其从插头中拔出应该只会清理之前无法清理的内容(可能是单元.device)。

为了以干净的方式实现上述操作,插入 USB 驱动器将导致自定义 systemd 单元的启动,然后我们将对其进行配置以完成其余操作。

写这个需要什么?

假设我们有一个有三个分区的 USB 驱动器: /dev/sdc1和/dev/sdc2- 它们是 LUKS 加密的,以及/dev/sdc3- 它们是未加密的。

例如,

>sudo blkid /dev/sdc{1,2,3}
/dev/sdc1: UUID="de9a000f-fa60-4050-8d11-864e97829b8a" TYPE="crypto_LUKS" PARTUUID="219578f5-5905-41cd-895d-7b937ac0756a"
/dev/sdc2: UUID="012059c1-6b88-4937-889a-a21448740492" TYPE="crypto_LUKS" PARTUUID="59c7f6f3-a5cb-41af-82fa-b515031d85d5"
/dev/sdc3: LABEL="README" UUID="9d262deb-2343-4096-bccf-bb26ed4415ad" BLOCK_SIZE="1024" TYPE="ext2" PARTUUID="165db3da-4ebb-4f59-ab09-ee5e5b26ed43"

以下UUID是所使用的内容/dev/disk/by-uuid:

>ls -l /dev/disk/by-uuid | grep sdc
lrwxrwxrwx 1 root root 10 Dec 22 18:27 012059c1-6b88-4937-889a-a21448740492 -> ../../sdc2
lrwxrwxrwx 1 root root 10 Dec 22 18:27 9d262deb-2343-4096-bccf-bb26ed4415ad -> ../../sdc3
lrwxrwxrwx 1 root root 10 Dec 22 18:27 de9a000f-fa60-4050-8d11-864e97829b8a -> ../../sdc1

由于设备名称/dev/sdc相当随机,从现在开始我们应该只使用 UUID。

为了手动挂载未加密的分区,我们需要执行(确保 /mnt 和/或 /mnt/usb 上尚未挂载任何内容!):

UUID=9d262deb-2343-4096-bccf-bb26ed4415ad
SERIAL=408D5CBECAC3E7C0E9170AEC
sudo /bin/mkdir -p /mnt/usb/$SERIAL/part3
sudo mount -t ext2 /dev/disk/by-uuid/$UUID /mnt/usb/$SERIAL/part3

我确实选择使用 USB 设备的值ID_SERIAL_SHORT,例如可以通过以下方式获取:

>udevadm info -n /dev/sdc3 | grep -E '(ID_SERIAL_SHORT|ID_FS_UUID)='
E: ID_SERIAL_SHORT=408D5CBECAC3E7C0E9170AEC
E: ID_FS_UUID=9d262deb-2343-4096-bccf-bb26ed4415ad

/etc/fstab让我们通过向该文件添加以下内容来存储挂载点:

UUID=9d262deb-2343-4096-bccf-bb26ed4415ad   /mnt/usb/408D5CBECAC3E7C0E9170AEC/part3 ext2    rw,noauto   0 0

请注意,此后我们可以执行以下操作:

sudo mount /dev/sdc3

只要该块设备具有预期的 UUID,它就能顺利完成挂载。

另外两个分区/dev/sdc{1,2}已加密,首先需要

UUID1=573bfda0-69f5-4fb9-9d7e-333a70a51710
UUID2=6d7bdc1d-3eb0-4774-a9fb-3d1ac1027010
echo $LUKS_PASS | sudo cryptsetup -q luksOpen /dev/disk/by-uuid/$UUID1 usb-$UUID1
echo $LUKS_PASS | sudo cryptsetup -q luksOpen /dev/disk/by-uuid/$UUID2 usb-$UUID2

要执行的命令,我假设环境变量LUKS_PASS包含解​​密 LUKS 分区所需的密码。这里的 UUID 是 blkid 返回的:

>sudo blkid /dev/sdc{1,2}
/dev/sdc1: UUID="573bfda0-69f5-4fb9-9d7e-333a70a51710" TYPE="crypto_LUKS" PARTUUID="caa57a9d-7389-4990-a243-34b19a179368"
/dev/sdc2: UUID="6d7bdc1d-3eb0-4774-a9fb-3d1ac1027010" TYPE="crypto_LUKS" PARTUUID="10813450-6dcc-4700-9e88-d0577c0c9aeb"

这将为/dev/mapper/usb-$UUID每个分区创建一个设备,每个设备都有自己的 UUID:

>sudo blkid /dev/mapper/usb*
/dev/mapper/usb-573bfda0-69f5-4fb9-9d7e-333a70a51710: LABEL="gold1-2024-12-21" UUID="67f056be-dbbc-4f7a-979d-6ff077d16e93" BLOCK_SIZE="4096" TYPE="ext2"
/dev/mapper/usb-6d7bdc1d-3eb0-4774-a9fb-3d1ac1027010: LABEL="gold2-2024-12-21" UUID="94bfcc55-6b52-431f-bc76-3aa198c107c7" BLOCK_SIZE="4096" TYPE="ext2"

这些就是我们想要添加的 UUID /etc/fstab。

为了让生活更轻松,我编写了以下脚本,该脚本/etc/fstab在插入 USB 后运行时打印所需的配置(就我的特定情况而言):

# Get the device path.
DEVPATH=$(/bin/ls /dev/disk/by-id/usb-Kingston_DataTraveler* | grep -E -v -- '-part[0-9]+$')
# Get the serial of the USB stick.
ID_SERIAL_SHORT=$(udevadm info -n $DEVPATH | grep ID_SERIAL_SHORT | sed -e 's/.*ID_SERIAL_SHORT=//')
# Run over all existing partitions.
for p in $(/bin/ls $DEVPATH-part*); do
  # Extract the "part?" string.
  PART=$(echo $p | sed -r -e 's/.*-(part[0-9]+)$/\1/')
  # Get the UUID of the block device of this partition iff it is a LUKS encrypted partition.
  UUID=$(blkid --match-token TYPE=crypto_LUKS $p | sed -e 's/.* UUID="\([^ ]*\)".*/\1/' || true)
  if [ -n "$UUID" ]; then
    # Decrypt the partition.
    echo $LUKS_PASS | sudo cryptsetup -q luksOpen /dev/disk/by-uuid/$UUID usb-$UUID
    # Get the UUID of the encrypted partition.
    UUID2=$(blkid /dev/mapper/usb-$UUID | sed -e 's/.* UUID="\([^ ]*\)".*/\1/')
    echo -e "UUID=$UUID2\t/mnt/usb/$ID_SERIAL_SHORT/$PART\text2\trw,noauto\t0 0"
    sudo cryptsetup luksClose usb-$UUID
  else
    # Get UUID of non-encrypted partition.
    UUID=$(blkid $p | sed -e 's/.* UUID="\([^ ]*\)".*/\1/')
    echo -e "UUID=$UUID\t/mnt/usb/$ID_SERIAL_SHORT/$PART\text2\trw,noauto\t0 0"
  fi
done

导出后,LUKS_PASS请确保运行上述脚本sudo -E以保存环境。示例输出:

>sudo -E ./foo.sh
UUID=db97c4b0-8f92-4edc-bacb-dc90e62de2e2       /mnt/usb/408D5CBECAC3E7C0E9170AEC/part1 ext2    rw,noauto       0 0
UUID=c45c6a7a-1c0f-49c4-bcfb-15766114daa1       /mnt/usb/408D5CBECAC3E7C0E9170AEC/part2 ext2    rw,noauto       0 0
UUID=9d262deb-2343-4096-bccf-bb26ed4415ad       /mnt/usb/408D5CBECAC3E7C0E9170AEC/part3 ext2    rw,noauto       0 0

设置完毕/etc/fstab并确切知道需要什么命令后,剩下的就是使用udev和来自动执行此操作systemd units。

问题是:如何做?

udev
  • 2 个回答
  • 59 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve