Skip to content

ดิสก์: GPT → LUKS2 → btrfs → subvolume

สร้าง “ที่อยู่” ของ hop 2 (ESP) และ hop 3–4 (root ที่เข้ารหัส)
Partitioning, full-disk encryption and btrfs subvolume layout

ใช้ทำอะไร (Purpose)

จาก ext4 ที่คุ้นเคย เพิ่มแค่ 2 ชั้น

ext4:   nvme0n1p2 ─────────────────────────► ext4 ─► /
ใหม่:   nvme0n1p2 ─► [LUKS] ─► /dev/mapper/cryptroot ─► btrfs ─► [subvolume] ─► mount หลายจุด
ชั้นเปรียบกับ network
LUKS → /dev/mapper/cryptrootVPN: eth0 เห็นแต่ข้อมูลเข้ารหัส / tun0 เห็นข้อมูลปกติ
btrfs subvolumeVLAN: switch ตัวเดียว หลายเครือข่ายแยกกัน ใช้ backplane ร่วม
mount -o subvol=@homeเลือก VLAN tag

ขั้นตอน (Setup)

1. เงื่อนไขก่อนแตะดิสก์

cat /sys/firmware/efi/fw_platform_size   # ต้องได้ 64 (UEFI) — systemd-boot ใช้ได้แค่ UEFI
timedatectl                              # System clock synchronized: yes — ลายเซ็นแพ็กเกจต้องการเวลาถูก

2. ดูสิ่งที่จะลบเป็นครั้งสุดท้าย แล้วล้าง

lsblk -o NAME,SIZE,FSTYPE,LABEL /dev/nvme0n1
blkdiscard /dev/nvme0n1        # ถูกปฏิเสธเพราะเจอ GPT = ระบบป้องกันทำงาน
blkdiscard -f /dev/nvme0n1     # ล้างจริง (TRIM ทั้งดิสก์ ไม่เขียนข้อมูล ไม่เปลืองอายุ SSD)
wipefs /dev/nvme0n1            # อ่านลายเซ็นจากดิสก์จริง: เงียบ = สะอาด

⚠️ ตรวจด้วย wipefs ไม่ใช่ lsblk — lsblk อ่านจาก cache ของ kernel (เหมือน ARP cache)

3. ตาราง GPT

sgdisk -o /dev/nvme0n1
sgdisk -n 1:0:+1G -t 1:ef00 -c 1:ESP /dev/nvme0n1
sgdisk -n 2:0:0   -t 2:8309 -c 2:LUKS /dev/nvme0n1
sgdisk -p /dev/nvme0n1
lsblk /dev/nvme0n1             # ยืนยันว่า kernel เห็น partition ใหม่
ค่าทำไม
ESP 1 GiBเก็บ kernel 2 ตัว + initramfs (NVIDIA ทำให้ใหญ่)
เริ่ม sector 2048จัดแนวกับหน่วยภายใน SSD (เหมือน MTU ไม่ตรง → แตก packet)
8309ป้ายบอกว่าเข้ารหัส (ช่วย triage ดิสก์ในงานสืบ)
ชื่อ LUKS ≠ cryptrootกันสับสนว่าพูดถึงชั้นไหน

ตรวจด้วยเลขคณิต: 1 GiB ÷ 512 = 2,097,152 sector → p1 จบ 2,099,199 / p2 เริ่ม 2,099,200 ✓

GPT มีสารบัญ 2 ชุด (หัว + ท้ายดิสก์) = redundancy ถ้าตัวหน้าเสีย ดูท้ายดิสก์

4. ESP

mkfs.fat -F 32 -n ESP /dev/nvme0n1p1    # UEFI ต้องอ่าน FAT ได้ตามมาตรฐาน

5. LUKS2

cryptsetup luksFormat --verbose /dev/nvme0n1p2      # พิมพ์ YES ตัวใหญ่
cryptsetup open --allow-discards --persistent /dev/nvme0n1p2 cryptroot
cryptsetup status cryptroot
  • รหัสใช้ตัวอักษรบนแป้น US เท่านั้น (หน้าถามรหัสตอนบูตยังไม่มีภาษาไทย)
  • ลืมรหัส = ข้อมูลหายถาวร
  • --persistent = เขียนค่า discards ลง header ไม่ต้องใส่ kernel parameter
  • TRIM ผ่าน LUKS: รั่วแค่ “แผนที่พื้นที่ว่าง” ไม่รั่วเนื้อหา

ตรวจด้วยเลขคณิต: 998,115,983 − 32,768 (header 16 MiB) = 998,083,215 ✓ ตรงกับ size

6. btrfs + subvolume

mkfs.btrfs -L ARCH /dev/mapper/cryptroot     # ⚠️ ที่ mapper ไม่ใช่ p2 (ไม่งั้นทับ LUKS)
mount /dev/mapper/cryptroot /mnt             # top-level (ID 5)
btrfs subvolume create /mnt/@ /mnt/@home /mnt/@snapshots /mnt/@log /mnt/@pkg
btrfs subvolume list /mnt                    # ทุกตัว top level 5 = พี่น้อง (flat layout)
umount /mnt
subvolumerollbackเหตุผล
@ย้อนตัวระบบ
@homeไม่ย้อนไฟล์งาน
@logไม่ย้อนหลักฐาน ว่าอะไรทำให้พัง
@pkgไม่ย้อนcache
@snapshotsไม่ย้อนไม่ให้ snapshot ถ่ายซ้อนตัวเอง

7. Mount ทุกอย่าง

mount -o noatime,compress=zstd:1,subvol=@ /dev/mapper/cryptroot /mnt
mkdir -p /mnt/{home,.snapshots,var/log,var/cache/pacman/pkg,boot}
mount -o noatime,compress=zstd:1,subvol=@home      /dev/mapper/cryptroot /mnt/home
mount -o noatime,compress=zstd:1,subvol=@snapshots /dev/mapper/cryptroot /mnt/.snapshots
mount -o noatime,compress=zstd:1,subvol=@log       /dev/mapper/cryptroot /mnt/var/log
mount -o noatime,compress=zstd:1,subvol=@pkg       /dev/mapper/cryptroot /mnt/var/cache/pacman/pkg
mount -o fmask=0077,dmask=0077 /dev/nvme0n1p1 /mnt/boot
findmnt -R /mnt
  • ต้อง mount @ ก่อน (จำลองสภาพตอนบูตจริง ไม่งั้น genfstab บันทึกผิด)
  • noatime: ไม่บันทึกเวลาอ่าน (ใน forensic atime มีค่ามาก แต่บนเครื่องเราไม่จำเป็น)
  • fmask/dmask=0077: FAT ไม่มีสิทธิ์แบบ Linux → ตั้งให้ root เท่านั้น (กันคำเตือน random-seed)

ทดสอบว่าใช้ได้ (Verification)

ตรวจหลักฐาน
TRIM ผ่าน LUKS จริงflags: discards + mkfs.btrfs ขึ้น “Performing full device TRIM”
subvolume ถูกตัวfindmnt แสดง [/@home] ฯลฯ
ESPvfat + fmask=0077,dmask=0077
discard ปลายทางdiscard=async ปรากฏเองใน options

UUID 3 ตัว (จุดพลาดคลาสสิก)

<LUKS-UUID>-...  LUKS  (nvme0n1p2)   → kernel parameter rd.luks.name=
<BTRFS-UUID>-...  btrfs (cryptroot)   → /etc/fstab
1A5F-40FD     FAT   (nvme0n1p1)   → /etc/fstab

สลับ LUKS กับ btrfs = บูตไม่ขึ้น

ปัญหาที่เคยเจอ & สิ่งที่ทายผิด (Troubleshooting)

เหตุการณ์บทเรียน
ทายว่า sgdisk พิมพ์ Setting name! / partNum is 0รุ่นใหม่ตัดข้อความภายในออกแล้ว — ตรวจด้วย sgdisk -p แทนการเชื่อข้อความ
ทายวันที่ผิด (29 vs 1 ต.ค.)ข้อมูลจากเครื่องถูกเสมอ
ลำดับ partition minor 259:3, 259:4kernel แจกเลขต่อจากตาราง Windows เดิม = ร่องรอยประวัติ

คำถามชวนคิด

  1. ถ้าเผลอรัน mkfs.btrfs /dev/nvme0n1p2 แทน mapper ข้อมูลอะไรหายไป และยังกู้อะไรได้บ้าง (เบาะแส: header สำรอง)
  2. ทำไม subvolume แบบ “พี่น้อง” (flat) จึง rollback ได้ง่ายกว่าแบบ “ซ้อนใน @” ลองวาดภาพตอนสลับ @ ทั้งก้อน
  3. TRIM ผ่าน LUKS ทำให้ผู้ตรวจพิสูจน์รู้อะไรเกี่ยวกับดิสก์ได้บ้าง ถ้าคุณเป็นฝ่ายตรวจดิสก์ของผู้ต้องสงสัย ข้อมูลนี้มีค่าแค่ไหน